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     bool is_apple = false;
294     if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
295         is_apple = true;
296     switch (m_arch.GetTriple().getOS())
297     {
298             case llvm::Triple::Darwin:
299             case llvm::Triple::MacOSX:
300             case llvm::Triple::IOS:
301                 is_apple = true;
302                 break;
303             default:
304                 break;
305     }
306 
307     /* On Apple iOS et al, the frame pointer register is always r7.
308      * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
309      */
310 
311     uint32_t fp_regnum = 11;
312 
313     if (is_apple)
314         fp_regnum = 7;
315 
316     if (m_opcode_mode == eModeThumb)
317         fp_regnum = 7;
318 
319     return fp_regnum;
320 }
321 
322 uint32_t
323 EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const
324 {
325     bool is_apple = false;
326     if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
327         is_apple = true;
328     switch (m_arch.GetTriple().getOS())
329     {
330             case llvm::Triple::Darwin:
331             case llvm::Triple::MacOSX:
332             case llvm::Triple::IOS:
333                 is_apple = true;
334                 break;
335             default:
336                 break;
337     }
338 
339     /* On Apple iOS et al, the frame pointer register is always r7.
340      * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
341      */
342 
343     uint32_t fp_regnum = dwarf_r11;
344 
345     if (is_apple)
346         fp_regnum = dwarf_r7;
347 
348     if (m_opcode_mode == eModeThumb)
349         fp_regnum = dwarf_r7;
350 
351     return fp_regnum;
352 }
353 
354 // Push Multiple Registers stores multiple registers to the stack, storing to
355 // consecutive memory locations ending just below the address in SP, and updates
356 // SP to point to the start of the stored data.
357 bool
358 EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding)
359 {
360 #if 0
361     // ARM pseudo code...
362     if (ConditionPassed())
363     {
364         EncodingSpecificOperations();
365         NullCheckIfThumbEE(13);
366         address = SP - 4*BitCount(registers);
367 
368         for (i = 0 to 14)
369         {
370             if (registers<i> == '1')
371             {
372                 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
373                     MemA[address,4] = bits(32) UNKNOWN;
374                 else
375                     MemA[address,4] = R[i];
376                 address = address + 4;
377             }
378         }
379 
380         if (registers<15> == '1') // Only possible for encoding A1 or A2
381             MemA[address,4] = PCStoreValue();
382 
383         SP = SP - 4*BitCount(registers);
384     }
385 #endif
386 
387     bool conditional = false;
388     bool success = false;
389     if (ConditionPassed(opcode, &conditional))
390     {
391         const uint32_t addr_byte_size = GetAddressByteSize();
392         const addr_t sp = ReadCoreReg (SP_REG, &success);
393         if (!success)
394             return false;
395         uint32_t registers = 0;
396         uint32_t Rt; // the source register
397         switch (encoding) {
398         case eEncodingT1:
399             registers = Bits32(opcode, 7, 0);
400             // The M bit represents LR.
401             if (Bit32(opcode, 8))
402                 registers |= (1u << 14);
403             // if BitCount(registers) < 1 then UNPREDICTABLE;
404             if (BitCount(registers) < 1)
405                 return false;
406             break;
407         case eEncodingT2:
408             // Ignore bits 15 & 13.
409             registers = Bits32(opcode, 15, 0) & ~0xa000;
410             // if BitCount(registers) < 2 then UNPREDICTABLE;
411             if (BitCount(registers) < 2)
412                 return false;
413             break;
414         case eEncodingT3:
415             Rt = Bits32(opcode, 15, 12);
416             // if BadReg(t) then UNPREDICTABLE;
417             if (BadReg(Rt))
418                 return false;
419             registers = (1u << Rt);
420             break;
421         case eEncodingA1:
422             registers = Bits32(opcode, 15, 0);
423             // Instead of return false, let's handle the following case as well,
424             // which amounts to pushing one reg onto the full descending stacks.
425             // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
426             break;
427         case eEncodingA2:
428             Rt = Bits32(opcode, 15, 12);
429             // if t == 13 then UNPREDICTABLE;
430             if (Rt == dwarf_sp)
431                 return false;
432             registers = (1u << Rt);
433             break;
434         default:
435             return false;
436         }
437         addr_t sp_offset = addr_byte_size * BitCount (registers);
438         addr_t addr = sp - sp_offset;
439         uint32_t i;
440 
441         EmulateInstruction::Context context;
442         if (conditional)
443             context.type = EmulateInstruction::eContextRegisterStore;
444         else
445             context.type = EmulateInstruction::eContextPushRegisterOnStack;
446         RegisterInfo reg_info;
447         RegisterInfo sp_reg;
448         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
449         for (i=0; i<15; ++i)
450         {
451             if (BitIsSet (registers, i))
452             {
453                 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info);
454                 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
455                 uint32_t reg_value = ReadCoreReg(i, &success);
456                 if (!success)
457                     return false;
458                 if (!MemAWrite (context, addr, reg_value, addr_byte_size))
459                     return false;
460                 addr += addr_byte_size;
461             }
462         }
463 
464         if (BitIsSet (registers, 15))
465         {
466             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info);
467             context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
468             const uint32_t pc = ReadCoreReg(PC_REG, &success);
469             if (!success)
470                 return false;
471             if (!MemAWrite (context, addr, pc, addr_byte_size))
472                 return false;
473         }
474 
475         context.type = EmulateInstruction::eContextAdjustStackPointer;
476         context.SetImmediateSigned (-sp_offset);
477 
478         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
479             return false;
480     }
481     return true;
482 }
483 
484 // Pop Multiple Registers loads multiple registers from the stack, loading from
485 // consecutive memory locations staring at the address in SP, and updates
486 // SP to point just above the loaded data.
487 bool
488 EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding)
489 {
490 #if 0
491     // ARM pseudo code...
492     if (ConditionPassed())
493     {
494         EncodingSpecificOperations(); NullCheckIfThumbEE(13);
495         address = SP;
496         for i = 0 to 14
497             if registers<i> == '1' then
498                 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
499         if registers<15> == '1' then
500             if UnalignedAllowed then
501                 LoadWritePC(MemU[address,4]);
502             else
503                 LoadWritePC(MemA[address,4]);
504         if registers<13> == '0' then SP = SP + 4*BitCount(registers);
505         if registers<13> == '1' then SP = bits(32) UNKNOWN;
506     }
507 #endif
508 
509     bool success = false;
510 
511     bool conditional = false;
512     if (ConditionPassed(opcode, &conditional))
513     {
514         const uint32_t addr_byte_size = GetAddressByteSize();
515         const addr_t sp = ReadCoreReg (SP_REG, &success);
516         if (!success)
517             return false;
518         uint32_t registers = 0;
519         uint32_t Rt; // the destination register
520         switch (encoding) {
521         case eEncodingT1:
522             registers = Bits32(opcode, 7, 0);
523             // The P bit represents PC.
524             if (Bit32(opcode, 8))
525                 registers |= (1u << 15);
526             // if BitCount(registers) < 1 then UNPREDICTABLE;
527             if (BitCount(registers) < 1)
528                 return false;
529             break;
530         case eEncodingT2:
531             // Ignore bit 13.
532             registers = Bits32(opcode, 15, 0) & ~0x2000;
533             // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
534             if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
535                 return false;
536             // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
537             if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
538                 return false;
539             break;
540         case eEncodingT3:
541             Rt = Bits32(opcode, 15, 12);
542             // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
543             if (Rt == 13)
544                 return false;
545             if (Rt == 15 && InITBlock() && !LastInITBlock())
546                 return false;
547             registers = (1u << Rt);
548             break;
549         case eEncodingA1:
550             registers = Bits32(opcode, 15, 0);
551             // Instead of return false, let's handle the following case as well,
552             // which amounts to popping one reg from the full descending stacks.
553             // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
554 
555             // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
556             if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
557                 return false;
558             break;
559         case eEncodingA2:
560             Rt = Bits32(opcode, 15, 12);
561             // if t == 13 then UNPREDICTABLE;
562             if (Rt == dwarf_sp)
563                 return false;
564             registers = (1u << Rt);
565             break;
566         default:
567             return false;
568         }
569         addr_t sp_offset = addr_byte_size * BitCount (registers);
570         addr_t addr = sp;
571         uint32_t i, data;
572 
573         EmulateInstruction::Context context;
574         if (conditional)
575             context.type = EmulateInstruction::eContextRegisterLoad;
576         else
577             context.type = EmulateInstruction::eContextPopRegisterOffStack;
578 
579         RegisterInfo sp_reg;
580         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
581 
582         for (i=0; i<15; ++i)
583         {
584             if (BitIsSet (registers, i))
585             {
586                 context.SetRegisterPlusOffset (sp_reg, addr - sp);
587                 data = MemARead(context, addr, 4, 0, &success);
588                 if (!success)
589                     return false;
590                 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data))
591                     return false;
592                 addr += addr_byte_size;
593             }
594         }
595 
596         if (BitIsSet (registers, 15))
597         {
598             context.SetRegisterPlusOffset (sp_reg, addr - sp);
599             data = MemARead(context, addr, 4, 0, &success);
600             if (!success)
601                 return false;
602             // In ARMv5T and above, this is an interworking branch.
603             if (!LoadWritePC(context, data))
604                 return false;
605             //addr += addr_byte_size;
606         }
607 
608         context.type = EmulateInstruction::eContextAdjustStackPointer;
609         context.SetImmediateSigned (sp_offset);
610 
611         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
612             return false;
613     }
614     return true;
615 }
616 
617 // Set r7 or ip to point to saved value residing within the stack.
618 // ADD (SP plus immediate)
619 bool
620 EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding)
621 {
622 #if 0
623     // ARM pseudo code...
624     if (ConditionPassed())
625     {
626         EncodingSpecificOperations();
627         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
628         if d == 15 then
629            ALUWritePC(result); // setflags is always FALSE here
630         else
631             R[d] = result;
632             if setflags then
633                 APSR.N = result<31>;
634                 APSR.Z = IsZeroBit(result);
635                 APSR.C = carry;
636                 APSR.V = overflow;
637     }
638 #endif
639 
640     bool success = false;
641 
642     if (ConditionPassed(opcode))
643     {
644         const addr_t sp = ReadCoreReg (SP_REG, &success);
645         if (!success)
646             return false;
647         uint32_t Rd; // the destination register
648         uint32_t imm32;
649         switch (encoding) {
650         case eEncodingT1:
651             Rd = 7;
652             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
653             break;
654         case eEncodingA1:
655             Rd = Bits32(opcode, 15, 12);
656             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
657             break;
658         default:
659             return false;
660         }
661         addr_t sp_offset = imm32;
662         addr_t addr = sp + sp_offset; // a pointer to the stack area
663 
664         EmulateInstruction::Context context;
665         context.type = eContextSetFramePointer;
666         RegisterInfo sp_reg;
667         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
668         context.SetRegisterPlusOffset (sp_reg, sp_offset);
669 
670         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
671             return false;
672     }
673     return true;
674 }
675 
676 // Set r7 or ip to the current stack pointer.
677 // MOV (register)
678 bool
679 EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding)
680 {
681 #if 0
682     // ARM pseudo code...
683     if (ConditionPassed())
684     {
685         EncodingSpecificOperations();
686         result = R[m];
687         if d == 15 then
688             ALUWritePC(result); // setflags is always FALSE here
689         else
690             R[d] = result;
691             if setflags then
692                 APSR.N = result<31>;
693                 APSR.Z = IsZeroBit(result);
694                 // APSR.C unchanged
695                 // APSR.V unchanged
696     }
697 #endif
698 
699     bool success = false;
700 
701     if (ConditionPassed(opcode))
702     {
703         const addr_t sp = ReadCoreReg (SP_REG, &success);
704         if (!success)
705             return false;
706         uint32_t Rd; // the destination register
707         switch (encoding) {
708         case eEncodingT1:
709             Rd = 7;
710             break;
711         case eEncodingA1:
712             Rd = 12;
713             break;
714         default:
715             return false;
716         }
717 
718         EmulateInstruction::Context context;
719         if (Rd == GetFramePointerRegisterNumber())
720             context.type = EmulateInstruction::eContextSetFramePointer;
721         else
722             context.type = EmulateInstruction::eContextRegisterPlusOffset;
723         RegisterInfo sp_reg;
724         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
725         context.SetRegisterPlusOffset (sp_reg, 0);
726 
727         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
728             return false;
729     }
730     return true;
731 }
732 
733 // Move from high register (r8-r15) to low register (r0-r7).
734 // MOV (register)
735 bool
736 EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding)
737 {
738     return EmulateMOVRdRm (opcode, encoding);
739 }
740 
741 // Move from register to register.
742 // MOV (register)
743 bool
744 EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding)
745 {
746 #if 0
747     // ARM pseudo code...
748     if (ConditionPassed())
749     {
750         EncodingSpecificOperations();
751         result = R[m];
752         if d == 15 then
753             ALUWritePC(result); // setflags is always FALSE here
754         else
755             R[d] = result;
756             if setflags then
757                 APSR.N = result<31>;
758                 APSR.Z = IsZeroBit(result);
759                 // APSR.C unchanged
760                 // APSR.V unchanged
761     }
762 #endif
763 
764     bool success = false;
765 
766     if (ConditionPassed(opcode))
767     {
768         uint32_t Rm; // the source register
769         uint32_t Rd; // the destination register
770         bool setflags;
771         switch (encoding) {
772         case eEncodingT1:
773             Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
774             Rm = Bits32(opcode, 6, 3);
775             setflags = false;
776             if (Rd == 15 && InITBlock() && !LastInITBlock())
777                 return false;
778             break;
779         case eEncodingT2:
780             Rd = Bits32(opcode, 2, 0);
781             Rm = Bits32(opcode, 5, 3);
782             setflags = true;
783             if (InITBlock())
784                 return false;
785             break;
786         case eEncodingT3:
787             Rd = Bits32(opcode, 11, 8);
788             Rm = Bits32(opcode, 3, 0);
789             setflags = BitIsSet(opcode, 20);
790             // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
791             if (setflags && (BadReg(Rd) || BadReg(Rm)))
792                 return false;
793             // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE;
794             if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
795                 return false;
796             break;
797         case eEncodingA1:
798             Rd = Bits32(opcode, 15, 12);
799             Rm = Bits32(opcode, 3, 0);
800             setflags = BitIsSet(opcode, 20);
801 
802             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
803             if (Rd == 15 && setflags)
804                 return EmulateSUBSPcLrEtc (opcode, encoding);
805             break;
806         default:
807             return false;
808         }
809         uint32_t result = ReadCoreReg(Rm, &success);
810         if (!success)
811             return false;
812 
813         // The context specifies that Rm is to be moved into Rd.
814         EmulateInstruction::Context context;
815         context.type = EmulateInstruction::eContextRegisterLoad;
816         RegisterInfo dwarf_reg;
817         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
818         context.SetRegister (dwarf_reg);
819 
820         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
821             return false;
822     }
823     return true;
824 }
825 
826 // Move (immediate) writes an immediate value to the destination register.  It
827 // can optionally update the condition flags based on the value.
828 // MOV (immediate)
829 bool
830 EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding)
831 {
832 #if 0
833     // ARM pseudo code...
834     if (ConditionPassed())
835     {
836         EncodingSpecificOperations();
837         result = imm32;
838         if d == 15 then         // Can only occur for ARM encoding
839             ALUWritePC(result); // setflags is always FALSE here
840         else
841             R[d] = result;
842             if setflags then
843                 APSR.N = result<31>;
844                 APSR.Z = IsZeroBit(result);
845                 APSR.C = carry;
846                 // APSR.V unchanged
847     }
848 #endif
849 
850     if (ConditionPassed(opcode))
851     {
852         uint32_t Rd; // the destination register
853         uint32_t imm32; // the immediate value to be written to Rd
854         uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
855                             // for setflags == false, this value is a don't care
856                             // initialized to 0 to silence the static analyzer
857         bool setflags;
858         switch (encoding) {
859             case eEncodingT1:
860                 Rd = Bits32(opcode, 10, 8);
861                 setflags = !InITBlock();
862                 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
863                 carry = APSR_C;
864 
865                 break;
866 
867             case eEncodingT2:
868                 Rd = Bits32(opcode, 11, 8);
869                 setflags = BitIsSet(opcode, 20);
870                 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
871                 if (BadReg(Rd))
872                   return false;
873 
874                 break;
875 
876             case eEncodingT3:
877             {
878                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32);
879                 Rd = Bits32 (opcode, 11, 8);
880                 setflags = false;
881                 uint32_t imm4 = Bits32 (opcode, 19, 16);
882                 uint32_t imm3 = Bits32 (opcode, 14, 12);
883                 uint32_t i = Bit32 (opcode, 26);
884                 uint32_t imm8 = Bits32 (opcode, 7, 0);
885                 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
886 
887                 // if BadReg(d) then UNPREDICTABLE;
888                 if (BadReg (Rd))
889                     return false;
890             }
891                 break;
892 
893             case eEncodingA1:
894                 // d = UInt(Rd); setflags = (S == �1�); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C);
895                 Rd = Bits32 (opcode, 15, 12);
896                 setflags = BitIsSet (opcode, 20);
897                 imm32 = ARMExpandImm_C (opcode, APSR_C, carry);
898 
899                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
900                 if ((Rd == 15) && setflags)
901                     return EmulateSUBSPcLrEtc (opcode, encoding);
902 
903                 break;
904 
905             case eEncodingA2:
906             {
907                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
908                 Rd = Bits32 (opcode, 15, 12);
909                 setflags = false;
910                 uint32_t imm4 = Bits32 (opcode, 19, 16);
911                 uint32_t imm12 = Bits32 (opcode, 11, 0);
912                 imm32 = (imm4 << 12) | imm12;
913 
914                 // if d == 15 then UNPREDICTABLE;
915                 if (Rd == 15)
916                     return false;
917             }
918                 break;
919 
920             default:
921                 return false;
922         }
923         uint32_t result = imm32;
924 
925         // The context specifies that an immediate is to be moved into Rd.
926         EmulateInstruction::Context context;
927         context.type = EmulateInstruction::eContextImmediate;
928         context.SetNoArgs ();
929 
930         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
931             return false;
932     }
933     return true;
934 }
935 
936 // MUL multiplies two register values.  The least significant 32 bits of the result are written to the destination
937 // register.  These 32 bits do not depend on whether the source register values are considered to be signed values or
938 // unsigned values.
939 //
940 // Optionally, it can update the condition flags based on the result.  In the Thumb instruction set, this option is
941 // limited to only a few forms of the instruction.
942 bool
943 EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding)
944 {
945 #if 0
946     if ConditionPassed() then
947         EncodingSpecificOperations();
948         operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
949         operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
950         result = operand1 * operand2;
951         R[d] = result<31:0>;
952         if setflags then
953             APSR.N = result<31>;
954             APSR.Z = IsZeroBit(result);
955             if ArchVersion() == 4 then
956                 APSR.C = bit UNKNOWN;
957             // else APSR.C unchanged
958             // APSR.V always unchanged
959 #endif
960 
961     if (ConditionPassed(opcode))
962     {
963         uint32_t d;
964         uint32_t n;
965         uint32_t m;
966         bool setflags;
967 
968         // EncodingSpecificOperations();
969         switch (encoding)
970         {
971             case eEncodingT1:
972                 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
973                 d = Bits32 (opcode, 2, 0);
974                 n = Bits32 (opcode, 5, 3);
975                 m = Bits32 (opcode, 2, 0);
976                 setflags = !InITBlock();
977 
978                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
979                 if ((ArchVersion() < ARMv6) && (d == n))
980                     return false;
981 
982                 break;
983 
984             case eEncodingT2:
985                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
986                 d = Bits32 (opcode, 11, 8);
987                 n = Bits32 (opcode, 19, 16);
988                 m = Bits32 (opcode, 3, 0);
989                 setflags = false;
990 
991                 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
992                 if (BadReg (d) || BadReg (n) || BadReg (m))
993                     return false;
994 
995                 break;
996 
997             case eEncodingA1:
998                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
999                 d = Bits32 (opcode, 19, 16);
1000                 n = Bits32 (opcode, 3, 0);
1001                 m = Bits32 (opcode, 11, 8);
1002                 setflags = BitIsSet (opcode, 20);
1003 
1004                 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
1005                 if ((d == 15) ||  (n == 15) || (m == 15))
1006                     return false;
1007 
1008                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1009                 if ((ArchVersion() < ARMv6) && (d == n))
1010                     return false;
1011 
1012                 break;
1013 
1014             default:
1015                 return false;
1016         }
1017 
1018         bool success = false;
1019 
1020         // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
1021         uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
1022         if (!success)
1023             return false;
1024 
1025         // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
1026         uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
1027         if (!success)
1028             return false;
1029 
1030         // result = operand1 * operand2;
1031         uint64_t result = operand1 * operand2;
1032 
1033         // R[d] = result<31:0>;
1034         RegisterInfo op1_reg;
1035         RegisterInfo op2_reg;
1036         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
1037         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
1038 
1039         EmulateInstruction::Context context;
1040         context.type = eContextArithmetic;
1041         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
1042 
1043         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result)))
1044             return false;
1045 
1046         // if setflags then
1047         if (setflags)
1048         {
1049             // APSR.N = result<31>;
1050             // APSR.Z = IsZeroBit(result);
1051             m_new_inst_cpsr = m_opcode_cpsr;
1052             SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31));
1053             SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1054             if (m_new_inst_cpsr != m_opcode_cpsr)
1055             {
1056                 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1057                     return false;
1058             }
1059 
1060             // if ArchVersion() == 4 then
1061                 // APSR.C = bit UNKNOWN;
1062         }
1063     }
1064     return true;
1065 }
1066 
1067 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register.
1068 // It can optionally update the condition flags based on the value.
1069 bool
1070 EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding)
1071 {
1072 #if 0
1073     // ARM pseudo code...
1074     if (ConditionPassed())
1075     {
1076         EncodingSpecificOperations();
1077         result = NOT(imm32);
1078         if d == 15 then         // Can only occur for ARM encoding
1079             ALUWritePC(result); // setflags is always FALSE here
1080         else
1081             R[d] = result;
1082             if setflags then
1083                 APSR.N = result<31>;
1084                 APSR.Z = IsZeroBit(result);
1085                 APSR.C = carry;
1086                 // APSR.V unchanged
1087     }
1088 #endif
1089 
1090     if (ConditionPassed(opcode))
1091     {
1092         uint32_t Rd; // the destination register
1093         uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1094         uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1095         bool setflags;
1096         switch (encoding) {
1097         case eEncodingT1:
1098             Rd = Bits32(opcode, 11, 8);
1099             setflags = BitIsSet(opcode, 20);
1100             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1101             break;
1102         case eEncodingA1:
1103             Rd = Bits32(opcode, 15, 12);
1104             setflags = BitIsSet(opcode, 20);
1105             imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1106 
1107             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1108             if (Rd == 15 && setflags)
1109                 return EmulateSUBSPcLrEtc (opcode, encoding);
1110             break;
1111         default:
1112             return false;
1113         }
1114         uint32_t result = ~imm32;
1115 
1116         // The context specifies that an immediate is to be moved into Rd.
1117         EmulateInstruction::Context context;
1118         context.type = EmulateInstruction::eContextImmediate;
1119         context.SetNoArgs ();
1120 
1121         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1122             return false;
1123     }
1124     return true;
1125 }
1126 
1127 // Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register.
1128 // It can optionally update the condition flags based on the result.
1129 bool
1130 EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding)
1131 {
1132 #if 0
1133     // ARM pseudo code...
1134     if (ConditionPassed())
1135     {
1136         EncodingSpecificOperations();
1137         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1138         result = NOT(shifted);
1139         if d == 15 then         // Can only occur for ARM encoding
1140             ALUWritePC(result); // setflags is always FALSE here
1141         else
1142             R[d] = result;
1143             if setflags then
1144                 APSR.N = result<31>;
1145                 APSR.Z = IsZeroBit(result);
1146                 APSR.C = carry;
1147                 // APSR.V unchanged
1148     }
1149 #endif
1150 
1151     if (ConditionPassed(opcode))
1152     {
1153         uint32_t Rm; // the source register
1154         uint32_t Rd; // the destination register
1155         ARM_ShifterType shift_t;
1156         uint32_t shift_n; // the shift applied to the value read from Rm
1157         bool setflags;
1158         uint32_t carry; // the carry bit after the shift operation
1159         switch (encoding) {
1160         case eEncodingT1:
1161             Rd = Bits32(opcode, 2, 0);
1162             Rm = Bits32(opcode, 5, 3);
1163             setflags = !InITBlock();
1164             shift_t = SRType_LSL;
1165             shift_n = 0;
1166             if (InITBlock())
1167                 return false;
1168             break;
1169         case eEncodingT2:
1170             Rd = Bits32(opcode, 11, 8);
1171             Rm = Bits32(opcode, 3, 0);
1172             setflags = BitIsSet(opcode, 20);
1173             shift_n = DecodeImmShiftThumb(opcode, shift_t);
1174             // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1175             if (BadReg(Rd) || BadReg(Rm))
1176                 return false;
1177             break;
1178         case eEncodingA1:
1179             Rd = Bits32(opcode, 15, 12);
1180             Rm = Bits32(opcode, 3, 0);
1181             setflags = BitIsSet(opcode, 20);
1182             shift_n = DecodeImmShiftARM(opcode, shift_t);
1183             break;
1184         default:
1185             return false;
1186         }
1187         bool success = false;
1188         uint32_t value = ReadCoreReg(Rm, &success);
1189         if (!success)
1190             return false;
1191 
1192         uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1193         if (!success)
1194             return false;
1195         uint32_t result = ~shifted;
1196 
1197         // The context specifies that an immediate is to be moved into Rd.
1198         EmulateInstruction::Context context;
1199         context.type = EmulateInstruction::eContextImmediate;
1200         context.SetNoArgs ();
1201 
1202         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1203             return false;
1204     }
1205     return true;
1206 }
1207 
1208 // PC relative immediate load into register, possibly followed by ADD (SP plus register).
1209 // LDR (literal)
1210 bool
1211 EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding)
1212 {
1213 #if 0
1214     // ARM pseudo code...
1215     if (ConditionPassed())
1216     {
1217         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1218         base = Align(PC,4);
1219         address = if add then (base + imm32) else (base - imm32);
1220         data = MemU[address,4];
1221         if t == 15 then
1222             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1223         elsif UnalignedSupport() || address<1:0> = '00' then
1224             R[t] = data;
1225         else // Can only apply before ARMv7
1226             if CurrentInstrSet() == InstrSet_ARM then
1227                 R[t] = ROR(data, 8*UInt(address<1:0>));
1228             else
1229                 R[t] = bits(32) UNKNOWN;
1230     }
1231 #endif
1232 
1233     if (ConditionPassed(opcode))
1234     {
1235         bool success = false;
1236         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1237         if (!success)
1238             return false;
1239 
1240         // PC relative immediate load context
1241         EmulateInstruction::Context context;
1242         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1243         RegisterInfo pc_reg;
1244         GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
1245         context.SetRegisterPlusOffset (pc_reg, 0);
1246 
1247         uint32_t Rt;    // the destination register
1248         uint32_t imm32; // immediate offset from the PC
1249         bool add;       // +imm32 or -imm32?
1250         addr_t base;    // the base address
1251         addr_t address; // the PC relative address
1252         uint32_t data;  // the literal data value from the PC relative load
1253         switch (encoding) {
1254         case eEncodingT1:
1255             Rt = Bits32(opcode, 10, 8);
1256             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1257             add = true;
1258             break;
1259         case eEncodingT2:
1260             Rt = Bits32(opcode, 15, 12);
1261             imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1262             add = BitIsSet(opcode, 23);
1263             if (Rt == 15 && InITBlock() && !LastInITBlock())
1264                 return false;
1265             break;
1266         default:
1267             return false;
1268         }
1269 
1270         base = Align(pc, 4);
1271         if (add)
1272             address = base + imm32;
1273         else
1274             address = base - imm32;
1275 
1276         context.SetRegisterPlusOffset(pc_reg, address - base);
1277         data = MemURead(context, address, 4, 0, &success);
1278         if (!success)
1279             return false;
1280 
1281         if (Rt == 15)
1282         {
1283             if (Bits32(address, 1, 0) == 0)
1284             {
1285                 // In ARMv5T and above, this is an interworking branch.
1286                 if (!LoadWritePC(context, data))
1287                     return false;
1288             }
1289             else
1290                 return false;
1291         }
1292         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
1293         {
1294             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
1295                 return false;
1296         }
1297         else // We don't handle ARM for now.
1298             return false;
1299 
1300     }
1301     return true;
1302 }
1303 
1304 // An add operation to adjust the SP.
1305 // ADD (SP plus immediate)
1306 bool
1307 EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding)
1308 {
1309 #if 0
1310     // ARM pseudo code...
1311     if (ConditionPassed())
1312     {
1313         EncodingSpecificOperations();
1314         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1315         if d == 15 then // Can only occur for ARM encoding
1316             ALUWritePC(result); // setflags is always FALSE here
1317         else
1318             R[d] = result;
1319             if setflags then
1320                 APSR.N = result<31>;
1321                 APSR.Z = IsZeroBit(result);
1322                 APSR.C = carry;
1323                 APSR.V = overflow;
1324     }
1325 #endif
1326 
1327     bool success = false;
1328 
1329     if (ConditionPassed(opcode))
1330     {
1331         const addr_t sp = ReadCoreReg (SP_REG, &success);
1332         if (!success)
1333             return false;
1334         uint32_t imm32; // the immediate operand
1335         uint32_t d;
1336         //bool setflags = false; // Add this back if/when support eEncodingT3 eEncodingA1
1337         switch (encoding)
1338         {
1339             case eEncodingT1:
1340                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1341                 d = Bits32 (opcode, 10, 8);
1342                 imm32 = (Bits32 (opcode, 7, 0) << 2);
1343 
1344                 break;
1345 
1346             case eEncodingT2:
1347                 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1348                 d = 13;
1349                 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1350 
1351                 break;
1352 
1353             default:
1354                 return false;
1355         }
1356         addr_t sp_offset = imm32;
1357         addr_t addr = sp + sp_offset; // the adjusted stack pointer value
1358 
1359         EmulateInstruction::Context context;
1360         context.type = EmulateInstruction::eContextAdjustStackPointer;
1361         RegisterInfo sp_reg;
1362         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1363         context.SetRegisterPlusOffset (sp_reg, sp_offset);
1364 
1365         if (d == 15)
1366         {
1367             if (!ALUWritePC (context, addr))
1368                 return false;
1369         }
1370         else
1371         {
1372             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr))
1373                 return false;
1374 
1375             // Add this back if/when support eEncodingT3 eEncodingA1
1376             //if (setflags)
1377             //{
1378             //    APSR.N = result<31>;
1379             //    APSR.Z = IsZeroBit(result);
1380             //    APSR.C = carry;
1381             //    APSR.V = overflow;
1382             //}
1383         }
1384     }
1385     return true;
1386 }
1387 
1388 // An add operation to adjust the SP.
1389 // ADD (SP plus register)
1390 bool
1391 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding)
1392 {
1393 #if 0
1394     // ARM pseudo code...
1395     if (ConditionPassed())
1396     {
1397         EncodingSpecificOperations();
1398         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1399         (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1400         if d == 15 then
1401             ALUWritePC(result); // setflags is always FALSE here
1402         else
1403             R[d] = result;
1404             if setflags then
1405                 APSR.N = result<31>;
1406                 APSR.Z = IsZeroBit(result);
1407                 APSR.C = carry;
1408                 APSR.V = overflow;
1409     }
1410 #endif
1411 
1412     bool success = false;
1413 
1414     if (ConditionPassed(opcode))
1415     {
1416         const addr_t sp = ReadCoreReg (SP_REG, &success);
1417         if (!success)
1418             return false;
1419         uint32_t Rm; // the second operand
1420         switch (encoding) {
1421         case eEncodingT2:
1422             Rm = Bits32(opcode, 6, 3);
1423             break;
1424         default:
1425             return false;
1426         }
1427         int32_t reg_value = ReadCoreReg(Rm, &success);
1428         if (!success)
1429             return false;
1430 
1431         addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1432 
1433         EmulateInstruction::Context context;
1434         context.type = eContextArithmetic;
1435         RegisterInfo sp_reg;
1436         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1437 
1438         RegisterInfo other_reg;
1439         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1440         context.SetRegisterRegisterOperands (sp_reg, other_reg);
1441 
1442         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
1443             return false;
1444     }
1445     return true;
1446 }
1447 
1448 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
1449 // at a PC-relative address, and changes instruction set from ARM to Thumb, or
1450 // from Thumb to ARM.
1451 // BLX (immediate)
1452 bool
1453 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding)
1454 {
1455 #if 0
1456     // ARM pseudo code...
1457     if (ConditionPassed())
1458     {
1459         EncodingSpecificOperations();
1460         if CurrentInstrSet() == InstrSet_ARM then
1461             LR = PC - 4;
1462         else
1463             LR = PC<31:1> : '1';
1464         if targetInstrSet == InstrSet_ARM then
1465             targetAddress = Align(PC,4) + imm32;
1466         else
1467             targetAddress = PC + imm32;
1468         SelectInstrSet(targetInstrSet);
1469         BranchWritePC(targetAddress);
1470     }
1471 #endif
1472 
1473     bool success = true;
1474 
1475     if (ConditionPassed(opcode))
1476     {
1477         EmulateInstruction::Context context;
1478         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1479         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1480         if (!success)
1481             return false;
1482         addr_t lr; // next instruction address
1483         addr_t target; // target address
1484         int32_t imm32; // PC-relative offset
1485         switch (encoding) {
1486         case eEncodingT1:
1487             {
1488             lr = pc | 1u; // return address
1489             uint32_t S = Bit32(opcode, 26);
1490             uint32_t imm10 = Bits32(opcode, 25, 16);
1491             uint32_t J1 = Bit32(opcode, 13);
1492             uint32_t J2 = Bit32(opcode, 11);
1493             uint32_t imm11 = Bits32(opcode, 10, 0);
1494             uint32_t I1 = !(J1 ^ S);
1495             uint32_t I2 = !(J2 ^ S);
1496             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1497             imm32 = llvm::SignExtend32<25>(imm25);
1498             target = pc + imm32;
1499             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
1500             if (InITBlock() && !LastInITBlock())
1501                 return false;
1502             break;
1503             }
1504         case eEncodingT2:
1505             {
1506             lr = pc | 1u; // return address
1507             uint32_t S = Bit32(opcode, 26);
1508             uint32_t imm10H = Bits32(opcode, 25, 16);
1509             uint32_t J1 = Bit32(opcode, 13);
1510             uint32_t J2 = Bit32(opcode, 11);
1511             uint32_t imm10L = Bits32(opcode, 10, 1);
1512             uint32_t I1 = !(J1 ^ S);
1513             uint32_t I2 = !(J2 ^ S);
1514             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
1515             imm32 = llvm::SignExtend32<25>(imm25);
1516             target = Align(pc, 4) + imm32;
1517             context.SetISAAndImmediateSigned (eModeARM, 4 + imm32);
1518             if (InITBlock() && !LastInITBlock())
1519                 return false;
1520             break;
1521             }
1522         case eEncodingA1:
1523             lr = pc - 4; // return address
1524             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1525             target = Align(pc, 4) + imm32;
1526             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
1527             break;
1528         case eEncodingA2:
1529             lr = pc - 4; // return address
1530             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
1531             target = pc + imm32;
1532             context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32);
1533             break;
1534         default:
1535             return false;
1536         }
1537         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1538             return false;
1539         if (!BranchWritePC(context, target))
1540             return false;
1541     }
1542     return true;
1543 }
1544 
1545 // Branch with Link and Exchange (register) calls a subroutine at an address and
1546 // instruction set specified by a register.
1547 // BLX (register)
1548 bool
1549 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding)
1550 {
1551 #if 0
1552     // ARM pseudo code...
1553     if (ConditionPassed())
1554     {
1555         EncodingSpecificOperations();
1556         target = R[m];
1557         if CurrentInstrSet() == InstrSet_ARM then
1558             next_instr_addr = PC - 4;
1559             LR = next_instr_addr;
1560         else
1561             next_instr_addr = PC - 2;
1562             LR = next_instr_addr<31:1> : '1';
1563         BXWritePC(target);
1564     }
1565 #endif
1566 
1567     bool success = false;
1568 
1569     if (ConditionPassed(opcode))
1570     {
1571         EmulateInstruction::Context context;
1572         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1573         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1574         addr_t lr; // next instruction address
1575         if (!success)
1576             return false;
1577         uint32_t Rm; // the register with the target address
1578         switch (encoding) {
1579         case eEncodingT1:
1580             lr = (pc - 2) | 1u; // return address
1581             Rm = Bits32(opcode, 6, 3);
1582             // if m == 15 then UNPREDICTABLE;
1583             if (Rm == 15)
1584                 return false;
1585             if (InITBlock() && !LastInITBlock())
1586                 return false;
1587             break;
1588         case eEncodingA1:
1589             lr = pc - 4; // return address
1590             Rm = Bits32(opcode, 3, 0);
1591             // if m == 15 then UNPREDICTABLE;
1592             if (Rm == 15)
1593                 return false;
1594             break;
1595         default:
1596             return false;
1597         }
1598         addr_t target = ReadCoreReg (Rm, &success);
1599         if (!success)
1600             return false;
1601         RegisterInfo dwarf_reg;
1602         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1603         context.SetRegister (dwarf_reg);
1604         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1605             return false;
1606         if (!BXWritePC(context, target))
1607             return false;
1608     }
1609     return true;
1610 }
1611 
1612 // Branch and Exchange causes a branch to an address and instruction set specified by a register.
1613 bool
1614 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding)
1615 {
1616 #if 0
1617     // ARM pseudo code...
1618     if (ConditionPassed())
1619     {
1620         EncodingSpecificOperations();
1621         BXWritePC(R[m]);
1622     }
1623 #endif
1624 
1625     if (ConditionPassed(opcode))
1626     {
1627         EmulateInstruction::Context context;
1628         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1629         uint32_t Rm; // the register with the target address
1630         switch (encoding) {
1631         case eEncodingT1:
1632             Rm = Bits32(opcode, 6, 3);
1633             if (InITBlock() && !LastInITBlock())
1634                 return false;
1635             break;
1636         case eEncodingA1:
1637             Rm = Bits32(opcode, 3, 0);
1638             break;
1639         default:
1640             return false;
1641         }
1642         bool success = false;
1643         addr_t target = ReadCoreReg (Rm, &success);
1644         if (!success)
1645             return false;
1646 
1647         RegisterInfo dwarf_reg;
1648         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1649         context.SetRegister (dwarf_reg);
1650         if (!BXWritePC(context, target))
1651             return false;
1652     }
1653     return true;
1654 }
1655 
1656 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an
1657 // address and instruction set specified by a register as though it were a BX instruction.
1658 //
1659 // TODO: Emulate Jazelle architecture?
1660 //       We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation.
1661 bool
1662 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding)
1663 {
1664 #if 0
1665     // ARM pseudo code...
1666     if (ConditionPassed())
1667     {
1668         EncodingSpecificOperations();
1669         if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
1670             BXWritePC(R[m]);
1671         else
1672             if JazelleAcceptsExecution() then
1673                 SwitchToJazelleExecution();
1674             else
1675                 SUBARCHITECTURE_DEFINED handler call;
1676     }
1677 #endif
1678 
1679     if (ConditionPassed(opcode))
1680     {
1681         EmulateInstruction::Context context;
1682         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1683         uint32_t Rm; // the register with the target address
1684         switch (encoding) {
1685         case eEncodingT1:
1686             Rm = Bits32(opcode, 19, 16);
1687             if (BadReg(Rm))
1688                 return false;
1689             if (InITBlock() && !LastInITBlock())
1690                 return false;
1691             break;
1692         case eEncodingA1:
1693             Rm = Bits32(opcode, 3, 0);
1694             if (Rm == 15)
1695                 return false;
1696             break;
1697         default:
1698             return false;
1699         }
1700         bool success = false;
1701         addr_t target = ReadCoreReg (Rm, &success);
1702         if (!success)
1703             return false;
1704 
1705         RegisterInfo dwarf_reg;
1706         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1707         context.SetRegister (dwarf_reg);
1708         if (!BXWritePC(context, target))
1709             return false;
1710     }
1711     return true;
1712 }
1713 
1714 // Set r7 to point to some ip offset.
1715 // SUB (immediate)
1716 bool
1717 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding)
1718 {
1719 #if 0
1720     // ARM pseudo code...
1721     if (ConditionPassed())
1722     {
1723         EncodingSpecificOperations();
1724         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1725         if d == 15 then // Can only occur for ARM encoding
1726            ALUWritePC(result); // setflags is always FALSE here
1727         else
1728             R[d] = result;
1729             if setflags then
1730                 APSR.N = result<31>;
1731                 APSR.Z = IsZeroBit(result);
1732                 APSR.C = carry;
1733                 APSR.V = overflow;
1734     }
1735 #endif
1736 
1737     if (ConditionPassed(opcode))
1738     {
1739         bool success = false;
1740         const addr_t ip = ReadCoreReg (12, &success);
1741         if (!success)
1742             return false;
1743         uint32_t imm32;
1744         switch (encoding) {
1745         case eEncodingA1:
1746             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1747             break;
1748         default:
1749             return false;
1750         }
1751         addr_t ip_offset = imm32;
1752         addr_t addr = ip - ip_offset; // the adjusted ip value
1753 
1754         EmulateInstruction::Context context;
1755         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1756         RegisterInfo dwarf_reg;
1757         GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg);
1758         context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
1759 
1760         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
1761             return false;
1762     }
1763     return true;
1764 }
1765 
1766 // Set ip to point to some stack offset.
1767 // SUB (SP minus immediate)
1768 bool
1769 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding)
1770 {
1771 #if 0
1772     // ARM pseudo code...
1773     if (ConditionPassed())
1774     {
1775         EncodingSpecificOperations();
1776         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1777         if d == 15 then // Can only occur for ARM encoding
1778            ALUWritePC(result); // setflags is always FALSE here
1779         else
1780             R[d] = result;
1781             if setflags then
1782                 APSR.N = result<31>;
1783                 APSR.Z = IsZeroBit(result);
1784                 APSR.C = carry;
1785                 APSR.V = overflow;
1786     }
1787 #endif
1788 
1789     if (ConditionPassed(opcode))
1790     {
1791         bool success = false;
1792         const addr_t sp = ReadCoreReg (SP_REG, &success);
1793         if (!success)
1794             return false;
1795         uint32_t imm32;
1796         switch (encoding) {
1797         case eEncodingA1:
1798             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1799             break;
1800         default:
1801             return false;
1802         }
1803         addr_t sp_offset = imm32;
1804         addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1805 
1806         EmulateInstruction::Context context;
1807         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1808         RegisterInfo dwarf_reg;
1809         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
1810         context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
1811 
1812         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
1813             return false;
1814     }
1815     return true;
1816 }
1817 
1818 // This instruction subtracts an immediate value from the SP value, and writes
1819 // the result to the destination register.
1820 //
1821 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage.
1822 bool
1823 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding)
1824 {
1825 #if 0
1826     // ARM pseudo code...
1827     if (ConditionPassed())
1828     {
1829         EncodingSpecificOperations();
1830         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1831         if d == 15 then        // Can only occur for ARM encoding
1832            ALUWritePC(result); // setflags is always FALSE here
1833         else
1834             R[d] = result;
1835             if setflags then
1836                 APSR.N = result<31>;
1837                 APSR.Z = IsZeroBit(result);
1838                 APSR.C = carry;
1839                 APSR.V = overflow;
1840     }
1841 #endif
1842 
1843     bool success = false;
1844     if (ConditionPassed(opcode))
1845     {
1846         const addr_t sp = ReadCoreReg (SP_REG, &success);
1847         if (!success)
1848             return false;
1849 
1850         uint32_t Rd;
1851         bool setflags;
1852         uint32_t imm32;
1853         switch (encoding) {
1854         case eEncodingT1:
1855             Rd = 13;
1856             setflags = false;
1857             imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1858             break;
1859         case eEncodingT2:
1860             Rd = Bits32(opcode, 11, 8);
1861             setflags = BitIsSet(opcode, 20);
1862             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1863             if (Rd == 15 && setflags)
1864                 return EmulateCMPImm(opcode, eEncodingT2);
1865             if (Rd == 15 && !setflags)
1866                 return false;
1867             break;
1868         case eEncodingT3:
1869             Rd = Bits32(opcode, 11, 8);
1870             setflags = false;
1871             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
1872             if (Rd == 15)
1873                 return false;
1874             break;
1875         case eEncodingA1:
1876             Rd = Bits32(opcode, 15, 12);
1877             setflags = BitIsSet(opcode, 20);
1878             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1879 
1880             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1881             if (Rd == 15 && setflags)
1882                 return EmulateSUBSPcLrEtc (opcode, encoding);
1883             break;
1884         default:
1885             return false;
1886         }
1887         AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
1888 
1889         EmulateInstruction::Context context;
1890         if (Rd == 13)
1891         {
1892             uint64_t imm64 = imm32;  // Need to expand it to 64 bits before attempting to negate it, or the wrong
1893                                      // value gets passed down to context.SetImmediateSigned.
1894             context.type = EmulateInstruction::eContextAdjustStackPointer;
1895             context.SetImmediateSigned (-imm64); // the stack pointer offset
1896         }
1897         else
1898         {
1899             context.type = EmulateInstruction::eContextImmediate;
1900             context.SetNoArgs ();
1901         }
1902 
1903         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
1904             return false;
1905     }
1906     return true;
1907 }
1908 
1909 // A store operation to the stack that also updates the SP.
1910 bool
1911 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding)
1912 {
1913 #if 0
1914     // ARM pseudo code...
1915     if (ConditionPassed())
1916     {
1917         EncodingSpecificOperations();
1918         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1919         address = if index then offset_addr else R[n];
1920         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1921         if wback then R[n] = offset_addr;
1922     }
1923 #endif
1924 
1925     bool conditional = false;
1926     bool success = false;
1927     if (ConditionPassed(opcode, &conditional))
1928     {
1929         const uint32_t addr_byte_size = GetAddressByteSize();
1930         const addr_t sp = ReadCoreReg (SP_REG, &success);
1931         if (!success)
1932             return false;
1933         uint32_t Rt; // the source register
1934         uint32_t imm12;
1935         uint32_t Rn;  // This function assumes Rn is the SP, but we should verify that.
1936 
1937         bool index;
1938         bool add;
1939         bool wback;
1940         switch (encoding) {
1941         case eEncodingA1:
1942             Rt = Bits32(opcode, 15, 12);
1943             imm12 = Bits32(opcode, 11, 0);
1944             Rn = Bits32 (opcode, 19, 16);
1945 
1946             if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
1947                 return false;
1948 
1949             index = BitIsSet (opcode, 24);
1950             add = BitIsSet (opcode, 23);
1951             wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
1952 
1953             if (wback && ((Rn == 15) || (Rn == Rt)))
1954                 return false;
1955             break;
1956         default:
1957             return false;
1958         }
1959         addr_t offset_addr;
1960         if (add)
1961             offset_addr = sp + imm12;
1962         else
1963             offset_addr = sp - imm12;
1964 
1965         addr_t addr;
1966         if (index)
1967             addr = offset_addr;
1968         else
1969             addr = sp;
1970 
1971         EmulateInstruction::Context context;
1972         if (conditional)
1973             context.type = EmulateInstruction::eContextRegisterStore;
1974         else
1975             context.type = EmulateInstruction::eContextPushRegisterOnStack;
1976         RegisterInfo sp_reg;
1977         RegisterInfo dwarf_reg;
1978 
1979         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1980         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
1981         context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
1982         if (Rt != 15)
1983         {
1984             uint32_t reg_value = ReadCoreReg(Rt, &success);
1985             if (!success)
1986                 return false;
1987             if (!MemUWrite (context, addr, reg_value, addr_byte_size))
1988                 return false;
1989         }
1990         else
1991         {
1992             const uint32_t pc = ReadCoreReg(PC_REG, &success);
1993             if (!success)
1994                 return false;
1995             if (!MemUWrite (context, addr, pc, addr_byte_size))
1996                 return false;
1997         }
1998 
1999 
2000         if (wback)
2001         {
2002             context.type = EmulateInstruction::eContextAdjustStackPointer;
2003             context.SetImmediateSigned (addr - sp);
2004             if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr))
2005                 return false;
2006         }
2007     }
2008     return true;
2009 }
2010 
2011 // Vector Push stores multiple extension registers to the stack.
2012 // It also updates SP to point to the start of the stored data.
2013 bool
2014 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding)
2015 {
2016 #if 0
2017     // ARM pseudo code...
2018     if (ConditionPassed())
2019     {
2020         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2021         address = SP - imm32;
2022         SP = SP - imm32;
2023         if single_regs then
2024             for r = 0 to regs-1
2025                 MemA[address,4] = S[d+r]; address = address+4;
2026         else
2027             for r = 0 to regs-1
2028                 // Store as two word-aligned words in the correct order for current endianness.
2029                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
2030                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
2031                 address = address+8;
2032     }
2033 #endif
2034 
2035     bool success = false;
2036     bool conditional = false;
2037     if (ConditionPassed(opcode, &conditional))
2038     {
2039         const uint32_t addr_byte_size = GetAddressByteSize();
2040         const addr_t sp = ReadCoreReg (SP_REG, &success);
2041         if (!success)
2042             return false;
2043         bool single_regs;
2044         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2045         uint32_t imm32; // stack offset
2046         uint32_t regs;  // number of registers
2047         switch (encoding) {
2048         case eEncodingT1:
2049         case eEncodingA1:
2050             single_regs = false;
2051             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2052             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2053             // If UInt(imm8) is odd, see "FSTMX".
2054             regs = Bits32(opcode, 7, 0) / 2;
2055             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2056             if (regs == 0 || regs > 16 || (d + regs) > 32)
2057                 return false;
2058             break;
2059         case eEncodingT2:
2060         case eEncodingA2:
2061             single_regs = true;
2062             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2063             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2064             regs = Bits32(opcode, 7, 0);
2065             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2066             if (regs == 0 || regs > 16 || (d + regs) > 32)
2067                 return false;
2068             break;
2069         default:
2070             return false;
2071         }
2072         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2073         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2074         addr_t sp_offset = imm32;
2075         addr_t addr = sp - sp_offset;
2076         uint32_t i;
2077 
2078         EmulateInstruction::Context context;
2079         if (conditional)
2080             context.type = EmulateInstruction::eContextRegisterStore;
2081         else
2082             context.type = EmulateInstruction::eContextPushRegisterOnStack;
2083         RegisterInfo dwarf_reg;
2084         RegisterInfo sp_reg;
2085         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2086         for (i=0; i<regs; ++i)
2087         {
2088             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2089             context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
2090             // uint64_t to accommodate 64-bit registers.
2091             uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success);
2092             if (!success)
2093                 return false;
2094             if (!MemAWrite (context, addr, reg_value, reg_byte_size))
2095                 return false;
2096             addr += reg_byte_size;
2097         }
2098 
2099         context.type = EmulateInstruction::eContextAdjustStackPointer;
2100         context.SetImmediateSigned (-sp_offset);
2101 
2102         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2103             return false;
2104     }
2105     return true;
2106 }
2107 
2108 // Vector Pop loads multiple extension registers from the stack.
2109 // It also updates SP to point just above the loaded data.
2110 bool
2111 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding)
2112 {
2113 #if 0
2114     // ARM pseudo code...
2115     if (ConditionPassed())
2116     {
2117         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2118         address = SP;
2119         SP = SP + imm32;
2120         if single_regs then
2121             for r = 0 to regs-1
2122                 S[d+r] = MemA[address,4]; address = address+4;
2123         else
2124             for r = 0 to regs-1
2125                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2126                 // Combine the word-aligned words in the correct order for current endianness.
2127                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2128     }
2129 #endif
2130 
2131     bool success = false;
2132     bool conditional = false;
2133     if (ConditionPassed(opcode, &conditional))
2134     {
2135         const uint32_t addr_byte_size = GetAddressByteSize();
2136         const addr_t sp = ReadCoreReg (SP_REG, &success);
2137         if (!success)
2138             return false;
2139         bool single_regs;
2140         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2141         uint32_t imm32; // stack offset
2142         uint32_t regs;  // number of registers
2143         switch (encoding) {
2144         case eEncodingT1:
2145         case eEncodingA1:
2146             single_regs = false;
2147             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2148             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2149             // If UInt(imm8) is odd, see "FLDMX".
2150             regs = Bits32(opcode, 7, 0) / 2;
2151             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2152             if (regs == 0 || regs > 16 || (d + regs) > 32)
2153                 return false;
2154             break;
2155         case eEncodingT2:
2156         case eEncodingA2:
2157             single_regs = true;
2158             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2159             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2160             regs = Bits32(opcode, 7, 0);
2161             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2162             if (regs == 0 || regs > 16 || (d + regs) > 32)
2163                 return false;
2164             break;
2165         default:
2166             return false;
2167         }
2168         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2169         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2170         addr_t sp_offset = imm32;
2171         addr_t addr = sp;
2172         uint32_t i;
2173         uint64_t data; // uint64_t to accommodate 64-bit registers.
2174 
2175         EmulateInstruction::Context context;
2176         if (conditional)
2177             context.type = EmulateInstruction::eContextRegisterLoad;
2178         else
2179             context.type = EmulateInstruction::eContextPopRegisterOffStack;
2180         RegisterInfo dwarf_reg;
2181         RegisterInfo sp_reg;
2182         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2183         for (i=0; i<regs; ++i)
2184         {
2185             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2186             context.SetRegisterPlusOffset (sp_reg, addr - sp);
2187             data = MemARead(context, addr, reg_byte_size, 0, &success);
2188             if (!success)
2189                 return false;
2190             if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2191                 return false;
2192             addr += reg_byte_size;
2193         }
2194 
2195         context.type = EmulateInstruction::eContextAdjustStackPointer;
2196         context.SetImmediateSigned (sp_offset);
2197 
2198         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2199             return false;
2200     }
2201     return true;
2202 }
2203 
2204 // SVC (previously SWI)
2205 bool
2206 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding)
2207 {
2208 #if 0
2209     // ARM pseudo code...
2210     if (ConditionPassed())
2211     {
2212         EncodingSpecificOperations();
2213         CallSupervisor();
2214     }
2215 #endif
2216 
2217     bool success = false;
2218 
2219     if (ConditionPassed(opcode))
2220     {
2221         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2222         addr_t lr; // next instruction address
2223         if (!success)
2224             return false;
2225         uint32_t imm32; // the immediate constant
2226         uint32_t mode;  // ARM or Thumb mode
2227         switch (encoding) {
2228         case eEncodingT1:
2229             lr = (pc + 2) | 1u; // return address
2230             imm32 = Bits32(opcode, 7, 0);
2231             mode = eModeThumb;
2232             break;
2233         case eEncodingA1:
2234             lr = pc + 4; // return address
2235             imm32 = Bits32(opcode, 23, 0);
2236             mode = eModeARM;
2237             break;
2238         default:
2239             return false;
2240         }
2241 
2242         EmulateInstruction::Context context;
2243         context.type = EmulateInstruction::eContextSupervisorCall;
2244         context.SetISAAndImmediate (mode, imm32);
2245         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
2246             return false;
2247     }
2248     return true;
2249 }
2250 
2251 // If Then makes up to four following instructions (the IT block) conditional.
2252 bool
2253 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding)
2254 {
2255 #if 0
2256     // ARM pseudo code...
2257     EncodingSpecificOperations();
2258     ITSTATE.IT<7:0> = firstcond:mask;
2259 #endif
2260 
2261     m_it_session.InitIT(Bits32(opcode, 7, 0));
2262     return true;
2263 }
2264 
2265 bool
2266 EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding)
2267 {
2268     // NOP, nothing to do...
2269     return true;
2270 }
2271 
2272 // Branch causes a branch to a target address.
2273 bool
2274 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding)
2275 {
2276 #if 0
2277     // ARM pseudo code...
2278     if (ConditionPassed())
2279     {
2280         EncodingSpecificOperations();
2281         BranchWritePC(PC + imm32);
2282     }
2283 #endif
2284 
2285     bool success = false;
2286 
2287     if (ConditionPassed(opcode))
2288     {
2289         EmulateInstruction::Context context;
2290         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2291         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2292         if (!success)
2293             return false;
2294         addr_t target; // target address
2295         int32_t imm32; // PC-relative offset
2296         switch (encoding) {
2297         case eEncodingT1:
2298             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2299             imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2300             target = pc + imm32;
2301             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2302             break;
2303         case eEncodingT2:
2304             imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0));
2305             target = pc + imm32;
2306             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2307             break;
2308         case eEncodingT3:
2309             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2310             {
2311             uint32_t S = Bit32(opcode, 26);
2312             uint32_t imm6 = Bits32(opcode, 21, 16);
2313             uint32_t J1 = Bit32(opcode, 13);
2314             uint32_t J2 = Bit32(opcode, 11);
2315             uint32_t imm11 = Bits32(opcode, 10, 0);
2316             uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2317             imm32 = llvm::SignExtend32<21>(imm21);
2318             target = pc + imm32;
2319             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2320             break;
2321             }
2322         case eEncodingT4:
2323             {
2324             uint32_t S = Bit32(opcode, 26);
2325             uint32_t imm10 = Bits32(opcode, 25, 16);
2326             uint32_t J1 = Bit32(opcode, 13);
2327             uint32_t J2 = Bit32(opcode, 11);
2328             uint32_t imm11 = Bits32(opcode, 10, 0);
2329             uint32_t I1 = !(J1 ^ S);
2330             uint32_t I2 = !(J2 ^ S);
2331             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2332             imm32 = llvm::SignExtend32<25>(imm25);
2333             target = pc + imm32;
2334             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2335             break;
2336             }
2337         case eEncodingA1:
2338             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2339             target = pc + imm32;
2340             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
2341             break;
2342         default:
2343             return false;
2344         }
2345         if (!BranchWritePC(context, target))
2346             return false;
2347     }
2348     return true;
2349 }
2350 
2351 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
2352 // zero and conditionally branch forward a constant value.  They do not affect the condition flags.
2353 // CBNZ, CBZ
2354 bool
2355 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding)
2356 {
2357 #if 0
2358     // ARM pseudo code...
2359     EncodingSpecificOperations();
2360     if nonzero ^ IsZero(R[n]) then
2361         BranchWritePC(PC + imm32);
2362 #endif
2363 
2364     bool success = false;
2365 
2366     // Read the register value from the operand register Rn.
2367     uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2368     if (!success)
2369         return false;
2370 
2371     EmulateInstruction::Context context;
2372     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2373     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2374     if (!success)
2375         return false;
2376 
2377     addr_t target;  // target address
2378     uint32_t imm32; // PC-relative offset to branch forward
2379     bool nonzero;
2380     switch (encoding) {
2381     case eEncodingT1:
2382         imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2383         nonzero = BitIsSet(opcode, 11);
2384         target = pc + imm32;
2385         context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2386         break;
2387     default:
2388         return false;
2389     }
2390     if (nonzero ^ (reg_val == 0))
2391         if (!BranchWritePC(context, target))
2392             return false;
2393 
2394     return true;
2395 }
2396 
2397 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
2398 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2399 // The branch length is twice the value of the byte returned from the table.
2400 //
2401 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
2402 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2403 // The branch length is twice the value of the halfword returned from the table.
2404 // TBB, TBH
2405 bool
2406 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding)
2407 {
2408 #if 0
2409     // ARM pseudo code...
2410     EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2411     if is_tbh then
2412         halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2413     else
2414         halfwords = UInt(MemU[R[n]+R[m], 1]);
2415     BranchWritePC(PC + 2*halfwords);
2416 #endif
2417 
2418     bool success = false;
2419 
2420     uint32_t Rn;     // the base register which contains the address of the table of branch lengths
2421     uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
2422     bool is_tbh;     // true if table branch halfword
2423     switch (encoding) {
2424     case eEncodingT1:
2425         Rn = Bits32(opcode, 19, 16);
2426         Rm = Bits32(opcode, 3, 0);
2427         is_tbh = BitIsSet(opcode, 4);
2428         if (Rn == 13 || BadReg(Rm))
2429             return false;
2430         if (InITBlock() && !LastInITBlock())
2431             return false;
2432         break;
2433     default:
2434         return false;
2435     }
2436 
2437     // Read the address of the table from the operand register Rn.
2438     // The PC can be used, in which case the table immediately follows this instruction.
2439     uint32_t base = ReadCoreReg(Rm, &success);
2440     if (!success)
2441         return false;
2442 
2443     // the table index
2444     uint32_t index = ReadCoreReg(Rm, &success);
2445     if (!success)
2446         return false;
2447 
2448     // the offsetted table address
2449     addr_t addr = base + (is_tbh ? index*2 : index);
2450 
2451     // PC-relative offset to branch forward
2452     EmulateInstruction::Context context;
2453     context.type = EmulateInstruction::eContextTableBranchReadMemory;
2454     uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2455     if (!success)
2456         return false;
2457 
2458     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2459     if (!success)
2460         return false;
2461 
2462     // target address
2463     addr_t target = pc + offset;
2464     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2465     context.SetISAAndImmediateSigned (eModeThumb, 4 + offset);
2466 
2467     if (!BranchWritePC(context, target))
2468         return false;
2469 
2470     return true;
2471 }
2472 
2473 // This instruction adds an immediate value to a register value, and writes the result to the destination register.
2474 // It can optionally update the condition flags based on the result.
2475 bool
2476 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding)
2477 {
2478 #if 0
2479     if ConditionPassed() then
2480         EncodingSpecificOperations();
2481         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2482         R[d] = result;
2483         if setflags then
2484             APSR.N = result<31>;
2485             APSR.Z = IsZeroBit(result);
2486             APSR.C = carry;
2487             APSR.V = overflow;
2488 #endif
2489 
2490     bool success = false;
2491 
2492     if (ConditionPassed(opcode))
2493     {
2494         uint32_t d;
2495         uint32_t n;
2496         bool setflags;
2497         uint32_t imm32;
2498         uint32_t carry_out;
2499 
2500         //EncodingSpecificOperations();
2501         switch (encoding)
2502         {
2503             case eEncodingT1:
2504                 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32);
2505                 d = Bits32 (opcode, 2, 0);
2506                 n = Bits32 (opcode, 5, 3);
2507                 setflags = !InITBlock();
2508                 imm32 = Bits32 (opcode, 8,6);
2509 
2510                 break;
2511 
2512             case eEncodingT2:
2513                 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32);
2514                 d = Bits32 (opcode, 10, 8);
2515                 n = Bits32 (opcode, 10, 8);
2516                 setflags = !InITBlock();
2517                 imm32 = Bits32 (opcode, 7, 0);
2518 
2519                 break;
2520 
2521             case eEncodingT3:
2522                 // if Rd == '1111' && S == '1' then SEE CMN (immediate);
2523                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2524                 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8);
2525                 d = Bits32 (opcode, 11, 8);
2526                 n = Bits32 (opcode, 19, 16);
2527                 setflags = BitIsSet (opcode, 20);
2528                 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out);
2529 
2530                 // if BadReg(d) || n == 15 then UNPREDICTABLE;
2531                 if (BadReg (d) || (n == 15))
2532                     return false;
2533 
2534                 break;
2535 
2536             case eEncodingT4:
2537             {
2538                 // if Rn == '1111' then SEE ADR;
2539                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2540                 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
2541                 d = Bits32 (opcode, 11, 8);
2542                 n = Bits32 (opcode, 19, 16);
2543                 setflags = false;
2544                 uint32_t i = Bit32 (opcode, 26);
2545                 uint32_t imm3 = Bits32 (opcode, 14, 12);
2546                 uint32_t imm8 = Bits32 (opcode, 7, 0);
2547                 imm32 = (i << 11) | (imm3 << 8) | imm8;
2548 
2549                 // if BadReg(d) then UNPREDICTABLE;
2550                 if (BadReg (d))
2551                     return false;
2552 
2553                 break;
2554             }
2555             default:
2556                 return false;
2557         }
2558 
2559         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2560         if (!success)
2561             return false;
2562 
2563         //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2564         AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
2565 
2566         RegisterInfo reg_n;
2567         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
2568 
2569         EmulateInstruction::Context context;
2570         context.type = eContextArithmetic;
2571         context.SetRegisterPlusOffset (reg_n, imm32);
2572 
2573         //R[d] = result;
2574         //if setflags then
2575             //APSR.N = result<31>;
2576             //APSR.Z = IsZeroBit(result);
2577             //APSR.C = carry;
2578             //APSR.V = overflow;
2579         if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
2580             return false;
2581 
2582     }
2583     return true;
2584 }
2585 
2586 // This instruction adds an immediate value to a register value, and writes the result to the destination
2587 // register.  It can optionally update the condition flags based on the result.
2588 bool
2589 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding)
2590 {
2591 #if 0
2592     // ARM pseudo code...
2593     if ConditionPassed() then
2594         EncodingSpecificOperations();
2595         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2596         if d == 15 then
2597             ALUWritePC(result); // setflags is always FALSE here
2598         else
2599             R[d] = result;
2600             if setflags then
2601                 APSR.N = result<31>;
2602                 APSR.Z = IsZeroBit(result);
2603                 APSR.C = carry;
2604                 APSR.V = overflow;
2605 #endif
2606 
2607     bool success = false;
2608 
2609     if (ConditionPassed(opcode))
2610     {
2611         uint32_t Rd, Rn;
2612         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
2613         bool setflags;
2614         switch (encoding)
2615         {
2616         case eEncodingA1:
2617             Rd = Bits32(opcode, 15, 12);
2618             Rn = Bits32(opcode, 19, 16);
2619             setflags = BitIsSet(opcode, 20);
2620             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2621             break;
2622         default:
2623             return false;
2624         }
2625 
2626         // Read the first operand.
2627         uint32_t val1 = ReadCoreReg(Rn, &success);
2628         if (!success)
2629             return false;
2630 
2631         AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
2632 
2633         EmulateInstruction::Context context;
2634         context.type = eContextArithmetic;
2635         RegisterInfo dwarf_reg;
2636         GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
2637         context.SetRegisterPlusOffset (dwarf_reg, imm32);
2638 
2639         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2640             return false;
2641     }
2642     return true;
2643 }
2644 
2645 // This instruction adds a register value and an optionally-shifted register value, and writes the result
2646 // to the destination register. It can optionally update the condition flags based on the result.
2647 bool
2648 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding)
2649 {
2650 #if 0
2651     // ARM pseudo code...
2652     if ConditionPassed() then
2653         EncodingSpecificOperations();
2654         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2655         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2656         if d == 15 then
2657             ALUWritePC(result); // setflags is always FALSE here
2658         else
2659             R[d] = result;
2660             if setflags then
2661                 APSR.N = result<31>;
2662                 APSR.Z = IsZeroBit(result);
2663                 APSR.C = carry;
2664                 APSR.V = overflow;
2665 #endif
2666 
2667     bool success = false;
2668 
2669     if (ConditionPassed(opcode))
2670     {
2671         uint32_t Rd, Rn, Rm;
2672         ARM_ShifterType shift_t;
2673         uint32_t shift_n; // the shift applied to the value read from Rm
2674         bool setflags;
2675         switch (encoding)
2676         {
2677         case eEncodingT1:
2678             Rd = Bits32(opcode, 2, 0);
2679             Rn = Bits32(opcode, 5, 3);
2680             Rm = Bits32(opcode, 8, 6);
2681             setflags = !InITBlock();
2682             shift_t = SRType_LSL;
2683             shift_n = 0;
2684             break;
2685         case eEncodingT2:
2686             Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2687             Rm = Bits32(opcode, 6, 3);
2688             setflags = false;
2689             shift_t = SRType_LSL;
2690             shift_n = 0;
2691             if (Rn == 15 && Rm == 15)
2692                 return false;
2693             if (Rd == 15 && InITBlock() && !LastInITBlock())
2694                 return false;
2695             break;
2696         case eEncodingA1:
2697             Rd = Bits32(opcode, 15, 12);
2698             Rn = Bits32(opcode, 19, 16);
2699             Rm = Bits32(opcode, 3, 0);
2700             setflags = BitIsSet(opcode, 20);
2701             shift_n = DecodeImmShiftARM(opcode, shift_t);
2702             break;
2703         default:
2704             return false;
2705         }
2706 
2707         // Read the first operand.
2708         uint32_t val1 = ReadCoreReg(Rn, &success);
2709         if (!success)
2710             return false;
2711 
2712         // Read the second operand.
2713         uint32_t val2 = ReadCoreReg(Rm, &success);
2714         if (!success)
2715             return false;
2716 
2717         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2718         if (!success)
2719             return false;
2720         AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2721 
2722         EmulateInstruction::Context context;
2723         context.type = eContextArithmetic;
2724         RegisterInfo op1_reg;
2725         RegisterInfo op2_reg;
2726         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
2727         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
2728         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
2729 
2730         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2731             return false;
2732     }
2733     return true;
2734 }
2735 
2736 // Compare Negative (immediate) adds a register value and an immediate value.
2737 // It updates the condition flags based on the result, and discards the result.
2738 bool
2739 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding)
2740 {
2741 #if 0
2742     // ARM pseudo code...
2743     if ConditionPassed() then
2744         EncodingSpecificOperations();
2745         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2746         APSR.N = result<31>;
2747         APSR.Z = IsZeroBit(result);
2748         APSR.C = carry;
2749         APSR.V = overflow;
2750 #endif
2751 
2752     bool success = false;
2753 
2754     uint32_t Rn; // the first operand
2755     uint32_t imm32; // the immediate value to be compared with
2756     switch (encoding) {
2757     case eEncodingT1:
2758         Rn = Bits32(opcode, 19, 16);
2759         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2760         if (Rn == 15)
2761             return false;
2762         break;
2763     case eEncodingA1:
2764         Rn = Bits32(opcode, 19, 16);
2765         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2766         break;
2767     default:
2768         return false;
2769     }
2770     // Read the register value from the operand register Rn.
2771     uint32_t reg_val = ReadCoreReg(Rn, &success);
2772     if (!success)
2773         return false;
2774 
2775     AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
2776 
2777     EmulateInstruction::Context context;
2778     context.type = EmulateInstruction::eContextImmediate;
2779     context.SetNoArgs ();
2780     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2781         return false;
2782 
2783     return true;
2784 }
2785 
2786 // Compare Negative (register) adds a register value and an optionally-shifted register value.
2787 // It updates the condition flags based on the result, and discards the result.
2788 bool
2789 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding)
2790 {
2791 #if 0
2792     // ARM pseudo code...
2793     if ConditionPassed() then
2794         EncodingSpecificOperations();
2795         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2796         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2797         APSR.N = result<31>;
2798         APSR.Z = IsZeroBit(result);
2799         APSR.C = carry;
2800         APSR.V = overflow;
2801 #endif
2802 
2803     bool success = false;
2804 
2805     uint32_t Rn; // the first operand
2806     uint32_t Rm; // the second operand
2807     ARM_ShifterType shift_t;
2808     uint32_t shift_n; // the shift applied to the value read from Rm
2809     switch (encoding) {
2810     case eEncodingT1:
2811         Rn = Bits32(opcode, 2, 0);
2812         Rm = Bits32(opcode, 5, 3);
2813         shift_t = SRType_LSL;
2814         shift_n = 0;
2815         break;
2816     case eEncodingT2:
2817         Rn = Bits32(opcode, 19, 16);
2818         Rm = Bits32(opcode, 3, 0);
2819         shift_n = DecodeImmShiftThumb(opcode, shift_t);
2820         // if n == 15 || BadReg(m) then UNPREDICTABLE;
2821         if (Rn == 15 || BadReg(Rm))
2822             return false;
2823         break;
2824     case eEncodingA1:
2825         Rn = Bits32(opcode, 19, 16);
2826         Rm = Bits32(opcode, 3, 0);
2827         shift_n = DecodeImmShiftARM(opcode, shift_t);
2828         break;
2829     default:
2830         return false;
2831     }
2832     // Read the register value from register Rn.
2833     uint32_t val1 = ReadCoreReg(Rn, &success);
2834     if (!success)
2835         return false;
2836 
2837     // Read the register value from register Rm.
2838     uint32_t val2 = ReadCoreReg(Rm, &success);
2839     if (!success)
2840         return false;
2841 
2842     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2843     if (!success)
2844         return false;
2845     AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2846 
2847     EmulateInstruction::Context context;
2848     context.type = EmulateInstruction::eContextImmediate;
2849     context.SetNoArgs();
2850     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2851         return false;
2852 
2853     return true;
2854 }
2855 
2856 // Compare (immediate) subtracts an immediate value from a register value.
2857 // It updates the condition flags based on the result, and discards the result.
2858 bool
2859 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding)
2860 {
2861 #if 0
2862     // ARM pseudo code...
2863     if ConditionPassed() then
2864         EncodingSpecificOperations();
2865         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2866         APSR.N = result<31>;
2867         APSR.Z = IsZeroBit(result);
2868         APSR.C = carry;
2869         APSR.V = overflow;
2870 #endif
2871 
2872     bool success = false;
2873 
2874     uint32_t Rn; // the first operand
2875     uint32_t imm32; // the immediate value to be compared with
2876     switch (encoding) {
2877     case eEncodingT1:
2878         Rn = Bits32(opcode, 10, 8);
2879         imm32 = Bits32(opcode, 7, 0);
2880         break;
2881     case eEncodingT2:
2882         Rn = Bits32(opcode, 19, 16);
2883         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2884         if (Rn == 15)
2885             return false;
2886         break;
2887     case eEncodingA1:
2888         Rn = Bits32(opcode, 19, 16);
2889         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2890         break;
2891     default:
2892         return false;
2893     }
2894     // Read the register value from the operand register Rn.
2895     uint32_t reg_val = ReadCoreReg(Rn, &success);
2896     if (!success)
2897         return false;
2898 
2899     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
2900 
2901     EmulateInstruction::Context context;
2902     context.type = EmulateInstruction::eContextImmediate;
2903     context.SetNoArgs ();
2904     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2905         return false;
2906 
2907     return true;
2908 }
2909 
2910 // Compare (register) subtracts an optionally-shifted register value from a register value.
2911 // It updates the condition flags based on the result, and discards the result.
2912 bool
2913 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding)
2914 {
2915 #if 0
2916     // ARM pseudo code...
2917     if ConditionPassed() then
2918         EncodingSpecificOperations();
2919         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2920         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2921         APSR.N = result<31>;
2922         APSR.Z = IsZeroBit(result);
2923         APSR.C = carry;
2924         APSR.V = overflow;
2925 #endif
2926 
2927     bool success = false;
2928 
2929     uint32_t Rn; // the first operand
2930     uint32_t Rm; // the second operand
2931     ARM_ShifterType shift_t;
2932     uint32_t shift_n; // the shift applied to the value read from Rm
2933     switch (encoding) {
2934     case eEncodingT1:
2935         Rn = Bits32(opcode, 2, 0);
2936         Rm = Bits32(opcode, 5, 3);
2937         shift_t = SRType_LSL;
2938         shift_n = 0;
2939         break;
2940     case eEncodingT2:
2941         Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2942         Rm = Bits32(opcode, 6, 3);
2943         shift_t = SRType_LSL;
2944         shift_n = 0;
2945         if (Rn < 8 && Rm < 8)
2946             return false;
2947         if (Rn == 15 || Rm == 15)
2948             return false;
2949         break;
2950     case eEncodingA1:
2951         Rn = Bits32(opcode, 19, 16);
2952         Rm = Bits32(opcode, 3, 0);
2953         shift_n = DecodeImmShiftARM(opcode, shift_t);
2954         break;
2955     default:
2956         return false;
2957     }
2958     // Read the register value from register Rn.
2959     uint32_t val1 = ReadCoreReg(Rn, &success);
2960     if (!success)
2961         return false;
2962 
2963     // Read the register value from register Rm.
2964     uint32_t val2 = ReadCoreReg(Rm, &success);
2965     if (!success)
2966         return false;
2967 
2968     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2969     if (!success)
2970         return false;
2971     AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
2972 
2973     EmulateInstruction::Context context;
2974     context.type = EmulateInstruction::eContextImmediate;
2975     context.SetNoArgs();
2976     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2977         return false;
2978 
2979     return true;
2980 }
2981 
2982 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
2983 // shifting in copies of its sign bit, and writes the result to the destination register.  It can
2984 // optionally update the condition flags based on the result.
2985 bool
2986 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding)
2987 {
2988 #if 0
2989     // ARM pseudo code...
2990     if ConditionPassed() then
2991         EncodingSpecificOperations();
2992         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2993         if d == 15 then         // Can only occur for ARM encoding
2994             ALUWritePC(result); // setflags is always FALSE here
2995         else
2996             R[d] = result;
2997             if setflags then
2998                 APSR.N = result<31>;
2999                 APSR.Z = IsZeroBit(result);
3000                 APSR.C = carry;
3001                 // APSR.V unchanged
3002 #endif
3003 
3004     return EmulateShiftImm (opcode, encoding, SRType_ASR);
3005 }
3006 
3007 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
3008 // shifting in copies of its sign bit, and writes the result to the destination register.
3009 // The variable number of bits is read from the bottom byte of a register. It can optionally update
3010 // the condition flags based on the result.
3011 bool
3012 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding)
3013 {
3014 #if 0
3015     // ARM pseudo code...
3016     if ConditionPassed() then
3017         EncodingSpecificOperations();
3018         shift_n = UInt(R[m]<7:0>);
3019         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3020         R[d] = result;
3021         if setflags then
3022             APSR.N = result<31>;
3023             APSR.Z = IsZeroBit(result);
3024             APSR.C = carry;
3025             // APSR.V unchanged
3026 #endif
3027 
3028     return EmulateShiftReg (opcode, encoding, SRType_ASR);
3029 }
3030 
3031 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
3032 // shifting in zeros, and writes the result to the destination register.  It can optionally
3033 // update the condition flags based on the result.
3034 bool
3035 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding)
3036 {
3037 #if 0
3038     // ARM pseudo code...
3039     if ConditionPassed() then
3040         EncodingSpecificOperations();
3041         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3042         if d == 15 then         // Can only occur for ARM encoding
3043             ALUWritePC(result); // setflags is always FALSE here
3044         else
3045             R[d] = result;
3046             if setflags then
3047                 APSR.N = result<31>;
3048                 APSR.Z = IsZeroBit(result);
3049                 APSR.C = carry;
3050                 // APSR.V unchanged
3051 #endif
3052 
3053     return EmulateShiftImm (opcode, encoding, SRType_LSL);
3054 }
3055 
3056 // Logical Shift Left (register) shifts a register value left by a variable number of bits,
3057 // shifting in zeros, and writes the result to the destination register.  The variable number
3058 // of bits is read from the bottom byte of a register. It can optionally update the condition
3059 // flags based on the result.
3060 bool
3061 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding)
3062 {
3063 #if 0
3064     // ARM pseudo code...
3065     if ConditionPassed() then
3066         EncodingSpecificOperations();
3067         shift_n = UInt(R[m]<7:0>);
3068         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3069         R[d] = result;
3070         if setflags then
3071             APSR.N = result<31>;
3072             APSR.Z = IsZeroBit(result);
3073             APSR.C = carry;
3074             // APSR.V unchanged
3075 #endif
3076 
3077     return EmulateShiftReg (opcode, encoding, SRType_LSL);
3078 }
3079 
3080 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
3081 // shifting in zeros, and writes the result to the destination register.  It can optionally
3082 // update the condition flags based on the result.
3083 bool
3084 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding)
3085 {
3086 #if 0
3087     // ARM pseudo code...
3088     if ConditionPassed() then
3089         EncodingSpecificOperations();
3090         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3091         if d == 15 then         // Can only occur for ARM encoding
3092             ALUWritePC(result); // setflags is always FALSE here
3093         else
3094             R[d] = result;
3095             if setflags then
3096                 APSR.N = result<31>;
3097                 APSR.Z = IsZeroBit(result);
3098                 APSR.C = carry;
3099                 // APSR.V unchanged
3100 #endif
3101 
3102     return EmulateShiftImm (opcode, encoding, SRType_LSR);
3103 }
3104 
3105 // Logical Shift Right (register) shifts a register value right by a variable number of bits,
3106 // shifting in zeros, and writes the result to the destination register.  The variable number
3107 // of bits is read from the bottom byte of a register. It can optionally update the condition
3108 // flags based on the result.
3109 bool
3110 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding)
3111 {
3112 #if 0
3113     // ARM pseudo code...
3114     if ConditionPassed() then
3115         EncodingSpecificOperations();
3116         shift_n = UInt(R[m]<7:0>);
3117         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3118         R[d] = result;
3119         if setflags then
3120             APSR.N = result<31>;
3121             APSR.Z = IsZeroBit(result);
3122             APSR.C = carry;
3123             // APSR.V unchanged
3124 #endif
3125 
3126     return EmulateShiftReg (opcode, encoding, SRType_LSR);
3127 }
3128 
3129 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
3130 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3131 // It can optionally update the condition flags based on the result.
3132 bool
3133 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding)
3134 {
3135 #if 0
3136     // ARM pseudo code...
3137     if ConditionPassed() then
3138         EncodingSpecificOperations();
3139         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3140         if d == 15 then         // Can only occur for ARM encoding
3141             ALUWritePC(result); // setflags is always FALSE here
3142         else
3143             R[d] = result;
3144             if setflags then
3145                 APSR.N = result<31>;
3146                 APSR.Z = IsZeroBit(result);
3147                 APSR.C = carry;
3148                 // APSR.V unchanged
3149 #endif
3150 
3151     return EmulateShiftImm (opcode, encoding, SRType_ROR);
3152 }
3153 
3154 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
3155 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3156 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
3157 // flags based on the result.
3158 bool
3159 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding)
3160 {
3161 #if 0
3162     // ARM pseudo code...
3163     if ConditionPassed() then
3164         EncodingSpecificOperations();
3165         shift_n = UInt(R[m]<7:0>);
3166         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3167         R[d] = result;
3168         if setflags then
3169             APSR.N = result<31>;
3170             APSR.Z = IsZeroBit(result);
3171             APSR.C = carry;
3172             // APSR.V unchanged
3173 #endif
3174 
3175     return EmulateShiftReg (opcode, encoding, SRType_ROR);
3176 }
3177 
3178 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
3179 // with the carry flag shifted into bit [31].
3180 //
3181 // RRX can optionally update the condition flags based on the result.
3182 // In that case, bit [0] is shifted into the carry flag.
3183 bool
3184 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding)
3185 {
3186 #if 0
3187     // ARM pseudo code...
3188     if ConditionPassed() then
3189         EncodingSpecificOperations();
3190         (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3191         if d == 15 then         // Can only occur for ARM encoding
3192             ALUWritePC(result); // setflags is always FALSE here
3193         else
3194             R[d] = result;
3195             if setflags then
3196                 APSR.N = result<31>;
3197                 APSR.Z = IsZeroBit(result);
3198                 APSR.C = carry;
3199                 // APSR.V unchanged
3200 #endif
3201 
3202     return EmulateShiftImm (opcode, encoding, SRType_RRX);
3203 }
3204 
3205 bool
3206 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3207 {
3208 //    assert(shift_type == SRType_ASR
3209 //           || shift_type == SRType_LSL
3210 //           || shift_type == SRType_LSR
3211 //           || shift_type == SRType_ROR
3212 //           || shift_type == SRType_RRX);
3213 
3214     bool success = false;
3215 
3216     if (ConditionPassed(opcode))
3217     {
3218         uint32_t Rd;    // the destination register
3219         uint32_t Rm;    // the first operand register
3220         uint32_t imm5;  // encoding for the shift amount
3221         uint32_t carry; // the carry bit after the shift operation
3222         bool setflags;
3223 
3224         // Special case handling!
3225         // A8.6.139 ROR (immediate) -- Encoding T1
3226         ARMEncoding use_encoding = encoding;
3227         if (shift_type == SRType_ROR && use_encoding == eEncodingT1)
3228         {
3229             // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
3230             // have the same decoding of bit fields as the other Thumb2 shift operations.
3231             use_encoding = eEncodingT2;
3232         }
3233 
3234         switch (use_encoding) {
3235         case eEncodingT1:
3236             // Due to the above special case handling!
3237             if (shift_type == SRType_ROR)
3238                 return false;
3239 
3240             Rd = Bits32(opcode, 2, 0);
3241             Rm = Bits32(opcode, 5, 3);
3242             setflags = !InITBlock();
3243             imm5 = Bits32(opcode, 10, 6);
3244             break;
3245         case eEncodingT2:
3246             // A8.6.141 RRX
3247             // There's no imm form of RRX instructions.
3248             if (shift_type == SRType_RRX)
3249                 return false;
3250 
3251             Rd = Bits32(opcode, 11, 8);
3252             Rm = Bits32(opcode, 3, 0);
3253             setflags = BitIsSet(opcode, 20);
3254             imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3255             if (BadReg(Rd) || BadReg(Rm))
3256                 return false;
3257             break;
3258         case eEncodingA1:
3259             Rd = Bits32(opcode, 15, 12);
3260             Rm = Bits32(opcode, 3, 0);
3261             setflags = BitIsSet(opcode, 20);
3262             imm5 = Bits32(opcode, 11, 7);
3263             break;
3264         default:
3265             return false;
3266         }
3267 
3268         // A8.6.139 ROR (immediate)
3269         if (shift_type == SRType_ROR && imm5 == 0)
3270             shift_type = SRType_RRX;
3271 
3272         // Get the first operand.
3273         uint32_t value = ReadCoreReg (Rm, &success);
3274         if (!success)
3275             return false;
3276 
3277         // Decode the shift amount if not RRX.
3278         uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3279 
3280         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3281         if (!success)
3282             return false;
3283 
3284         // The context specifies that an immediate is to be moved into Rd.
3285         EmulateInstruction::Context context;
3286         context.type = EmulateInstruction::eContextImmediate;
3287         context.SetNoArgs ();
3288 
3289         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3290             return false;
3291     }
3292     return true;
3293 }
3294 
3295 bool
3296 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3297 {
3298     // assert(shift_type == SRType_ASR
3299     //        || shift_type == SRType_LSL
3300     //        || shift_type == SRType_LSR
3301     //        || shift_type == SRType_ROR);
3302 
3303     bool success = false;
3304 
3305     if (ConditionPassed(opcode))
3306     {
3307         uint32_t Rd;    // the destination register
3308         uint32_t Rn;    // the first operand register
3309         uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
3310         uint32_t carry; // the carry bit after the shift operation
3311         bool setflags;
3312         switch (encoding) {
3313         case eEncodingT1:
3314             Rd = Bits32(opcode, 2, 0);
3315             Rn = Rd;
3316             Rm = Bits32(opcode, 5, 3);
3317             setflags = !InITBlock();
3318             break;
3319         case eEncodingT2:
3320             Rd = Bits32(opcode, 11, 8);
3321             Rn = Bits32(opcode, 19, 16);
3322             Rm = Bits32(opcode, 3, 0);
3323             setflags = BitIsSet(opcode, 20);
3324             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3325                 return false;
3326             break;
3327         case eEncodingA1:
3328             Rd = Bits32(opcode, 15, 12);
3329             Rn = Bits32(opcode, 3, 0);
3330             Rm = Bits32(opcode, 11, 8);
3331             setflags = BitIsSet(opcode, 20);
3332             if (Rd == 15 || Rn == 15 || Rm == 15)
3333                 return false;
3334             break;
3335         default:
3336             return false;
3337         }
3338 
3339         // Get the first operand.
3340         uint32_t value = ReadCoreReg (Rn, &success);
3341         if (!success)
3342             return false;
3343         // Get the Rm register content.
3344         uint32_t val = ReadCoreReg (Rm, &success);
3345         if (!success)
3346             return false;
3347 
3348         // Get the shift amount.
3349         uint32_t amt = Bits32(val, 7, 0);
3350 
3351         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3352         if (!success)
3353             return false;
3354 
3355         // The context specifies that an immediate is to be moved into Rd.
3356         EmulateInstruction::Context context;
3357         context.type = EmulateInstruction::eContextImmediate;
3358         context.SetNoArgs ();
3359 
3360         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3361             return false;
3362     }
3363     return true;
3364 }
3365 
3366 // LDM loads multiple registers from consecutive memory locations, using an
3367 // address from a base register.  Optionally the address just above the highest of those locations
3368 // can be written back to the base register.
3369 bool
3370 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding)
3371 {
3372 #if 0
3373     // ARM pseudo code...
3374     if ConditionPassed()
3375         EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3376         address = R[n];
3377 
3378         for i = 0 to 14
3379             if registers<i> == '1' then
3380                 R[i] = MemA[address, 4]; address = address + 4;
3381         if registers<15> == '1' then
3382             LoadWritePC (MemA[address, 4]);
3383 
3384         if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3385         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3386 
3387 #endif
3388 
3389     bool success = false;
3390     bool conditional = false;
3391     if (ConditionPassed(opcode, &conditional))
3392     {
3393         uint32_t n;
3394         uint32_t registers = 0;
3395         bool wback;
3396         const uint32_t addr_byte_size = GetAddressByteSize();
3397         switch (encoding)
3398         {
3399             case eEncodingT1:
3400                 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0');
3401                 n = Bits32 (opcode, 10, 8);
3402                 registers = Bits32 (opcode, 7, 0);
3403                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3404                 wback = BitIsClear (registers, n);
3405                 // if BitCount(registers) < 1 then UNPREDICTABLE;
3406                 if (BitCount(registers) < 1)
3407                     return false;
3408                 break;
3409             case eEncodingT2:
3410                 // if W == '1' && Rn == '1101' then SEE POP;
3411                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3412                 n = Bits32 (opcode, 19, 16);
3413                 registers = Bits32 (opcode, 15, 0);
3414                 registers = registers & 0xdfff; // Make sure bit 13 is zero.
3415                 wback = BitIsSet (opcode, 21);
3416 
3417                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3418                 if ((n == 15)
3419                     || (BitCount (registers) < 2)
3420                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3421                     return false;
3422 
3423                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3424                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3425                     return false;
3426 
3427                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3428                 if (wback
3429                     && BitIsSet (registers, n))
3430                     return false;
3431                 break;
3432 
3433             case eEncodingA1:
3434                 n = Bits32 (opcode, 19, 16);
3435                 registers = Bits32 (opcode, 15, 0);
3436                 wback = BitIsSet (opcode, 21);
3437                 if ((n == 15)
3438                     || (BitCount (registers) < 1))
3439                     return false;
3440                 break;
3441             default:
3442                 return false;
3443         }
3444 
3445         int32_t offset = 0;
3446         const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3447         if (!success)
3448             return false;
3449 
3450         EmulateInstruction::Context context;
3451         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3452         RegisterInfo dwarf_reg;
3453         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3454         context.SetRegisterPlusOffset (dwarf_reg, offset);
3455 
3456         for (int i = 0; i < 14; ++i)
3457         {
3458             if (BitIsSet (registers, i))
3459             {
3460                 context.type = EmulateInstruction::eContextRegisterPlusOffset;
3461                 context.SetRegisterPlusOffset (dwarf_reg, offset);
3462                 if (wback && (n == 13)) // Pop Instruction
3463                 {
3464                     if (conditional)
3465                         context.type = EmulateInstruction::eContextRegisterLoad;
3466                     else
3467                         context.type = EmulateInstruction::eContextPopRegisterOffStack;
3468                 }
3469 
3470                 // R[i] = MemA [address, 4]; address = address + 4;
3471                 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3472                 if (!success)
3473                     return false;
3474 
3475                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3476                     return false;
3477 
3478                 offset += addr_byte_size;
3479             }
3480         }
3481 
3482         if (BitIsSet (registers, 15))
3483         {
3484             //LoadWritePC (MemA [address, 4]);
3485             context.type = EmulateInstruction::eContextRegisterPlusOffset;
3486             context.SetRegisterPlusOffset (dwarf_reg, offset);
3487             uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3488             if (!success)
3489                 return false;
3490             // In ARMv5T and above, this is an interworking branch.
3491             if (!LoadWritePC(context, data))
3492                 return false;
3493         }
3494 
3495         if (wback && BitIsClear (registers, n))
3496         {
3497             // R[n] = R[n] + 4 * BitCount (registers)
3498             int32_t offset = addr_byte_size * BitCount (registers);
3499             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3500             context.SetRegisterPlusOffset (dwarf_reg, offset);
3501 
3502             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
3503                 return false;
3504         }
3505         if (wback && BitIsSet (registers, n))
3506             // R[n] bits(32) UNKNOWN;
3507             return WriteBits32Unknown (n);
3508     }
3509     return true;
3510 }
3511 
3512 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register.
3513 // The consecutive memory locations end at this address and the address just below the lowest of those locations
3514 // can optionally be written back to the base register.
3515 bool
3516 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding)
3517 {
3518 #if 0
3519     // ARM pseudo code...
3520     if ConditionPassed() then
3521         EncodingSpecificOperations();
3522         address = R[n] - 4*BitCount(registers) + 4;
3523 
3524         for i = 0 to 14
3525             if registers<i> == '1' then
3526                   R[i] = MemA[address,4]; address = address + 4;
3527 
3528         if registers<15> == '1' then
3529             LoadWritePC(MemA[address,4]);
3530 
3531         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3532         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3533 #endif
3534 
3535     bool success = false;
3536 
3537     if (ConditionPassed(opcode))
3538     {
3539         uint32_t n;
3540         uint32_t registers = 0;
3541         bool wback;
3542         const uint32_t addr_byte_size = GetAddressByteSize();
3543 
3544         // EncodingSpecificOperations();
3545         switch (encoding)
3546         {
3547             case eEncodingA1:
3548                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3549                 n = Bits32 (opcode, 19, 16);
3550                 registers = Bits32 (opcode, 15, 0);
3551                 wback = BitIsSet (opcode, 21);
3552 
3553                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3554                 if ((n == 15) || (BitCount (registers) < 1))
3555                     return false;
3556 
3557                 break;
3558 
3559             default:
3560                 return false;
3561         }
3562         // address = R[n] - 4*BitCount(registers) + 4;
3563 
3564         int32_t offset = 0;
3565         addr_t Rn = ReadCoreReg (n, &success);
3566 
3567         if (!success)
3568             return false;
3569 
3570         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size;
3571 
3572         EmulateInstruction::Context context;
3573         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3574         RegisterInfo dwarf_reg;
3575         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3576         context.SetRegisterPlusOffset (dwarf_reg, offset);
3577 
3578         // for i = 0 to 14
3579         for (int i = 0; i < 14; ++i)
3580         {
3581             // if registers<i> == '1' then
3582             if (BitIsSet (registers, i))
3583             {
3584                   // R[i] = MemA[address,4]; address = address + 4;
3585                   context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3586                   uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3587                   if (!success)
3588                       return false;
3589                   if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3590                       return false;
3591                   offset += addr_byte_size;
3592             }
3593         }
3594 
3595         // if registers<15> == '1' then
3596         //     LoadWritePC(MemA[address,4]);
3597         if (BitIsSet (registers, 15))
3598         {
3599             context.SetRegisterPlusOffset (dwarf_reg, offset);
3600             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3601             if (!success)
3602                 return false;
3603             // In ARMv5T and above, this is an interworking branch.
3604             if (!LoadWritePC(context, data))
3605                 return false;
3606         }
3607 
3608         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3609         if (wback && BitIsClear (registers, n))
3610         {
3611             if (!success)
3612                 return false;
3613 
3614             offset = (addr_byte_size * BitCount (registers)) * -1;
3615             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3616             context.SetImmediateSigned (offset);
3617             addr_t addr = Rn + offset;
3618             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3619                 return false;
3620         }
3621 
3622         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3623         if (wback && BitIsSet (registers, n))
3624             return WriteBits32Unknown (n);
3625     }
3626     return true;
3627 }
3628 
3629 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
3630 // consecutive memory locations end just below this address, and the address of the lowest of those locations can
3631 // be optionally written back to the base register.
3632 bool
3633 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding)
3634 {
3635 #if 0
3636     // ARM pseudo code...
3637     if ConditionPassed() then
3638         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3639         address = R[n] - 4*BitCount(registers);
3640 
3641         for i = 0 to 14
3642             if registers<i> == '1' then
3643                   R[i] = MemA[address,4]; address = address + 4;
3644         if registers<15> == '1' then
3645                   LoadWritePC(MemA[address,4]);
3646 
3647         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3648         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3649 #endif
3650 
3651     bool success = false;
3652 
3653     if (ConditionPassed(opcode))
3654     {
3655         uint32_t n;
3656         uint32_t registers = 0;
3657         bool wback;
3658         const uint32_t addr_byte_size = GetAddressByteSize();
3659         switch (encoding)
3660         {
3661             case eEncodingT1:
3662                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3663                 n = Bits32 (opcode, 19, 16);
3664                 registers = Bits32 (opcode, 15, 0);
3665                 registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
3666                 wback = BitIsSet (opcode, 21);
3667 
3668                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3669                 if ((n == 15)
3670                     || (BitCount (registers) < 2)
3671                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3672                     return false;
3673 
3674                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3675                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3676                     return false;
3677 
3678                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3679                 if (wback && BitIsSet (registers, n))
3680                     return false;
3681 
3682                 break;
3683 
3684             case eEncodingA1:
3685                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3686                 n = Bits32 (opcode, 19, 16);
3687                 registers = Bits32 (opcode, 15, 0);
3688                 wback = BitIsSet (opcode, 21);
3689 
3690                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3691                 if ((n == 15) || (BitCount (registers) < 1))
3692                     return false;
3693 
3694                 break;
3695 
3696             default:
3697                 return false;
3698         }
3699 
3700         // address = R[n] - 4*BitCount(registers);
3701 
3702         int32_t offset = 0;
3703         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3704 
3705         if (!success)
3706             return false;
3707 
3708         addr_t address = Rn - (addr_byte_size * BitCount (registers));
3709         EmulateInstruction::Context context;
3710         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3711         RegisterInfo dwarf_reg;
3712         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3713         context.SetRegisterPlusOffset (dwarf_reg, Rn - address);
3714 
3715         for (int i = 0; i < 14; ++i)
3716         {
3717             if (BitIsSet (registers, i))
3718             {
3719                 // R[i] = MemA[address,4]; address = address + 4;
3720                 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3721                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3722                 if (!success)
3723                     return false;
3724 
3725                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3726                     return false;
3727 
3728                 offset += addr_byte_size;
3729             }
3730         }
3731 
3732         // if registers<15> == '1' then
3733         //     LoadWritePC(MemA[address,4]);
3734         if (BitIsSet (registers, 15))
3735         {
3736             context.SetRegisterPlusOffset (dwarf_reg, offset);
3737             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3738             if (!success)
3739                 return false;
3740             // In ARMv5T and above, this is an interworking branch.
3741             if (!LoadWritePC(context, data))
3742                 return false;
3743         }
3744 
3745         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3746         if (wback && BitIsClear (registers, n))
3747         {
3748             if (!success)
3749                 return false;
3750 
3751             offset = (addr_byte_size * BitCount (registers)) * -1;
3752             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3753             context.SetImmediateSigned (offset);
3754             addr_t addr = Rn + offset;
3755             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3756                 return false;
3757         }
3758 
3759         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3760         if (wback && BitIsSet (registers, n))
3761             return WriteBits32Unknown (n);
3762     }
3763     return true;
3764 }
3765 
3766 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
3767 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can
3768 // optinoally be written back to the base register.
3769 bool
3770 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding)
3771 {
3772 #if 0
3773     if ConditionPassed() then
3774         EncodingSpecificOperations();
3775         address = R[n] + 4;
3776 
3777         for i = 0 to 14
3778             if registers<i> == '1' then
3779                   R[i] = MemA[address,4]; address = address + 4;
3780         if registers<15> == '1' then
3781             LoadWritePC(MemA[address,4]);
3782 
3783         if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3784         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3785 #endif
3786 
3787     bool success = false;
3788 
3789     if (ConditionPassed(opcode))
3790     {
3791         uint32_t n;
3792         uint32_t registers = 0;
3793         bool wback;
3794         const uint32_t addr_byte_size = GetAddressByteSize();
3795         switch (encoding)
3796         {
3797             case eEncodingA1:
3798                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3799                 n = Bits32 (opcode, 19, 16);
3800                 registers = Bits32 (opcode, 15, 0);
3801                 wback = BitIsSet (opcode, 21);
3802 
3803                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3804                 if ((n == 15) || (BitCount (registers) < 1))
3805                     return false;
3806 
3807                 break;
3808             default:
3809                 return false;
3810         }
3811         // address = R[n] + 4;
3812 
3813         int32_t offset = 0;
3814         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3815 
3816         if (!success)
3817             return false;
3818 
3819         addr_t address = Rn + addr_byte_size;
3820 
3821         EmulateInstruction::Context context;
3822         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3823         RegisterInfo dwarf_reg;
3824         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3825         context.SetRegisterPlusOffset (dwarf_reg, offset);
3826 
3827         for (int i = 0; i < 14; ++i)
3828         {
3829             if (BitIsSet (registers, i))
3830             {
3831                 // R[i] = MemA[address,4]; address = address + 4;
3832 
3833                 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size);
3834                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3835                 if (!success)
3836                     return false;
3837 
3838                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3839                     return false;
3840 
3841                 offset += addr_byte_size;
3842             }
3843         }
3844 
3845         // if registers<15> == '1' then
3846         //     LoadWritePC(MemA[address,4]);
3847         if (BitIsSet (registers, 15))
3848         {
3849             context.SetRegisterPlusOffset (dwarf_reg, offset);
3850             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3851             if (!success)
3852                 return false;
3853             // In ARMv5T and above, this is an interworking branch.
3854             if (!LoadWritePC(context, data))
3855                 return false;
3856         }
3857 
3858         // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3859         if (wback && BitIsClear (registers, n))
3860         {
3861             if (!success)
3862                 return false;
3863 
3864             offset = addr_byte_size * BitCount (registers);
3865             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3866             context.SetImmediateSigned (offset);
3867             addr_t addr = Rn + offset;
3868             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3869                 return false;
3870         }
3871 
3872         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3873         if (wback && BitIsSet (registers, n))
3874             return WriteBits32Unknown (n);
3875     }
3876     return true;
3877 }
3878 
3879 // Load Register (immediate) calculates an address from a base register value and
3880 // an immediate offset, loads a word from memory, and writes to a register.
3881 // LDR (immediate, Thumb)
3882 bool
3883 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding)
3884 {
3885 #if 0
3886     // ARM pseudo code...
3887     if (ConditionPassed())
3888     {
3889         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3890         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3891         address = if index then offset_addr else R[n];
3892         data = MemU[address,4];
3893         if wback then R[n] = offset_addr;
3894         if t == 15 then
3895             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3896         elsif UnalignedSupport() || address<1:0> = '00' then
3897             R[t] = data;
3898         else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3899     }
3900 #endif
3901 
3902     bool success = false;
3903 
3904     if (ConditionPassed(opcode))
3905     {
3906         uint32_t Rt; // the destination register
3907         uint32_t Rn; // the base register
3908         uint32_t imm32; // the immediate offset used to form the address
3909         addr_t offset_addr; // the offset address
3910         addr_t address; // the calculated address
3911         uint32_t data; // the literal data value from memory load
3912         bool add, index, wback;
3913         switch (encoding) {
3914             case eEncodingT1:
3915                 Rt = Bits32(opcode, 2, 0);
3916                 Rn = Bits32(opcode, 5, 3);
3917                 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3918                 // index = TRUE; add = TRUE; wback = FALSE
3919                 add = true;
3920                 index = true;
3921                 wback = false;
3922 
3923                 break;
3924 
3925             case eEncodingT2:
3926                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
3927                 Rt = Bits32 (opcode, 10, 8);
3928                 Rn = 13;
3929                 imm32 = Bits32 (opcode, 7, 0) << 2;
3930 
3931                 // index = TRUE; add = TRUE; wback = FALSE;
3932                 index = true;
3933                 add = true;
3934                 wback = false;
3935 
3936                 break;
3937 
3938             case eEncodingT3:
3939                 // if Rn == '1111' then SEE LDR (literal);
3940                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
3941                 Rt = Bits32 (opcode, 15, 12);
3942                 Rn = Bits32 (opcode, 19, 16);
3943                 imm32 = Bits32 (opcode, 11, 0);
3944 
3945                 // index = TRUE; add = TRUE; wback = FALSE;
3946                 index = true;
3947                 add = true;
3948                 wback = false;
3949 
3950                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3951                 if ((Rt == 15) && InITBlock() && !LastInITBlock())
3952                     return false;
3953 
3954                 break;
3955 
3956             case eEncodingT4:
3957                 // if Rn == '1111' then SEE LDR (literal);
3958                 // if P == '1' && U == '1' && W == '0' then SEE LDRT;
3959                 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
3960                 // if P == '0' && W == '0' then UNDEFINED;
3961                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
3962                     return false;
3963 
3964                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
3965                 Rt = Bits32 (opcode, 15, 12);
3966                 Rn = Bits32 (opcode, 19, 16);
3967                 imm32 = Bits32 (opcode, 7, 0);
3968 
3969                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
3970                 index = BitIsSet (opcode, 10);
3971                 add = BitIsSet (opcode, 9);
3972                 wback = BitIsSet (opcode, 8);
3973 
3974                 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
3975                 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock()))
3976                     return false;
3977 
3978                 break;
3979 
3980             default:
3981                 return false;
3982         }
3983         uint32_t base = ReadCoreReg (Rn, &success);
3984         if (!success)
3985             return false;
3986         if (add)
3987             offset_addr = base + imm32;
3988         else
3989             offset_addr = base - imm32;
3990 
3991         address = (index ? offset_addr : base);
3992 
3993         RegisterInfo base_reg;
3994         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
3995         if (wback)
3996         {
3997             EmulateInstruction::Context ctx;
3998             ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
3999             ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
4000 
4001             if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
4002                 return false;
4003         }
4004 
4005         // Prepare to write to the Rt register.
4006         EmulateInstruction::Context context;
4007         context.type = EmulateInstruction::eContextRegisterLoad;
4008         context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
4009 
4010         // Read memory from the address.
4011         data = MemURead(context, address, 4, 0, &success);
4012         if (!success)
4013             return false;
4014 
4015         if (Rt == 15)
4016         {
4017             if (Bits32(address, 1, 0) == 0)
4018             {
4019                 if (!LoadWritePC(context, data))
4020                     return false;
4021             }
4022             else
4023                 return false;
4024         }
4025         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
4026         {
4027             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
4028                 return false;
4029         }
4030         else
4031             WriteBits32Unknown (Rt);
4032     }
4033     return true;
4034 }
4035 
4036 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
4037 // from a base register.  The consecutive memory locations start at this address, and the address just above the last
4038 // of those locations can optionally be written back to the base register.
4039 bool
4040 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding)
4041 {
4042 #if 0
4043     if ConditionPassed() then
4044         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4045         address = R[n];
4046 
4047         for i = 0 to 14
4048             if registers<i> == '1' then
4049                 if i == n && wback && i != LowestSetBit(registers) then
4050                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4051                 else
4052                     MemA[address,4] = R[i];
4053                 address = address + 4;
4054 
4055         if registers<15> == '1' then // Only possible for encoding A1
4056             MemA[address,4] = PCStoreValue();
4057         if wback then R[n] = R[n] + 4*BitCount(registers);
4058 #endif
4059 
4060     bool success = false;
4061 
4062     if (ConditionPassed(opcode))
4063     {
4064         uint32_t n;
4065         uint32_t registers = 0;
4066         bool wback;
4067         const uint32_t addr_byte_size = GetAddressByteSize();
4068 
4069         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4070         switch (encoding)
4071         {
4072             case eEncodingT1:
4073                 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4074                 n = Bits32 (opcode, 10, 8);
4075                 registers = Bits32 (opcode, 7, 0);
4076                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
4077                 wback = true;
4078 
4079                 // if BitCount(registers) < 1 then UNPREDICTABLE;
4080                 if (BitCount (registers) < 1)
4081                     return false;
4082 
4083                 break;
4084 
4085             case eEncodingT2:
4086                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4087                 n = Bits32 (opcode, 19, 16);
4088                 registers = Bits32 (opcode, 15, 0);
4089                 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4090                 wback = BitIsSet (opcode, 21);
4091 
4092                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4093                 if ((n == 15) || (BitCount (registers) < 2))
4094                     return false;
4095 
4096                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4097                 if (wback && BitIsSet (registers, n))
4098                     return false;
4099 
4100                 break;
4101 
4102             case eEncodingA1:
4103                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4104                 n = Bits32 (opcode, 19, 16);
4105                 registers = Bits32 (opcode, 15, 0);
4106                 wback = BitIsSet (opcode, 21);
4107 
4108                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4109                 if ((n == 15) || (BitCount (registers) < 1))
4110                     return false;
4111 
4112                 break;
4113 
4114             default:
4115                 return false;
4116         }
4117 
4118         // address = R[n];
4119         int32_t offset = 0;
4120         const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4121         if (!success)
4122             return false;
4123 
4124         EmulateInstruction::Context context;
4125         context.type = EmulateInstruction::eContextRegisterStore;
4126         RegisterInfo base_reg;
4127         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4128 
4129         // for i = 0 to 14
4130         uint32_t lowest_set_bit = 14;
4131         for (uint32_t i = 0; i < 14; ++i)
4132         {
4133             // if registers<i> == '1' then
4134             if (BitIsSet (registers, i))
4135             {
4136                   if (i < lowest_set_bit)
4137                       lowest_set_bit = i;
4138                   // if i == n && wback && i != LowestSetBit(registers) then
4139                   if ((i == n) && wback && (i != lowest_set_bit))
4140                       // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4141                       WriteBits32UnknownToMemory (address + offset);
4142                   else
4143                   {
4144                      // MemA[address,4] = R[i];
4145                       uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4146                       if (!success)
4147                           return false;
4148 
4149                       RegisterInfo data_reg;
4150                       GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4151                       context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4152                       if (!MemAWrite (context, address + offset, data, addr_byte_size))
4153                           return false;
4154                   }
4155 
4156                   // address = address + 4;
4157                   offset += addr_byte_size;
4158             }
4159         }
4160 
4161         // if registers<15> == '1' then // Only possible for encoding A1
4162         //     MemA[address,4] = PCStoreValue();
4163         if (BitIsSet (registers, 15))
4164         {
4165             RegisterInfo pc_reg;
4166             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4167             context.SetRegisterPlusOffset (pc_reg, 8);
4168             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4169             if (!success)
4170                 return false;
4171 
4172             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4173                 return false;
4174         }
4175 
4176         // if wback then R[n] = R[n] + 4*BitCount(registers);
4177         if (wback)
4178         {
4179             offset = addr_byte_size * BitCount (registers);
4180             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4181             context.SetImmediateSigned (offset);
4182             addr_t data = address + offset;
4183             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4184                 return false;
4185         }
4186     }
4187     return true;
4188 }
4189 
4190 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
4191 // from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
4192 // of those locations can optionally be written back to the base register.
4193 bool
4194 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding)
4195 {
4196 #if 0
4197     if ConditionPassed() then
4198         EncodingSpecificOperations();
4199         address = R[n] - 4*BitCount(registers) + 4;
4200 
4201         for i = 0 to 14
4202             if registers<i> == '1' then
4203                 if i == n && wback && i != LowestSetBit(registers) then
4204                     MemA[address,4] = bits(32) UNKNOWN;
4205                 else
4206                     MemA[address,4] = R[i];
4207                 address = address + 4;
4208 
4209         if registers<15> == '1' then
4210             MemA[address,4] = PCStoreValue();
4211 
4212         if wback then R[n] = R[n] - 4*BitCount(registers);
4213 #endif
4214 
4215     bool success = false;
4216 
4217     if (ConditionPassed(opcode))
4218     {
4219         uint32_t n;
4220         uint32_t registers = 0;
4221         bool wback;
4222         const uint32_t addr_byte_size = GetAddressByteSize();
4223 
4224         // EncodingSpecificOperations();
4225         switch (encoding)
4226         {
4227             case eEncodingA1:
4228                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4229                 n = Bits32 (opcode, 19, 16);
4230                 registers = Bits32 (opcode, 15, 0);
4231                 wback = BitIsSet (opcode, 21);
4232 
4233                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4234                 if ((n == 15) || (BitCount (registers) < 1))
4235                     return false;
4236                 break;
4237             default:
4238                 return false;
4239         }
4240 
4241         // address = R[n] - 4*BitCount(registers) + 4;
4242         int32_t offset = 0;
4243         addr_t Rn = ReadCoreReg (n, &success);
4244         if (!success)
4245             return false;
4246 
4247         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4;
4248 
4249         EmulateInstruction::Context context;
4250         context.type = EmulateInstruction::eContextRegisterStore;
4251         RegisterInfo base_reg;
4252         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4253 
4254         // for i = 0 to 14
4255         uint32_t lowest_bit_set = 14;
4256         for (uint32_t i = 0; i < 14; ++i)
4257         {
4258             // if registers<i> == '1' then
4259             if (BitIsSet (registers, i))
4260             {
4261                 if (i < lowest_bit_set)
4262                     lowest_bit_set = i;
4263                 //if i == n && wback && i != LowestSetBit(registers) then
4264                 if ((i == n) && wback && (i != lowest_bit_set))
4265                     // MemA[address,4] = bits(32) UNKNOWN;
4266                     WriteBits32UnknownToMemory (address + offset);
4267                 else
4268                 {
4269                     // MemA[address,4] = R[i];
4270                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4271                     if (!success)
4272                         return false;
4273 
4274                     RegisterInfo data_reg;
4275                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4276                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4277                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4278                         return false;
4279                 }
4280 
4281                 // address = address + 4;
4282                 offset += addr_byte_size;
4283             }
4284         }
4285 
4286         // if registers<15> == '1' then
4287         //    MemA[address,4] = PCStoreValue();
4288         if (BitIsSet (registers, 15))
4289         {
4290             RegisterInfo pc_reg;
4291             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4292             context.SetRegisterPlusOffset (pc_reg, 8);
4293             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4294             if (!success)
4295                 return false;
4296 
4297             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4298                 return false;
4299         }
4300 
4301         // if wback then R[n] = R[n] - 4*BitCount(registers);
4302         if (wback)
4303         {
4304             offset = (addr_byte_size * BitCount (registers)) * -1;
4305             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4306             context.SetImmediateSigned (offset);
4307             addr_t data = Rn + offset;
4308             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4309                 return false;
4310         }
4311     }
4312     return true;
4313 }
4314 
4315 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
4316 // from a base register.  The consecutive memory locations end just below this address, and the address of the first of
4317 // those locations can optionally be written back to the base register.
4318 bool
4319 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding)
4320 {
4321 #if 0
4322     if ConditionPassed() then
4323         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4324         address = R[n] - 4*BitCount(registers);
4325 
4326         for i = 0 to 14
4327             if registers<i> == '1' then
4328                 if i == n && wback && i != LowestSetBit(registers) then
4329                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4330                 else
4331                     MemA[address,4] = R[i];
4332                 address = address + 4;
4333 
4334         if registers<15> == '1' then // Only possible for encoding A1
4335             MemA[address,4] = PCStoreValue();
4336 
4337         if wback then R[n] = R[n] - 4*BitCount(registers);
4338 #endif
4339 
4340 
4341     bool success = false;
4342 
4343     if (ConditionPassed(opcode))
4344     {
4345         uint32_t n;
4346         uint32_t registers = 0;
4347         bool wback;
4348         const uint32_t addr_byte_size = GetAddressByteSize();
4349 
4350         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4351         switch (encoding)
4352         {
4353             case eEncodingT1:
4354                 // if W == '1' && Rn == '1101' then SEE PUSH;
4355                 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
4356                 {
4357                     // See PUSH
4358                 }
4359                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4360                 n = Bits32 (opcode, 19, 16);
4361                 registers = Bits32 (opcode, 15, 0);
4362                 registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
4363                 wback = BitIsSet (opcode, 21);
4364                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4365                 if ((n == 15) || BitCount (registers) < 2)
4366                     return false;
4367                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4368                 if (wback && BitIsSet (registers, n))
4369                     return false;
4370                 break;
4371 
4372             case eEncodingA1:
4373                 // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH;
4374                 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
4375                 {
4376                     // See Push
4377                 }
4378                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4379                 n = Bits32 (opcode, 19, 16);
4380                 registers = Bits32 (opcode, 15, 0);
4381                 wback = BitIsSet (opcode, 21);
4382                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4383                 if ((n == 15) || BitCount (registers) < 1)
4384                     return false;
4385                 break;
4386 
4387             default:
4388                 return false;
4389         }
4390 
4391         // address = R[n] - 4*BitCount(registers);
4392 
4393         int32_t offset = 0;
4394         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4395         if (!success)
4396         return false;
4397 
4398         addr_t address = Rn - (addr_byte_size * BitCount (registers));
4399 
4400         EmulateInstruction::Context context;
4401         context.type = EmulateInstruction::eContextRegisterStore;
4402         RegisterInfo base_reg;
4403         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4404 
4405         // for i = 0 to 14
4406         uint32_t lowest_set_bit = 14;
4407         for (uint32_t i = 0; i < 14; ++i)
4408         {
4409             // if registers<i> == '1' then
4410             if (BitIsSet (registers, i))
4411             {
4412                 if (i < lowest_set_bit)
4413                     lowest_set_bit = i;
4414                 // if i == n && wback && i != LowestSetBit(registers) then
4415                 if ((i == n) && wback && (i != lowest_set_bit))
4416                     // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4417                     WriteBits32UnknownToMemory (address + offset);
4418                 else
4419                 {
4420                     // MemA[address,4] = R[i];
4421                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4422                     if (!success)
4423                         return false;
4424 
4425                     RegisterInfo data_reg;
4426                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4427                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4428                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4429                         return false;
4430                 }
4431 
4432                 // address = address + 4;
4433                 offset += addr_byte_size;
4434             }
4435         }
4436 
4437         // if registers<15> == '1' then // Only possible for encoding A1
4438         //     MemA[address,4] = PCStoreValue();
4439         if (BitIsSet (registers, 15))
4440         {
4441             RegisterInfo pc_reg;
4442             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4443             context.SetRegisterPlusOffset (pc_reg, 8);
4444             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4445             if (!success)
4446                 return false;
4447 
4448             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4449                 return false;
4450         }
4451 
4452         // if wback then R[n] = R[n] - 4*BitCount(registers);
4453         if (wback)
4454         {
4455             offset = (addr_byte_size * BitCount (registers)) * -1;
4456             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4457             context.SetImmediateSigned (offset);
4458             addr_t data = Rn + offset;
4459             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4460                 return false;
4461         }
4462     }
4463     return true;
4464 }
4465 
4466 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
4467 // from a base register.  The consecutive memory locations start just above this address, and the address of the last
4468 // of those locations can optionally be written back to the base register.
4469 bool
4470 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding)
4471 {
4472 #if 0
4473     if ConditionPassed() then
4474         EncodingSpecificOperations();
4475         address = R[n] + 4;
4476 
4477         for i = 0 to 14
4478             if registers<i> == '1' then
4479                 if i == n && wback && i != LowestSetBit(registers) then
4480                     MemA[address,4] = bits(32) UNKNOWN;
4481                 else
4482                     MemA[address,4] = R[i];
4483                 address = address + 4;
4484 
4485         if registers<15> == '1' then
4486             MemA[address,4] = PCStoreValue();
4487 
4488         if wback then R[n] = R[n] + 4*BitCount(registers);
4489 #endif
4490 
4491     bool success = false;
4492 
4493     if (ConditionPassed(opcode))
4494     {
4495         uint32_t n;
4496         uint32_t registers = 0;
4497         bool wback;
4498         const uint32_t addr_byte_size = GetAddressByteSize();
4499 
4500         // EncodingSpecificOperations();
4501         switch (encoding)
4502         {
4503             case eEncodingA1:
4504                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4505                 n = Bits32 (opcode, 19, 16);
4506                 registers = Bits32 (opcode, 15, 0);
4507                 wback = BitIsSet (opcode, 21);
4508 
4509                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4510                 if ((n == 15) && (BitCount (registers) < 1))
4511                     return false;
4512                 break;
4513             default:
4514                 return false;
4515         }
4516         // address = R[n] + 4;
4517 
4518         int32_t offset = 0;
4519         addr_t Rn = ReadCoreReg (n, &success);
4520         if (!success)
4521             return false;
4522 
4523         addr_t address = Rn + addr_byte_size;
4524 
4525         EmulateInstruction::Context context;
4526         context.type = EmulateInstruction::eContextRegisterStore;
4527         RegisterInfo base_reg;
4528         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4529 
4530         uint32_t lowest_set_bit = 14;
4531         // for i = 0 to 14
4532         for (uint32_t i = 0; i < 14; ++i)
4533         {
4534             // if registers<i> == '1' then
4535             if (BitIsSet (registers, i))
4536             {
4537                 if (i < lowest_set_bit)
4538                     lowest_set_bit = i;
4539                 // if i == n && wback && i != LowestSetBit(registers) then
4540                 if ((i == n) && wback && (i != lowest_set_bit))
4541                     // MemA[address,4] = bits(32) UNKNOWN;
4542                     WriteBits32UnknownToMemory (address + offset);
4543                 // else
4544                 else
4545                 {
4546                     // MemA[address,4] = R[i];
4547                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4548                     if (!success)
4549                         return false;
4550 
4551                     RegisterInfo data_reg;
4552                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4553                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size);
4554                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4555                         return false;
4556                 }
4557 
4558                 // address = address + 4;
4559                 offset += addr_byte_size;
4560             }
4561         }
4562 
4563         // if registers<15> == '1' then
4564             // MemA[address,4] = PCStoreValue();
4565         if (BitIsSet (registers, 15))
4566         {
4567             RegisterInfo pc_reg;
4568             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4569             context.SetRegisterPlusOffset (pc_reg, 8);
4570             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4571             if (!success)
4572             return false;
4573 
4574             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4575                 return false;
4576         }
4577 
4578         // if wback then R[n] = R[n] + 4*BitCount(registers);
4579         if (wback)
4580         {
4581             offset = addr_byte_size * BitCount (registers);
4582             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4583             context.SetImmediateSigned (offset);
4584             addr_t data = Rn + offset;
4585             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4586                 return false;
4587         }
4588     }
4589     return true;
4590 }
4591 
4592 // STR (store immediate) calculates an address from a base register value and an immediate offset, and stores a word
4593 // from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
4594 bool
4595 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding)
4596 {
4597 #if 0
4598     if ConditionPassed() then
4599         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4600         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4601         address = if index then offset_addr else R[n];
4602         if UnalignedSupport() || address<1:0> == '00' then
4603             MemU[address,4] = R[t];
4604         else // Can only occur before ARMv7
4605             MemU[address,4] = bits(32) UNKNOWN;
4606         if wback then R[n] = offset_addr;
4607 #endif
4608 
4609     bool success = false;
4610 
4611     if (ConditionPassed(opcode))
4612     {
4613         const uint32_t addr_byte_size = GetAddressByteSize();
4614 
4615         uint32_t t;
4616         uint32_t n;
4617         uint32_t imm32;
4618         bool index;
4619         bool add;
4620         bool wback;
4621         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4622         switch (encoding)
4623         {
4624             case eEncodingT1:
4625                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
4626                 t = Bits32 (opcode, 2, 0);
4627                 n = Bits32 (opcode, 5, 3);
4628                 imm32 = Bits32 (opcode, 10, 6) << 2;
4629 
4630                 // index = TRUE; add = TRUE; wback = FALSE;
4631                 index = true;
4632                 add = false;
4633                 wback = false;
4634                 break;
4635 
4636             case eEncodingT2:
4637                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4638                 t = Bits32 (opcode, 10, 8);
4639                 n = 13;
4640                 imm32 = Bits32 (opcode, 7, 0) << 2;
4641 
4642                 // index = TRUE; add = TRUE; wback = FALSE;
4643                 index = true;
4644                 add = true;
4645                 wback = false;
4646                 break;
4647 
4648             case eEncodingT3:
4649                 // if Rn == '1111' then UNDEFINED;
4650                 if (Bits32 (opcode, 19, 16) == 15)
4651                     return false;
4652 
4653                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4654                 t = Bits32 (opcode, 15, 12);
4655                 n = Bits32 (opcode, 19, 16);
4656                 imm32 = Bits32 (opcode, 11, 0);
4657 
4658                 // index = TRUE; add = TRUE; wback = FALSE;
4659                 index = true;
4660                 add = true;
4661                 wback = false;
4662 
4663                 // if t == 15 then UNPREDICTABLE;
4664                 if (t == 15)
4665                     return false;
4666                 break;
4667 
4668             case eEncodingT4:
4669                 // if P == '1' && U == '1' && W == '0' then SEE STRT;
4670                 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH;
4671                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4672                 if ((Bits32 (opcode, 19, 16) == 15)
4673                       || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
4674                     return false;
4675 
4676                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4677                 t = Bits32 (opcode, 15, 12);
4678                 n = Bits32 (opcode, 19, 16);
4679                 imm32 = Bits32 (opcode, 7, 0);
4680 
4681                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4682                 index = BitIsSet (opcode, 10);
4683                 add = BitIsSet (opcode, 9);
4684                 wback = BitIsSet (opcode, 8);
4685 
4686                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
4687                 if ((t == 15) || (wback && (n == t)))
4688                     return false;
4689                 break;
4690 
4691             default:
4692                 return false;
4693         }
4694 
4695         addr_t offset_addr;
4696         addr_t address;
4697 
4698         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4699         uint32_t base_address = ReadCoreReg (n, &success);
4700         if (!success)
4701             return false;
4702 
4703         if (add)
4704             offset_addr = base_address + imm32;
4705         else
4706             offset_addr = base_address - imm32;
4707 
4708         // address = if index then offset_addr else R[n];
4709         if (index)
4710             address = offset_addr;
4711         else
4712             address = base_address;
4713 
4714         EmulateInstruction::Context context;
4715         context.type = eContextRegisterStore;
4716         RegisterInfo base_reg;
4717         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4718 
4719         // if UnalignedSupport() || address<1:0> == '00' then
4720         if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
4721         {
4722             // MemU[address,4] = R[t];
4723             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4724             if (!success)
4725                 return false;
4726 
4727             RegisterInfo data_reg;
4728             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4729             int32_t offset = address - base_address;
4730             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4731             if (!MemUWrite (context, address, data, addr_byte_size))
4732                 return false;
4733         }
4734         else
4735         {
4736             // MemU[address,4] = bits(32) UNKNOWN;
4737             WriteBits32UnknownToMemory (address);
4738         }
4739 
4740         // if wback then R[n] = offset_addr;
4741         if (wback)
4742         {
4743             context.type = eContextRegisterLoad;
4744             context.SetAddress (offset_addr);
4745             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4746                 return false;
4747         }
4748     }
4749     return true;
4750 }
4751 
4752 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a
4753 // word from a register to memory.   The offset register value can optionally be shifted.
4754 bool
4755 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding)
4756 {
4757 #if 0
4758     if ConditionPassed() then
4759         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4760         offset = Shift(R[m], shift_t, shift_n, APSR.C);
4761         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4762         address = if index then offset_addr else R[n];
4763         if t == 15 then // Only possible for encoding A1
4764             data = PCStoreValue();
4765         else
4766             data = R[t];
4767         if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4768             MemU[address,4] = data;
4769         else // Can only occur before ARMv7
4770             MemU[address,4] = bits(32) UNKNOWN;
4771         if wback then R[n] = offset_addr;
4772 #endif
4773 
4774     bool success = false;
4775 
4776     if (ConditionPassed(opcode))
4777     {
4778         const uint32_t addr_byte_size = GetAddressByteSize();
4779 
4780         uint32_t t;
4781         uint32_t n;
4782         uint32_t m;
4783         ARM_ShifterType shift_t;
4784         uint32_t shift_n;
4785         bool index;
4786         bool add;
4787         bool wback;
4788 
4789         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4790         switch (encoding)
4791         {
4792             case eEncodingT1:
4793                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4794                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4795                 t = Bits32 (opcode, 2, 0);
4796                 n = Bits32 (opcode, 5, 3);
4797                 m = Bits32 (opcode, 8, 6);
4798 
4799                 // index = TRUE; add = TRUE; wback = FALSE;
4800                 index = true;
4801                 add = true;
4802                 wback = false;
4803 
4804                 // (shift_t, shift_n) = (SRType_LSL, 0);
4805                 shift_t = SRType_LSL;
4806                 shift_n = 0;
4807                 break;
4808 
4809             case eEncodingT2:
4810                 // if Rn == '1111' then UNDEFINED;
4811                 if (Bits32 (opcode, 19, 16) == 15)
4812                     return false;
4813 
4814                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4815                 t = Bits32 (opcode, 15, 12);
4816                 n = Bits32 (opcode, 19, 16);
4817                 m = Bits32 (opcode, 3, 0);
4818 
4819                 // index = TRUE; add = TRUE; wback = FALSE;
4820                 index = true;
4821                 add = true;
4822                 wback = false;
4823 
4824                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4825                 shift_t = SRType_LSL;
4826                 shift_n = Bits32 (opcode, 5, 4);
4827 
4828                 // if t == 15 || BadReg(m) then UNPREDICTABLE;
4829                 if ((t == 15) || (BadReg (m)))
4830                     return false;
4831                 break;
4832 
4833             case eEncodingA1:
4834             {
4835                 // if P == '0' && W == '1' then SEE STRT;
4836                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4837                 t = Bits32 (opcode, 15, 12);
4838                 n = Bits32 (opcode, 19, 16);
4839                 m = Bits32 (opcode, 3, 0);
4840 
4841                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
4842                 index = BitIsSet (opcode, 24);
4843                 add = BitIsSet (opcode, 23);
4844                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
4845 
4846                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
4847                 uint32_t typ = Bits32 (opcode, 6, 5);
4848                 uint32_t imm5 = Bits32 (opcode, 11, 7);
4849                 shift_n = DecodeImmShift(typ, imm5, shift_t);
4850 
4851                 // if m == 15 then UNPREDICTABLE;
4852                 if (m == 15)
4853                     return false;
4854 
4855                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
4856                 if (wback && ((n == 15) || (n == t)))
4857                     return false;
4858 
4859                 break;
4860             }
4861             default:
4862                 return false;
4863         }
4864 
4865         addr_t offset_addr;
4866         addr_t address;
4867         int32_t offset = 0;
4868 
4869         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4870         if (!success)
4871             return false;
4872 
4873         uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
4874         if (!success)
4875             return false;
4876 
4877         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4878         offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success);
4879         if (!success)
4880             return false;
4881 
4882         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4883         if (add)
4884             offset_addr = base_address + offset;
4885         else
4886             offset_addr = base_address - offset;
4887 
4888         // address = if index then offset_addr else R[n];
4889         if (index)
4890             address = offset_addr;
4891         else
4892             address = base_address;
4893 
4894         uint32_t data;
4895         // if t == 15 then // Only possible for encoding A1
4896         if (t == 15)
4897             // data = PCStoreValue();
4898             data = ReadCoreReg (PC_REG, &success);
4899         else
4900             // data = R[t];
4901             data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4902 
4903         if (!success)
4904             return false;
4905 
4906         EmulateInstruction::Context context;
4907         context.type = eContextRegisterStore;
4908 
4909         // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4910         if (UnalignedSupport ()
4911             || (BitIsClear (address, 1) && BitIsClear (address, 0))
4912             || CurrentInstrSet() == eModeARM)
4913         {
4914             // MemU[address,4] = data;
4915 
4916             RegisterInfo base_reg;
4917             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 +  n, base_reg);
4918 
4919             RegisterInfo data_reg;
4920             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4921 
4922             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4923             if (!MemUWrite (context, address, data, addr_byte_size))
4924                 return false;
4925 
4926         }
4927         else
4928             // MemU[address,4] = bits(32) UNKNOWN;
4929             WriteBits32UnknownToMemory (address);
4930 
4931         // if wback then R[n] = offset_addr;
4932         if (wback)
4933         {
4934             context.type = eContextRegisterLoad;
4935             context.SetAddress (offset_addr);
4936             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4937                 return false;
4938         }
4939 
4940     }
4941     return true;
4942 }
4943 
4944 bool
4945 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding)
4946 {
4947 #if 0
4948     if ConditionPassed() then
4949         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4950         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4951         address = if index then offset_addr else R[n];
4952         MemU[address,1] = R[t]<7:0>;
4953         if wback then R[n] = offset_addr;
4954 #endif
4955 
4956 
4957     bool success = false;
4958 
4959     if (ConditionPassed(opcode))
4960     {
4961         uint32_t t;
4962         uint32_t n;
4963         uint32_t imm32;
4964         bool index;
4965         bool add;
4966         bool wback;
4967         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4968         switch (encoding)
4969         {
4970             case eEncodingT1:
4971                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
4972                 t = Bits32 (opcode, 2, 0);
4973                 n = Bits32 (opcode, 5, 3);
4974                 imm32 = Bits32 (opcode, 10, 6);
4975 
4976                 // index = TRUE; add = TRUE; wback = FALSE;
4977                 index = true;
4978                 add = true;
4979                 wback = false;
4980                 break;
4981 
4982             case eEncodingT2:
4983                 // if Rn == '1111' then UNDEFINED;
4984                 if (Bits32 (opcode, 19, 16) == 15)
4985                     return false;
4986 
4987                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4988                 t = Bits32 (opcode, 15, 12);
4989                 n = Bits32 (opcode, 19, 16);
4990                 imm32 = Bits32 (opcode, 11, 0);
4991 
4992                 // index = TRUE; add = TRUE; wback = FALSE;
4993                 index = true;
4994                 add = true;
4995                 wback = false;
4996 
4997                 // if BadReg(t) then UNPREDICTABLE;
4998                 if (BadReg (t))
4999                     return false;
5000                 break;
5001 
5002             case eEncodingT3:
5003                 // if P == '1' && U == '1' && W == '0' then SEE STRBT;
5004                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5005                 if (Bits32 (opcode, 19, 16) == 15)
5006                     return false;
5007 
5008                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5009                 t = Bits32 (opcode, 15, 12);
5010                 n = Bits32 (opcode, 19, 16);
5011                 imm32 = Bits32 (opcode, 7, 0);
5012 
5013                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5014                 index = BitIsSet (opcode, 10);
5015                 add = BitIsSet (opcode, 9);
5016                 wback = BitIsSet (opcode, 8);
5017 
5018                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
5019                 if ((BadReg (t)) || (wback && (n == t)))
5020                     return false;
5021                 break;
5022 
5023             default:
5024                 return false;
5025         }
5026 
5027         addr_t offset_addr;
5028         addr_t address;
5029         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5030         if (!success)
5031             return false;
5032 
5033         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5034         if (add)
5035             offset_addr = base_address + imm32;
5036         else
5037             offset_addr = base_address - imm32;
5038 
5039         // address = if index then offset_addr else R[n];
5040         if (index)
5041             address = offset_addr;
5042         else
5043             address = base_address;
5044 
5045         // MemU[address,1] = R[t]<7:0>
5046         RegisterInfo base_reg;
5047         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5048 
5049         RegisterInfo data_reg;
5050         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5051 
5052         EmulateInstruction::Context context;
5053         context.type = eContextRegisterStore;
5054         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
5055 
5056         uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5057         if (!success)
5058             return false;
5059 
5060         data = Bits32 (data, 7, 0);
5061 
5062         if (!MemUWrite (context, address, data, 1))
5063             return false;
5064 
5065         // if wback then R[n] = offset_addr;
5066         if (wback)
5067         {
5068             context.type = eContextRegisterLoad;
5069             context.SetAddress (offset_addr);
5070             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5071                 return false;
5072         }
5073 
5074     }
5075 
5076     return true;
5077 }
5078 
5079 // STRH (register) calculates an address from a base register value and an offset register value, and stores a
5080 // halfword from a register to memory.  The offset register value can be shifted left by 0, 1, 2, or 3 bits.
5081 bool
5082 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding)
5083 {
5084 #if 0
5085     if ConditionPassed() then
5086         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5087         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5088         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5089         address = if index then offset_addr else R[n];
5090         if UnalignedSupport() || address<0> == '0' then
5091             MemU[address,2] = R[t]<15:0>;
5092         else // Can only occur before ARMv7
5093             MemU[address,2] = bits(16) UNKNOWN;
5094         if wback then R[n] = offset_addr;
5095 #endif
5096 
5097     bool success = false;
5098 
5099     if (ConditionPassed(opcode))
5100     {
5101         uint32_t t;
5102         uint32_t n;
5103         uint32_t m;
5104         bool index;
5105         bool add;
5106         bool wback;
5107         ARM_ShifterType shift_t;
5108         uint32_t shift_n;
5109 
5110         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5111         switch (encoding)
5112         {
5113             case eEncodingT1:
5114                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5115                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5116                 t = Bits32 (opcode, 2, 0);
5117                 n = Bits32 (opcode, 5, 3);
5118                 m = Bits32 (opcode, 8, 6);
5119 
5120                 // index = TRUE; add = TRUE; wback = FALSE;
5121                 index = true;
5122                 add = true;
5123                 wback = false;
5124 
5125                 // (shift_t, shift_n) = (SRType_LSL, 0);
5126                 shift_t = SRType_LSL;
5127                 shift_n = 0;
5128 
5129                 break;
5130 
5131             case eEncodingT2:
5132                 // if Rn == '1111' then UNDEFINED;
5133                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5134                 t = Bits32 (opcode, 15, 12);
5135                 n = Bits32 (opcode, 19, 16);
5136                 m = Bits32 (opcode, 3, 0);
5137                 if (n == 15)
5138                     return false;
5139 
5140                 // index = TRUE; add = TRUE; wback = FALSE;
5141                 index = true;
5142                 add = true;
5143                 wback = false;
5144 
5145                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5146                 shift_t = SRType_LSL;
5147                 shift_n = Bits32 (opcode, 5, 4);
5148 
5149                 // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5150                 if (BadReg (t) || BadReg (m))
5151                     return false;
5152 
5153                 break;
5154 
5155             case eEncodingA1:
5156                 // if P == '0' && W == '1' then SEE STRHT;
5157                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5158                 t = Bits32 (opcode, 15, 12);
5159                 n = Bits32 (opcode, 19, 16);
5160                 m = Bits32 (opcode, 3, 0);
5161 
5162                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5163                 index = BitIsSet (opcode, 24);
5164                 add = BitIsSet (opcode, 23);
5165                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5166 
5167                 // (shift_t, shift_n) = (SRType_LSL, 0);
5168                 shift_t = SRType_LSL;
5169                 shift_n = 0;
5170 
5171                 // if t == 15 || m == 15 then UNPREDICTABLE;
5172                 if ((t == 15) || (m == 15))
5173                     return false;
5174 
5175                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5176                 if (wback && ((n == 15) || (n == t)))
5177                     return false;
5178 
5179                 break;
5180 
5181             default:
5182                 return false;
5183         }
5184 
5185         uint32_t Rm = ReadCoreReg (m, &success);
5186         if (!success)
5187             return false;
5188 
5189         uint32_t Rn = ReadCoreReg (n, &success);
5190         if (!success)
5191             return false;
5192 
5193         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5194         uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
5195         if (!success)
5196             return false;
5197 
5198         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5199         addr_t offset_addr;
5200         if (add)
5201             offset_addr = Rn + offset;
5202         else
5203             offset_addr = Rn - offset;
5204 
5205         // address = if index then offset_addr else R[n];
5206         addr_t address;
5207         if (index)
5208             address = offset_addr;
5209         else
5210             address = Rn;
5211 
5212         EmulateInstruction::Context context;
5213         context.type = eContextRegisterStore;
5214         RegisterInfo base_reg;
5215         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5216         RegisterInfo offset_reg;
5217         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5218 
5219         // if UnalignedSupport() || address<0> == '0' then
5220         if (UnalignedSupport() || BitIsClear (address, 0))
5221         {
5222             // MemU[address,2] = R[t]<15:0>;
5223             uint32_t Rt = ReadCoreReg (t, &success);
5224             if (!success)
5225                 return false;
5226 
5227             EmulateInstruction::Context context;
5228             context.type = eContextRegisterStore;
5229             RegisterInfo base_reg;
5230             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5231             RegisterInfo offset_reg;
5232             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5233             RegisterInfo data_reg;
5234             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5235             context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
5236 
5237             if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2))
5238                 return false;
5239         }
5240         else // Can only occur before ARMv7
5241         {
5242             // MemU[address,2] = bits(16) UNKNOWN;
5243         }
5244 
5245         // if wback then R[n] = offset_addr;
5246         if (wback)
5247         {
5248             context.type = eContextAdjustBaseRegister;
5249             context.SetAddress (offset_addr);
5250             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5251                 return false;
5252         }
5253     }
5254 
5255     return true;
5256 }
5257 
5258 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value,
5259 // and writes the result to the destination register.  It can optionally update the condition flags
5260 // based on the result.
5261 bool
5262 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding)
5263 {
5264 #if 0
5265     // ARM pseudo code...
5266     if ConditionPassed() then
5267         EncodingSpecificOperations();
5268         (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5269         if d == 15 then         // Can only occur for ARM encoding
5270             ALUWritePC(result); // setflags is always FALSE here
5271         else
5272             R[d] = result;
5273             if setflags then
5274                 APSR.N = result<31>;
5275                 APSR.Z = IsZeroBit(result);
5276                 APSR.C = carry;
5277                 APSR.V = overflow;
5278 #endif
5279 
5280     bool success = false;
5281 
5282     if (ConditionPassed(opcode))
5283     {
5284         uint32_t Rd, Rn;
5285         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
5286         bool setflags;
5287         switch (encoding)
5288         {
5289         case eEncodingT1:
5290             Rd = Bits32(opcode, 11, 8);
5291             Rn = Bits32(opcode, 19, 16);
5292             setflags = BitIsSet(opcode, 20);
5293             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5294             if (BadReg(Rd) || BadReg(Rn))
5295                 return false;
5296             break;
5297         case eEncodingA1:
5298             Rd = Bits32(opcode, 15, 12);
5299             Rn = Bits32(opcode, 19, 16);
5300             setflags = BitIsSet(opcode, 20);
5301             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5302 
5303             if (Rd == 15 && setflags)
5304                 return EmulateSUBSPcLrEtc (opcode, encoding);
5305             break;
5306         default:
5307             return false;
5308         }
5309 
5310         // Read the first operand.
5311         int32_t val1 = ReadCoreReg(Rn, &success);
5312         if (!success)
5313             return false;
5314 
5315         AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5316 
5317         EmulateInstruction::Context context;
5318         context.type = EmulateInstruction::eContextImmediate;
5319         context.SetNoArgs ();
5320 
5321         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5322             return false;
5323     }
5324     return true;
5325 }
5326 
5327 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted
5328 // register value, and writes the result to the destination register.  It can optionally update the
5329 // condition flags based on the result.
5330 bool
5331 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding)
5332 {
5333 #if 0
5334     // ARM pseudo code...
5335     if ConditionPassed() then
5336         EncodingSpecificOperations();
5337         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5338         (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5339         if d == 15 then         // Can only occur for ARM encoding
5340             ALUWritePC(result); // setflags is always FALSE here
5341         else
5342             R[d] = result;
5343             if setflags then
5344                 APSR.N = result<31>;
5345                 APSR.Z = IsZeroBit(result);
5346                 APSR.C = carry;
5347                 APSR.V = overflow;
5348 #endif
5349 
5350     bool success = false;
5351 
5352     if (ConditionPassed(opcode))
5353     {
5354         uint32_t Rd, Rn, Rm;
5355         ARM_ShifterType shift_t;
5356         uint32_t shift_n; // the shift applied to the value read from Rm
5357         bool setflags;
5358         switch (encoding)
5359         {
5360         case eEncodingT1:
5361             Rd = Rn = Bits32(opcode, 2, 0);
5362             Rm = Bits32(opcode, 5, 3);
5363             setflags = !InITBlock();
5364             shift_t = SRType_LSL;
5365             shift_n = 0;
5366             break;
5367         case eEncodingT2:
5368             Rd = Bits32(opcode, 11, 8);
5369             Rn = Bits32(opcode, 19, 16);
5370             Rm = Bits32(opcode, 3, 0);
5371             setflags = BitIsSet(opcode, 20);
5372             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5373             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5374                 return false;
5375             break;
5376         case eEncodingA1:
5377             Rd = Bits32(opcode, 15, 12);
5378             Rn = Bits32(opcode, 19, 16);
5379             Rm = Bits32(opcode, 3, 0);
5380             setflags = BitIsSet(opcode, 20);
5381             shift_n = DecodeImmShiftARM(opcode, shift_t);
5382 
5383             if (Rd == 15 && setflags)
5384                 return EmulateSUBSPcLrEtc (opcode, encoding);
5385             break;
5386         default:
5387             return false;
5388         }
5389 
5390         // Read the first operand.
5391         int32_t val1 = ReadCoreReg(Rn, &success);
5392         if (!success)
5393             return false;
5394 
5395         // Read the second operand.
5396         int32_t val2 = ReadCoreReg(Rm, &success);
5397         if (!success)
5398             return false;
5399 
5400         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5401         if (!success)
5402             return false;
5403         AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5404 
5405         EmulateInstruction::Context context;
5406         context.type = EmulateInstruction::eContextImmediate;
5407         context.SetNoArgs ();
5408 
5409         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5410             return false;
5411     }
5412     return true;
5413 }
5414 
5415 // This instruction adds an immediate value to the PC value to form a PC-relative address,
5416 // and writes the result to the destination register.
5417 bool
5418 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding)
5419 {
5420 #if 0
5421     // ARM pseudo code...
5422     if ConditionPassed() then
5423         EncodingSpecificOperations();
5424         result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5425         if d == 15 then         // Can only occur for ARM encodings
5426             ALUWritePC(result);
5427         else
5428             R[d] = result;
5429 #endif
5430 
5431     bool success = false;
5432 
5433     if (ConditionPassed(opcode))
5434     {
5435         uint32_t Rd;
5436         uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5437         bool add;
5438         switch (encoding)
5439         {
5440         case eEncodingT1:
5441             Rd = Bits32(opcode, 10, 8);
5442             imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5443             add = true;
5444             break;
5445         case eEncodingT2:
5446         case eEncodingT3:
5447             Rd = Bits32(opcode, 11, 8);
5448             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5449             add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5450             if (BadReg(Rd))
5451                 return false;
5452             break;
5453         case eEncodingA1:
5454         case eEncodingA2:
5455             Rd = Bits32(opcode, 15, 12);
5456             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5457             add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5458             break;
5459         default:
5460             return false;
5461         }
5462 
5463         // Read the PC value.
5464         uint32_t pc = ReadCoreReg(PC_REG, &success);
5465         if (!success)
5466             return false;
5467 
5468         uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5469 
5470         EmulateInstruction::Context context;
5471         context.type = EmulateInstruction::eContextImmediate;
5472         context.SetNoArgs ();
5473 
5474         if (!WriteCoreReg(context, result, Rd))
5475             return false;
5476     }
5477     return true;
5478 }
5479 
5480 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result
5481 // to the destination register.  It can optionally update the condition flags based on the result.
5482 bool
5483 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding)
5484 {
5485 #if 0
5486     // ARM pseudo code...
5487     if ConditionPassed() then
5488         EncodingSpecificOperations();
5489         result = R[n] AND imm32;
5490         if d == 15 then         // Can only occur for ARM encoding
5491             ALUWritePC(result); // setflags is always FALSE here
5492         else
5493             R[d] = result;
5494             if setflags then
5495                 APSR.N = result<31>;
5496                 APSR.Z = IsZeroBit(result);
5497                 APSR.C = carry;
5498                 // APSR.V unchanged
5499 #endif
5500 
5501     bool success = false;
5502 
5503     if (ConditionPassed(opcode))
5504     {
5505         uint32_t Rd, Rn;
5506         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
5507         bool setflags;
5508         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5509         switch (encoding)
5510         {
5511         case eEncodingT1:
5512             Rd = Bits32(opcode, 11, 8);
5513             Rn = Bits32(opcode, 19, 16);
5514             setflags = BitIsSet(opcode, 20);
5515             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5516             // if Rd == '1111' && S == '1' then SEE TST (immediate);
5517             if (Rd == 15 && setflags)
5518                 return EmulateTSTImm(opcode, eEncodingT1);
5519             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
5520                 return false;
5521             break;
5522         case eEncodingA1:
5523             Rd = Bits32(opcode, 15, 12);
5524             Rn = Bits32(opcode, 19, 16);
5525             setflags = BitIsSet(opcode, 20);
5526             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5527 
5528             if (Rd == 15 && setflags)
5529                 return EmulateSUBSPcLrEtc (opcode, encoding);
5530             break;
5531         default:
5532             return false;
5533         }
5534 
5535         // Read the first operand.
5536         uint32_t val1 = ReadCoreReg(Rn, &success);
5537         if (!success)
5538             return false;
5539 
5540         uint32_t result = val1 & imm32;
5541 
5542         EmulateInstruction::Context context;
5543         context.type = EmulateInstruction::eContextImmediate;
5544         context.SetNoArgs ();
5545 
5546         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5547             return false;
5548     }
5549     return true;
5550 }
5551 
5552 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value,
5553 // and writes the result to the destination register.  It can optionally update the condition flags
5554 // based on the result.
5555 bool
5556 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding)
5557 {
5558 #if 0
5559     // ARM pseudo code...
5560     if ConditionPassed() then
5561         EncodingSpecificOperations();
5562         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5563         result = R[n] AND shifted;
5564         if d == 15 then         // Can only occur for ARM encoding
5565             ALUWritePC(result); // setflags is always FALSE here
5566         else
5567             R[d] = result;
5568             if setflags then
5569                 APSR.N = result<31>;
5570                 APSR.Z = IsZeroBit(result);
5571                 APSR.C = carry;
5572                 // APSR.V unchanged
5573 #endif
5574 
5575     bool success = false;
5576 
5577     if (ConditionPassed(opcode))
5578     {
5579         uint32_t Rd, Rn, Rm;
5580         ARM_ShifterType shift_t;
5581         uint32_t shift_n; // the shift applied to the value read from Rm
5582         bool setflags;
5583         uint32_t carry;
5584         switch (encoding)
5585         {
5586         case eEncodingT1:
5587             Rd = Rn = Bits32(opcode, 2, 0);
5588             Rm = Bits32(opcode, 5, 3);
5589             setflags = !InITBlock();
5590             shift_t = SRType_LSL;
5591             shift_n = 0;
5592             break;
5593         case eEncodingT2:
5594             Rd = Bits32(opcode, 11, 8);
5595             Rn = Bits32(opcode, 19, 16);
5596             Rm = Bits32(opcode, 3, 0);
5597             setflags = BitIsSet(opcode, 20);
5598             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5599             // if Rd == '1111' && S == '1' then SEE TST (register);
5600             if (Rd == 15 && setflags)
5601                 return EmulateTSTReg(opcode, eEncodingT2);
5602             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
5603                 return false;
5604             break;
5605         case eEncodingA1:
5606             Rd = Bits32(opcode, 15, 12);
5607             Rn = Bits32(opcode, 19, 16);
5608             Rm = Bits32(opcode, 3, 0);
5609             setflags = BitIsSet(opcode, 20);
5610             shift_n = DecodeImmShiftARM(opcode, shift_t);
5611 
5612             if (Rd == 15 && setflags)
5613                 return EmulateSUBSPcLrEtc (opcode, encoding);
5614             break;
5615         default:
5616             return false;
5617         }
5618 
5619         // Read the first operand.
5620         uint32_t val1 = ReadCoreReg(Rn, &success);
5621         if (!success)
5622             return false;
5623 
5624         // Read the second operand.
5625         uint32_t val2 = ReadCoreReg(Rm, &success);
5626         if (!success)
5627             return false;
5628 
5629         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5630         if (!success)
5631             return false;
5632         uint32_t result = val1 & shifted;
5633 
5634         EmulateInstruction::Context context;
5635         context.type = EmulateInstruction::eContextImmediate;
5636         context.SetNoArgs ();
5637 
5638         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5639             return false;
5640     }
5641     return true;
5642 }
5643 
5644 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an
5645 // immediate value, and writes the result to the destination register.  It can optionally update the
5646 // condition flags based on the result.
5647 bool
5648 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding)
5649 {
5650 #if 0
5651     // ARM pseudo code...
5652     if ConditionPassed() then
5653         EncodingSpecificOperations();
5654         result = R[n] AND NOT(imm32);
5655         if d == 15 then         // Can only occur for ARM encoding
5656             ALUWritePC(result); // setflags is always FALSE here
5657         else
5658             R[d] = result;
5659             if setflags then
5660                 APSR.N = result<31>;
5661                 APSR.Z = IsZeroBit(result);
5662                 APSR.C = carry;
5663                 // APSR.V unchanged
5664 #endif
5665 
5666     bool success = false;
5667 
5668     if (ConditionPassed(opcode))
5669     {
5670         uint32_t Rd, Rn;
5671         uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn
5672         bool setflags;
5673         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5674         switch (encoding)
5675         {
5676         case eEncodingT1:
5677             Rd = Bits32(opcode, 11, 8);
5678             Rn = Bits32(opcode, 19, 16);
5679             setflags = BitIsSet(opcode, 20);
5680             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5681             if (BadReg(Rd) || BadReg(Rn))
5682                 return false;
5683             break;
5684         case eEncodingA1:
5685             Rd = Bits32(opcode, 15, 12);
5686             Rn = Bits32(opcode, 19, 16);
5687             setflags = BitIsSet(opcode, 20);
5688             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5689 
5690             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5691             if (Rd == 15 && setflags)
5692                 return EmulateSUBSPcLrEtc (opcode, encoding);
5693             break;
5694         default:
5695             return false;
5696         }
5697 
5698         // Read the first operand.
5699         uint32_t val1 = ReadCoreReg(Rn, &success);
5700         if (!success)
5701             return false;
5702 
5703         uint32_t result = val1 & ~imm32;
5704 
5705         EmulateInstruction::Context context;
5706         context.type = EmulateInstruction::eContextImmediate;
5707         context.SetNoArgs ();
5708 
5709         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5710             return false;
5711     }
5712     return true;
5713 }
5714 
5715 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an
5716 // optionally-shifted register value, and writes the result to the destination register.
5717 // It can optionally update the condition flags based on the result.
5718 bool
5719 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding)
5720 {
5721 #if 0
5722     // ARM pseudo code...
5723     if ConditionPassed() then
5724         EncodingSpecificOperations();
5725         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5726         result = R[n] AND NOT(shifted);
5727         if d == 15 then         // Can only occur for ARM encoding
5728             ALUWritePC(result); // setflags is always FALSE here
5729         else
5730             R[d] = result;
5731             if setflags then
5732                 APSR.N = result<31>;
5733                 APSR.Z = IsZeroBit(result);
5734                 APSR.C = carry;
5735                 // APSR.V unchanged
5736 #endif
5737 
5738     bool success = false;
5739 
5740     if (ConditionPassed(opcode))
5741     {
5742         uint32_t Rd, Rn, Rm;
5743         ARM_ShifterType shift_t;
5744         uint32_t shift_n; // the shift applied to the value read from Rm
5745         bool setflags;
5746         uint32_t carry;
5747         switch (encoding)
5748         {
5749         case eEncodingT1:
5750             Rd = Rn = Bits32(opcode, 2, 0);
5751             Rm = Bits32(opcode, 5, 3);
5752             setflags = !InITBlock();
5753             shift_t = SRType_LSL;
5754             shift_n = 0;
5755             break;
5756         case eEncodingT2:
5757             Rd = Bits32(opcode, 11, 8);
5758             Rn = Bits32(opcode, 19, 16);
5759             Rm = Bits32(opcode, 3, 0);
5760             setflags = BitIsSet(opcode, 20);
5761             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5762             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5763                 return false;
5764             break;
5765         case eEncodingA1:
5766             Rd = Bits32(opcode, 15, 12);
5767             Rn = Bits32(opcode, 19, 16);
5768             Rm = Bits32(opcode, 3, 0);
5769             setflags = BitIsSet(opcode, 20);
5770             shift_n = DecodeImmShiftARM(opcode, shift_t);
5771 
5772             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5773             if (Rd == 15 && setflags)
5774                 return EmulateSUBSPcLrEtc (opcode, encoding);
5775             break;
5776         default:
5777             return false;
5778         }
5779 
5780         // Read the first operand.
5781         uint32_t val1 = ReadCoreReg(Rn, &success);
5782         if (!success)
5783             return false;
5784 
5785         // Read the second operand.
5786         uint32_t val2 = ReadCoreReg(Rm, &success);
5787         if (!success)
5788             return false;
5789 
5790         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5791         if (!success)
5792             return false;
5793         uint32_t result = val1 & ~shifted;
5794 
5795         EmulateInstruction::Context context;
5796         context.type = EmulateInstruction::eContextImmediate;
5797         context.SetNoArgs ();
5798 
5799         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5800             return false;
5801     }
5802     return true;
5803 }
5804 
5805 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
5806 // from memory, and writes it to a register.  It can use offset, post-indexed, or pre-indexed addressing.
5807 bool
5808 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding)
5809 {
5810 #if 0
5811     if ConditionPassed() then
5812         EncodingSpecificOperations();
5813         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5814         address = if index then offset_addr else R[n];
5815         data = MemU[address,4];
5816         if wback then R[n] = offset_addr;
5817         if t == 15 then
5818             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5819         elsif UnalignedSupport() || address<1:0> = '00' then
5820             R[t] = data;
5821         else // Can only apply before ARMv7
5822             R[t] = ROR(data, 8*UInt(address<1:0>));
5823 #endif
5824 
5825     bool success = false;
5826 
5827     if (ConditionPassed(opcode))
5828     {
5829         const uint32_t addr_byte_size = GetAddressByteSize();
5830 
5831         uint32_t t;
5832         uint32_t n;
5833         uint32_t imm32;
5834         bool index;
5835         bool add;
5836         bool wback;
5837 
5838         switch (encoding)
5839         {
5840             case eEncodingA1:
5841                 // if Rn == '1111' then SEE LDR (literal);
5842                 // if P == '0' && W == '1' then SEE LDRT;
5843                 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP;
5844                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5845                 t = Bits32 (opcode, 15, 12);
5846                 n = Bits32 (opcode, 19, 16);
5847                 imm32 = Bits32 (opcode, 11, 0);
5848 
5849                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5850                 index = BitIsSet (opcode, 24);
5851                 add = BitIsSet (opcode, 23);
5852                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5853 
5854                 // if wback && n == t then UNPREDICTABLE;
5855                 if (wback && (n == t))
5856                     return false;
5857 
5858                 break;
5859 
5860             default:
5861                 return false;
5862         }
5863 
5864         addr_t address;
5865         addr_t offset_addr;
5866         addr_t base_address = ReadCoreReg (n, &success);
5867         if (!success)
5868             return false;
5869 
5870         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5871         if (add)
5872             offset_addr = base_address + imm32;
5873         else
5874             offset_addr = base_address - imm32;
5875 
5876         // address = if index then offset_addr else R[n];
5877         if (index)
5878             address = offset_addr;
5879         else
5880             address = base_address;
5881 
5882         // data = MemU[address,4];
5883 
5884         RegisterInfo base_reg;
5885         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5886 
5887         EmulateInstruction::Context context;
5888         context.type = eContextRegisterLoad;
5889         context.SetRegisterPlusOffset (base_reg, address - base_address);
5890 
5891         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5892         if (!success)
5893             return false;
5894 
5895         // if wback then R[n] = offset_addr;
5896         if (wback)
5897         {
5898             context.type = eContextAdjustBaseRegister;
5899             context.SetAddress (offset_addr);
5900             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5901                 return false;
5902         }
5903 
5904         // if t == 15 then
5905         if (t == 15)
5906         {
5907             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5908             if (BitIsClear (address, 1) && BitIsClear (address, 0))
5909             {
5910                 // LoadWritePC (data);
5911                 context.type = eContextRegisterLoad;
5912                 context.SetRegisterPlusOffset (base_reg, address - base_address);
5913                 LoadWritePC (context, data);
5914             }
5915             else
5916                   return false;
5917         }
5918         // elsif UnalignedSupport() || address<1:0> = '00' then
5919         else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5920         {
5921             // R[t] = data;
5922             context.type = eContextRegisterLoad;
5923             context.SetRegisterPlusOffset (base_reg, address - base_address);
5924             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5925                 return false;
5926         }
5927         // else // Can only apply before ARMv7
5928         else
5929         {
5930             // R[t] = ROR(data, 8*UInt(address<1:0>));
5931             data = ROR (data, Bits32 (address, 1, 0), &success);
5932             if (!success)
5933                 return false;
5934             context.type = eContextRegisterLoad;
5935             context.SetImmediate (data);
5936             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5937                 return false;
5938         }
5939 
5940     }
5941     return true;
5942 }
5943 
5944 // LDR (register) calculates an address from a base register value and an offset register value, loads a word
5945 // from memory, and writes it to a register.  The offset register value can optionally be shifted.
5946 bool
5947 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding)
5948 {
5949 #if 0
5950     if ConditionPassed() then
5951         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5952         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5953         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5954         address = if index then offset_addr else R[n];
5955         data = MemU[address,4];
5956         if wback then R[n] = offset_addr;
5957         if t == 15 then
5958             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5959         elsif UnalignedSupport() || address<1:0> = '00' then
5960             R[t] = data;
5961         else // Can only apply before ARMv7
5962             if CurrentInstrSet() == InstrSet_ARM then
5963                 R[t] = ROR(data, 8*UInt(address<1:0>));
5964             else
5965                 R[t] = bits(32) UNKNOWN;
5966 #endif
5967 
5968     bool success = false;
5969 
5970     if (ConditionPassed(opcode))
5971     {
5972         const uint32_t addr_byte_size = GetAddressByteSize();
5973 
5974         uint32_t t;
5975         uint32_t n;
5976         uint32_t m;
5977         bool index;
5978         bool add;
5979         bool wback;
5980         ARM_ShifterType shift_t;
5981         uint32_t shift_n;
5982 
5983         switch (encoding)
5984         {
5985             case eEncodingT1:
5986                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5987                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5988                 t = Bits32 (opcode, 2, 0);
5989                 n = Bits32 (opcode, 5, 3);
5990                 m = Bits32 (opcode, 8, 6);
5991 
5992                 // index = TRUE; add = TRUE; wback = FALSE;
5993                 index = true;
5994                 add = true;
5995                 wback = false;
5996 
5997                 // (shift_t, shift_n) = (SRType_LSL, 0);
5998                 shift_t = SRType_LSL;
5999                 shift_n = 0;
6000 
6001                 break;
6002 
6003             case eEncodingT2:
6004                 // if Rn == '1111' then SEE LDR (literal);
6005                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6006                 t = Bits32 (opcode, 15, 12);
6007                 n = Bits32 (opcode, 19, 16);
6008                 m = Bits32 (opcode, 3, 0);
6009 
6010                 // index = TRUE; add = TRUE; wback = FALSE;
6011                 index = true;
6012                 add = true;
6013                 wback = false;
6014 
6015                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6016                 shift_t = SRType_LSL;
6017                 shift_n = Bits32 (opcode, 5, 4);
6018 
6019                 // if BadReg(m) then UNPREDICTABLE;
6020                 if (BadReg (m))
6021                     return false;
6022 
6023                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
6024                 if ((t == 15) && InITBlock() && !LastInITBlock())
6025                     return false;
6026 
6027                 break;
6028 
6029             case eEncodingA1:
6030             {
6031                 // if P == '0' && W == '1' then SEE LDRT;
6032                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6033                 t = Bits32 (opcode, 15, 12);
6034                 n = Bits32 (opcode, 19, 16);
6035                 m = Bits32 (opcode, 3, 0);
6036 
6037                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6038                 index = BitIsSet (opcode, 24);
6039                 add = BitIsSet (opcode, 23);
6040                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6041 
6042                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6043                 uint32_t type = Bits32 (opcode, 6, 5);
6044                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6045                 shift_n = DecodeImmShift (type, imm5, shift_t);
6046 
6047                 // if m == 15 then UNPREDICTABLE;
6048                 if (m == 15)
6049                     return false;
6050 
6051                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6052                 if (wback && ((n == 15) || (n == t)))
6053                     return false;
6054             }
6055                 break;
6056 
6057 
6058             default:
6059                 return false;
6060         }
6061 
6062         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6063         if (!success)
6064             return false;
6065 
6066         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6067         if (!success)
6068             return false;
6069 
6070         addr_t offset_addr;
6071         addr_t address;
6072 
6073         // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an application level alias for the CPSR".
6074         addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success);
6075         if (!success)
6076             return false;
6077 
6078         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6079         if (add)
6080             offset_addr = Rn + offset;
6081         else
6082             offset_addr = Rn - offset;
6083 
6084         // address = if index then offset_addr else R[n];
6085             if (index)
6086                 address = offset_addr;
6087             else
6088                 address = Rn;
6089 
6090         // data = MemU[address,4];
6091         RegisterInfo base_reg;
6092         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6093 
6094         EmulateInstruction::Context context;
6095         context.type = eContextRegisterLoad;
6096         context.SetRegisterPlusOffset (base_reg, address - Rn);
6097 
6098         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
6099         if (!success)
6100             return false;
6101 
6102         // if wback then R[n] = offset_addr;
6103         if (wback)
6104         {
6105             context.type = eContextAdjustBaseRegister;
6106             context.SetAddress (offset_addr);
6107             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6108                 return false;
6109         }
6110 
6111         // if t == 15 then
6112         if (t == 15)
6113         {
6114             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6115             if (BitIsClear (address, 1) && BitIsClear (address, 0))
6116             {
6117                 context.type = eContextRegisterLoad;
6118                 context.SetRegisterPlusOffset (base_reg, address - Rn);
6119                 LoadWritePC (context, data);
6120             }
6121             else
6122                 return false;
6123         }
6124         // elsif UnalignedSupport() || address<1:0> = '00' then
6125         else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
6126         {
6127             // R[t] = data;
6128             context.type = eContextRegisterLoad;
6129             context.SetRegisterPlusOffset (base_reg, address - Rn);
6130             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6131                 return false;
6132         }
6133         else // Can only apply before ARMv7
6134         {
6135             // if CurrentInstrSet() == InstrSet_ARM then
6136             if (CurrentInstrSet () == eModeARM)
6137             {
6138                 // R[t] = ROR(data, 8*UInt(address<1:0>));
6139                 data = ROR (data, Bits32 (address, 1, 0), &success);
6140                 if (!success)
6141                     return false;
6142                 context.type = eContextRegisterLoad;
6143                 context.SetImmediate (data);
6144                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6145                     return false;
6146             }
6147             else
6148             {
6149                 // R[t] = bits(32) UNKNOWN;
6150                 WriteBits32Unknown (t);
6151             }
6152         }
6153     }
6154     return true;
6155 }
6156 
6157 // LDRB (immediate, Thumb)
6158 bool
6159 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6160 {
6161 #if 0
6162     if ConditionPassed() then
6163         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6164         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6165         address = if index then offset_addr else R[n];
6166         R[t] = ZeroExtend(MemU[address,1], 32);
6167         if wback then R[n] = offset_addr;
6168 #endif
6169 
6170     bool success = false;
6171 
6172     if (ConditionPassed(opcode))
6173     {
6174         uint32_t t;
6175         uint32_t n;
6176         uint32_t imm32;
6177         bool index;
6178         bool add;
6179         bool wback;
6180 
6181         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6182         switch (encoding)
6183         {
6184             case eEncodingT1:
6185                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6186                 t = Bits32 (opcode, 2, 0);
6187                 n = Bits32 (opcode, 5, 3);
6188                 imm32 = Bits32 (opcode, 10, 6);
6189 
6190                 // index = TRUE; add = TRUE; wback = FALSE;
6191                 index = true;
6192                 add = true;
6193                 wback= false;
6194 
6195                 break;
6196 
6197             case eEncodingT2:
6198                 // if Rt == '1111' then SEE PLD;
6199                 // if Rn == '1111' then SEE LDRB (literal);
6200                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6201                 t = Bits32 (opcode, 15, 12);
6202                 n = Bits32 (opcode, 19, 16);
6203                 imm32 = Bits32 (opcode, 11, 0);
6204 
6205                 // index = TRUE; add = TRUE; wback = FALSE;
6206                 index = true;
6207                 add = true;
6208                 wback = false;
6209 
6210                 // if t == 13 then UNPREDICTABLE;
6211                 if (t == 13)
6212                     return false;
6213 
6214                 break;
6215 
6216             case eEncodingT3:
6217                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6218                 // if Rn == '1111' then SEE LDRB (literal);
6219                 // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6220                 // if P == '0' && W == '0' then UNDEFINED;
6221                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6222                     return false;
6223 
6224                   // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6225                 t = Bits32 (opcode, 15, 12);
6226                 n = Bits32 (opcode, 19, 16);
6227                 imm32 = Bits32 (opcode, 7, 0);
6228 
6229                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6230                 index = BitIsSet (opcode, 10);
6231                 add = BitIsSet (opcode, 9);
6232                 wback = BitIsSet (opcode, 8);
6233 
6234                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6235                 if (BadReg (t) || (wback && (n == t)))
6236                     return false;
6237 
6238                 break;
6239 
6240             default:
6241                 return false;
6242         }
6243 
6244         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6245         if (!success)
6246             return false;
6247 
6248         addr_t address;
6249         addr_t offset_addr;
6250 
6251         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6252         if (add)
6253             offset_addr = Rn + imm32;
6254         else
6255             offset_addr = Rn - imm32;
6256 
6257         // address = if index then offset_addr else R[n];
6258         if (index)
6259             address = offset_addr;
6260         else
6261             address = Rn;
6262 
6263         // R[t] = ZeroExtend(MemU[address,1], 32);
6264         RegisterInfo base_reg;
6265         RegisterInfo data_reg;
6266         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6267         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6268 
6269         EmulateInstruction::Context context;
6270         context.type = eContextRegisterLoad;
6271         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
6272 
6273         uint64_t data = MemURead (context, address, 1, 0, &success);
6274         if (!success)
6275             return false;
6276 
6277         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6278             return false;
6279 
6280         // if wback then R[n] = offset_addr;
6281         if (wback)
6282         {
6283             context.type = eContextAdjustBaseRegister;
6284             context.SetAddress (offset_addr);
6285             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6286                 return false;
6287         }
6288     }
6289     return true;
6290 }
6291 
6292 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6293 // zero-extends it to form a 32-bit word and writes it to a register.
6294 bool
6295 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6296 {
6297 #if 0
6298     if ConditionPassed() then
6299         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6300         base = Align(PC,4);
6301         address = if add then (base + imm32) else (base - imm32);
6302         R[t] = ZeroExtend(MemU[address,1], 32);
6303 #endif
6304 
6305     bool success = false;
6306 
6307     if (ConditionPassed(opcode))
6308     {
6309         uint32_t t;
6310         uint32_t imm32;
6311         bool add;
6312         switch (encoding)
6313         {
6314             case eEncodingT1:
6315                 // if Rt == '1111' then SEE PLD;
6316                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6317                 t = Bits32 (opcode, 15, 12);
6318                 imm32 = Bits32 (opcode, 11, 0);
6319                 add = BitIsSet (opcode, 23);
6320 
6321                 // if t == 13 then UNPREDICTABLE;
6322                 if (t == 13)
6323                     return false;
6324 
6325                 break;
6326 
6327             case eEncodingA1:
6328                 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6329                 t = Bits32 (opcode, 15, 12);
6330                 imm32 = Bits32 (opcode, 11, 0);
6331                 add = BitIsSet (opcode, 23);
6332 
6333                 // if t == 15 then UNPREDICTABLE;
6334                 if (t == 15)
6335                     return false;
6336                 break;
6337 
6338             default:
6339                 return false;
6340         }
6341 
6342         // base = Align(PC,4);
6343         uint32_t pc_val = ReadCoreReg (PC_REG, &success);
6344         if (!success)
6345             return false;
6346 
6347         uint32_t base = AlignPC (pc_val);
6348 
6349         addr_t address;
6350         // address = if add then (base + imm32) else (base - imm32);
6351         if (add)
6352             address = base + imm32;
6353         else
6354             address = base - imm32;
6355 
6356         // R[t] = ZeroExtend(MemU[address,1], 32);
6357         EmulateInstruction::Context context;
6358         context.type = eContextRelativeBranchImmediate;
6359         context.SetImmediate (address - base);
6360 
6361         uint64_t data = MemURead (context, address, 1, 0, &success);
6362         if (!success)
6363             return false;
6364 
6365         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6366             return false;
6367     }
6368     return true;
6369 }
6370 
6371 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from
6372 // memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6373 // optionally be shifted.
6374 bool
6375 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding)
6376 {
6377 #if 0
6378     if ConditionPassed() then
6379         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6380         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6381         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6382         address = if index then offset_addr else R[n];
6383         R[t] = ZeroExtend(MemU[address,1],32);
6384         if wback then R[n] = offset_addr;
6385 #endif
6386 
6387     bool success = false;
6388 
6389     if (ConditionPassed(opcode))
6390     {
6391         uint32_t t;
6392         uint32_t n;
6393         uint32_t m;
6394         bool index;
6395         bool add;
6396         bool wback;
6397         ARM_ShifterType shift_t;
6398         uint32_t shift_n;
6399 
6400         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6401         switch (encoding)
6402         {
6403             case eEncodingT1:
6404                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6405                 t = Bits32 (opcode, 2, 0);
6406                 n = Bits32 (opcode, 5, 3);
6407                 m = Bits32 (opcode, 8, 6);
6408 
6409                 // index = TRUE; add = TRUE; wback = FALSE;
6410                 index = true;
6411                 add = true;
6412                 wback = false;
6413 
6414                 // (shift_t, shift_n) = (SRType_LSL, 0);
6415                 shift_t = SRType_LSL;
6416                 shift_n = 0;
6417                 break;
6418 
6419             case eEncodingT2:
6420                 // if Rt == '1111' then SEE PLD;
6421                 // if Rn == '1111' then SEE LDRB (literal);
6422                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6423                 t = Bits32 (opcode, 15, 12);
6424                 n = Bits32 (opcode, 19, 16);
6425                 m = Bits32 (opcode, 3, 0);
6426 
6427                 // index = TRUE; add = TRUE; wback = FALSE;
6428                 index = true;
6429                 add = true;
6430                 wback = false;
6431 
6432                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6433                 shift_t = SRType_LSL;
6434                 shift_n = Bits32 (opcode, 5, 4);
6435 
6436                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6437                 if ((t == 13) || BadReg (m))
6438                     return false;
6439                 break;
6440 
6441             case eEncodingA1:
6442             {
6443                 // if P == '0' && W == '1' then SEE LDRBT;
6444                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6445                 t = Bits32 (opcode, 15, 12);
6446                 n = Bits32 (opcode, 19, 16);
6447                 m = Bits32 (opcode, 3, 0);
6448 
6449                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6450                 index = BitIsSet (opcode, 24);
6451                 add = BitIsSet (opcode, 23);
6452                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6453 
6454                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6455                 uint32_t type = Bits32 (opcode, 6, 5);
6456                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6457                 shift_n = DecodeImmShift (type, imm5, shift_t);
6458 
6459                 // if t == 15 || m == 15 then UNPREDICTABLE;
6460                 if ((t == 15) || (m == 15))
6461                     return false;
6462 
6463                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6464                 if (wback && ((n == 15) || (n == t)))
6465                     return false;
6466             }
6467                 break;
6468 
6469             default:
6470                 return false;
6471         }
6472 
6473         addr_t offset_addr;
6474         addr_t address;
6475 
6476         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6477         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6478         if (!success)
6479             return false;
6480 
6481         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6482         if (!success)
6483             return false;
6484 
6485         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6486         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6487         if (!success)
6488             return false;
6489 
6490         if (add)
6491             offset_addr = Rn + offset;
6492         else
6493             offset_addr = Rn - offset;
6494 
6495         // address = if index then offset_addr else R[n];
6496         if (index)
6497             address = offset_addr;
6498         else
6499             address = Rn;
6500 
6501         // R[t] = ZeroExtend(MemU[address,1],32);
6502         RegisterInfo base_reg;
6503         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6504 
6505         EmulateInstruction::Context context;
6506         context.type = eContextRegisterLoad;
6507         context.SetRegisterPlusOffset (base_reg, address - Rn);
6508 
6509         uint64_t data = MemURead (context, address, 1, 0, &success);
6510         if (!success)
6511             return false;
6512 
6513         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6514             return false;
6515 
6516         // if wback then R[n] = offset_addr;
6517         if (wback)
6518         {
6519             context.type = eContextAdjustBaseRegister;
6520             context.SetAddress (offset_addr);
6521             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6522                 return false;
6523         }
6524     }
6525     return true;
6526 }
6527 
6528 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a
6529 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register.  It can use offset,
6530 // post-indexed, or pre-indexed addressing.
6531 bool
6532 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding)
6533 {
6534 #if 0
6535     if ConditionPassed() then
6536         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6537         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6538         address = if index then offset_addr else R[n];
6539         data = MemU[address,2];
6540         if wback then R[n] = offset_addr;
6541         if UnalignedSupport() || address<0> = '0' then
6542             R[t] = ZeroExtend(data, 32);
6543         else // Can only apply before ARMv7
6544             R[t] = bits(32) UNKNOWN;
6545 #endif
6546 
6547 
6548     bool success = false;
6549 
6550     if (ConditionPassed(opcode))
6551     {
6552         uint32_t t;
6553         uint32_t n;
6554         uint32_t imm32;
6555         bool index;
6556         bool add;
6557         bool wback;
6558 
6559         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6560         switch (encoding)
6561         {
6562             case eEncodingT1:
6563                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
6564                 t = Bits32 (opcode, 2, 0);
6565                 n = Bits32 (opcode, 5, 3);
6566                 imm32 = Bits32 (opcode, 10, 6) << 1;
6567 
6568                 // index = TRUE; add = TRUE; wback = FALSE;
6569                 index = true;
6570                 add = true;
6571                 wback = false;
6572 
6573                 break;
6574 
6575             case eEncodingT2:
6576                 // if Rt == '1111' then SEE "Unallocated memory hints";
6577                 // if Rn == '1111' then SEE LDRH (literal);
6578                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6579                 t = Bits32 (opcode, 15, 12);
6580                 n = Bits32 (opcode, 19, 16);
6581                 imm32 = Bits32 (opcode, 11, 0);
6582 
6583                 // index = TRUE; add = TRUE; wback = FALSE;
6584                 index = true;
6585                 add = true;
6586                 wback = false;
6587 
6588                 // if t == 13 then UNPREDICTABLE;
6589                 if (t == 13)
6590                     return false;
6591                 break;
6592 
6593             case eEncodingT3:
6594                 // if Rn == '1111' then SEE LDRH (literal);
6595                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
6596                 // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
6597                 // if P == '0' && W == '0' then UNDEFINED;
6598                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6599                     return false;
6600 
6601                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6602                 t = Bits32 (opcode, 15, 12);
6603                 n = Bits32 (opcode, 19, 16);
6604                 imm32 = Bits32 (opcode, 7, 0);
6605 
6606                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6607                 index = BitIsSet (opcode, 10);
6608                 add = BitIsSet (opcode, 9);
6609                 wback = BitIsSet (opcode, 8);
6610 
6611                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6612                 if (BadReg (t) || (wback && (n == t)))
6613                     return false;
6614                 break;
6615 
6616             default:
6617                 return false;
6618         }
6619 
6620         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6621         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6622         if (!success)
6623             return false;
6624 
6625         addr_t offset_addr;
6626         addr_t address;
6627 
6628         if (add)
6629             offset_addr = Rn + imm32;
6630         else
6631             offset_addr = Rn - imm32;
6632 
6633         // address = if index then offset_addr else R[n];
6634         if (index)
6635             address = offset_addr;
6636         else
6637             address = Rn;
6638 
6639         // data = MemU[address,2];
6640         RegisterInfo base_reg;
6641         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6642 
6643         EmulateInstruction::Context context;
6644         context.type = eContextRegisterLoad;
6645         context.SetRegisterPlusOffset (base_reg, address - Rn);
6646 
6647         uint64_t data = MemURead (context, address, 2, 0, &success);
6648         if (!success)
6649             return false;
6650 
6651         // if wback then R[n] = offset_addr;
6652         if (wback)
6653         {
6654             context.type = eContextAdjustBaseRegister;
6655             context.SetAddress (offset_addr);
6656             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6657                 return false;
6658         }
6659 
6660         // if UnalignedSupport() || address<0> = '0' then
6661         if (UnalignedSupport () || BitIsClear (address, 0))
6662         {
6663             // R[t] = ZeroExtend(data, 32);
6664             context.type = eContextRegisterLoad;
6665             context.SetRegisterPlusOffset (base_reg, address - Rn);
6666             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6667                 return false;
6668         }
6669         else // Can only apply before ARMv7
6670         {
6671             // R[t] = bits(32) UNKNOWN;
6672             WriteBits32Unknown (t);
6673         }
6674     }
6675     return true;
6676 }
6677 
6678 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory,
6679 // zero-extends it to form a 32-bit word, and writes it to a register.
6680 bool
6681 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding)
6682 {
6683 #if 0
6684     if ConditionPassed() then
6685         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6686         base = Align(PC,4);
6687         address = if add then (base + imm32) else (base - imm32);
6688         data = MemU[address,2];
6689         if UnalignedSupport() || address<0> = '0' then
6690             R[t] = ZeroExtend(data, 32);
6691         else // Can only apply before ARMv7
6692             R[t] = bits(32) UNKNOWN;
6693 #endif
6694 
6695     bool success = false;
6696 
6697     if (ConditionPassed(opcode))
6698     {
6699         uint32_t t;
6700         uint32_t imm32;
6701         bool add;
6702 
6703         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6704         switch (encoding)
6705         {
6706             case eEncodingT1:
6707                 // if Rt == '1111' then SEE "Unallocated memory hints";
6708                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6709                 t = Bits32 (opcode, 15, 12);
6710                 imm32 = Bits32 (opcode, 11, 0);
6711                 add = BitIsSet (opcode, 23);
6712 
6713                 // if t == 13 then UNPREDICTABLE;
6714                 if (t == 13)
6715                     return false;
6716 
6717                 break;
6718 
6719             case eEncodingA1:
6720             {
6721                 uint32_t imm4H = Bits32 (opcode, 11, 8);
6722                 uint32_t imm4L = Bits32 (opcode, 3, 0);
6723 
6724                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6725                 t = Bits32 (opcode, 15, 12);
6726                 imm32 = (imm4H << 4) | imm4L;
6727                 add = BitIsSet (opcode, 23);
6728 
6729                 // if t == 15 then UNPREDICTABLE;
6730                 if (t == 15)
6731                     return false;
6732                 break;
6733             }
6734 
6735             default:
6736                 return false;
6737         }
6738 
6739         // base = Align(PC,4);
6740         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6741         if (!success)
6742             return false;
6743 
6744         addr_t base = AlignPC (pc_value);
6745         addr_t address;
6746 
6747         // address = if add then (base + imm32) else (base - imm32);
6748         if (add)
6749             address = base + imm32;
6750         else
6751             address = base - imm32;
6752 
6753         // data = MemU[address,2];
6754         RegisterInfo base_reg;
6755         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
6756 
6757         EmulateInstruction::Context context;
6758         context.type = eContextRegisterLoad;
6759         context.SetRegisterPlusOffset (base_reg, address - base);
6760 
6761         uint64_t data = MemURead (context, address, 2, 0, &success);
6762         if (!success)
6763             return false;
6764 
6765 
6766         // if UnalignedSupport() || address<0> = '0' then
6767         if (UnalignedSupport () || BitIsClear (address, 0))
6768         {
6769             // R[t] = ZeroExtend(data, 32);
6770             context.type = eContextRegisterLoad;
6771             context.SetRegisterPlusOffset (base_reg, address - base);
6772             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6773                 return false;
6774 
6775         }
6776         else // Can only apply before ARMv7
6777         {
6778             // R[t] = bits(32) UNKNOWN;
6779             WriteBits32Unknown (t);
6780         }
6781     }
6782     return true;
6783 }
6784 
6785 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword
6786 // from memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6787 // be shifted left by 0, 1, 2, or 3 bits.
6788 bool
6789 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding)
6790 {
6791 #if 0
6792     if ConditionPassed() then
6793         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6794         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6795         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6796         address = if index then offset_addr else R[n];
6797         data = MemU[address,2];
6798         if wback then R[n] = offset_addr;
6799         if UnalignedSupport() || address<0> = '0' then
6800             R[t] = ZeroExtend(data, 32);
6801         else // Can only apply before ARMv7
6802             R[t] = bits(32) UNKNOWN;
6803 #endif
6804 
6805     bool success = false;
6806 
6807     if (ConditionPassed(opcode))
6808     {
6809         uint32_t t;
6810         uint32_t n;
6811         uint32_t m;
6812         bool index;
6813         bool add;
6814         bool wback;
6815         ARM_ShifterType shift_t;
6816         uint32_t shift_n;
6817 
6818         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6819         switch (encoding)
6820         {
6821             case eEncodingT1:
6822                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6823                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6824                 t = Bits32 (opcode, 2, 0);
6825                 n = Bits32 (opcode, 5, 3);
6826                 m = Bits32 (opcode, 8, 6);
6827 
6828                 // index = TRUE; add = TRUE; wback = FALSE;
6829                 index = true;
6830                 add = true;
6831                 wback = false;
6832 
6833                 // (shift_t, shift_n) = (SRType_LSL, 0);
6834                 shift_t = SRType_LSL;
6835                 shift_n = 0;
6836 
6837                 break;
6838 
6839             case eEncodingT2:
6840                 // if Rn == '1111' then SEE LDRH (literal);
6841                 // if Rt == '1111' then SEE "Unallocated memory hints";
6842                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6843                 t = Bits32 (opcode, 15, 12);
6844                 n = Bits32 (opcode, 19, 16);
6845                 m = Bits32 (opcode, 3, 0);
6846 
6847                 // index = TRUE; add = TRUE; wback = FALSE;
6848                 index = true;
6849                 add = true;
6850                 wback = false;
6851 
6852                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6853                 shift_t = SRType_LSL;
6854                 shift_n = Bits32 (opcode, 5, 4);
6855 
6856                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6857                 if ((t == 13) || BadReg (m))
6858                     return false;
6859                 break;
6860 
6861             case eEncodingA1:
6862                 // if P == '0' && W == '1' then SEE LDRHT;
6863                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6864                 t = Bits32 (opcode, 15, 12);
6865                 n = Bits32 (opcode, 19, 16);
6866                 m = Bits32 (opcode, 3, 0);
6867 
6868                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6869                 index = BitIsSet (opcode, 24);
6870                 add = BitIsSet (opcode, 23);
6871                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6872 
6873                 // (shift_t, shift_n) = (SRType_LSL, 0);
6874                 shift_t = SRType_LSL;
6875                 shift_n = 0;
6876 
6877                 // if t == 15 || m == 15 then UNPREDICTABLE;
6878                 if ((t == 15) || (m == 15))
6879                     return false;
6880 
6881                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6882                 if (wback && ((n == 15) || (n == t)))
6883                     return false;
6884 
6885                 break;
6886 
6887             default:
6888                 return false;
6889         }
6890 
6891         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6892 
6893         uint64_t Rm  = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6894         if (!success)
6895             return false;
6896 
6897         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6898         if (!success)
6899             return false;
6900 
6901         addr_t offset_addr;
6902         addr_t address;
6903 
6904         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6905         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6906         if (!success)
6907             return false;
6908 
6909         if (add)
6910             offset_addr = Rn + offset;
6911         else
6912             offset_addr = Rn - offset;
6913 
6914         // address = if index then offset_addr else R[n];
6915         if (index)
6916             address = offset_addr;
6917         else
6918             address = Rn;
6919 
6920         // data = MemU[address,2];
6921         RegisterInfo base_reg;
6922         RegisterInfo offset_reg;
6923         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6924         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
6925 
6926         EmulateInstruction::Context context;
6927         context.type = eContextRegisterLoad;
6928         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6929         uint64_t data = MemURead (context, address, 2, 0, &success);
6930         if (!success)
6931             return false;
6932 
6933         // if wback then R[n] = offset_addr;
6934         if (wback)
6935         {
6936             context.type = eContextAdjustBaseRegister;
6937             context.SetAddress (offset_addr);
6938             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6939                 return false;
6940         }
6941 
6942         // if UnalignedSupport() || address<0> = '0' then
6943         if (UnalignedSupport() || BitIsClear (address, 0))
6944         {
6945             // R[t] = ZeroExtend(data, 32);
6946             context.type = eContextRegisterLoad;
6947             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6948             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6949                 return false;
6950         }
6951         else // Can only apply before ARMv7
6952         {
6953             // R[t] = bits(32) UNKNOWN;
6954             WriteBits32Unknown (t);
6955         }
6956     }
6957     return true;
6958 }
6959 
6960 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from
6961 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed,
6962 // or pre-indexed addressing.
6963 bool
6964 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6965 {
6966 #if 0
6967     if ConditionPassed() then
6968         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6969         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6970         address = if index then offset_addr else R[n];
6971         R[t] = SignExtend(MemU[address,1], 32);
6972         if wback then R[n] = offset_addr;
6973 #endif
6974 
6975     bool success = false;
6976 
6977     if (ConditionPassed(opcode))
6978     {
6979         uint32_t t;
6980         uint32_t n;
6981         uint32_t imm32;
6982         bool index;
6983         bool add;
6984         bool wback;
6985 
6986         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6987         switch (encoding)
6988         {
6989             case eEncodingT1:
6990                 // if Rt == '1111' then SEE PLI;
6991                 // if Rn == '1111' then SEE LDRSB (literal);
6992                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6993                 t = Bits32 (opcode, 15, 12);
6994                 n = Bits32 (opcode, 19, 16);
6995                 imm32 = Bits32 (opcode, 11, 0);
6996 
6997                 // index = TRUE; add = TRUE; wback = FALSE;
6998                 index = true;
6999                 add = true;
7000                 wback = false;
7001 
7002                 // if t == 13 then UNPREDICTABLE;
7003                 if (t == 13)
7004                     return false;
7005 
7006                 break;
7007 
7008             case eEncodingT2:
7009                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
7010                 // if Rn == '1111' then SEE LDRSB (literal);
7011                 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
7012                 // if P == '0' && W == '0' then UNDEFINED;
7013                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7014                     return false;
7015 
7016                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7017                 t = Bits32 (opcode, 15, 12);
7018                 n = Bits32 (opcode, 19, 16);
7019                 imm32 = Bits32 (opcode, 7, 0);
7020 
7021                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7022                 index = BitIsSet (opcode, 10);
7023                 add = BitIsSet (opcode, 9);
7024                 wback = BitIsSet (opcode, 8);
7025 
7026                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7027                   if (((t == 13) || ((t == 15)
7028                                      && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8))))
7029                       || (wback && (n == t)))
7030                     return false;
7031 
7032                 break;
7033 
7034             case eEncodingA1:
7035             {
7036                 // if Rn == '1111' then SEE LDRSB (literal);
7037                 // if P == '0' && W == '1' then SEE LDRSBT;
7038                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7039                 t = Bits32 (opcode, 15, 12);
7040                 n = Bits32 (opcode, 19, 16);
7041 
7042                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7043                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7044                 imm32 = (imm4H << 4) | imm4L;
7045 
7046                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7047                 index = BitIsSet (opcode, 24);
7048                 add = BitIsSet (opcode, 23);
7049                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
7050 
7051                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7052                 if ((t == 15) || (wback && (n == t)))
7053                     return false;
7054 
7055                 break;
7056             }
7057 
7058             default:
7059                 return false;
7060         }
7061 
7062         uint64_t Rn = ReadCoreReg (n, &success);
7063         if (!success)
7064             return false;
7065 
7066         addr_t offset_addr;
7067         addr_t address;
7068 
7069         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7070         if (add)
7071             offset_addr = Rn + imm32;
7072         else
7073             offset_addr = Rn - imm32;
7074 
7075         // address = if index then offset_addr else R[n];
7076         if (index)
7077             address = offset_addr;
7078         else
7079             address = Rn;
7080 
7081         // R[t] = SignExtend(MemU[address,1], 32);
7082         RegisterInfo base_reg;
7083         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7084 
7085         EmulateInstruction::Context context;
7086         context.type = eContextRegisterLoad;
7087         context.SetRegisterPlusOffset (base_reg, address - Rn);
7088 
7089         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7090         if (!success)
7091             return false;
7092 
7093         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7094         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7095             return false;
7096 
7097         // if wback then R[n] = offset_addr;
7098         if (wback)
7099         {
7100             context.type = eContextAdjustBaseRegister;
7101             context.SetAddress (offset_addr);
7102             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7103                 return false;
7104         }
7105     }
7106 
7107     return true;
7108 }
7109 
7110 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
7111 // sign-extends it to form a 32-bit word, and writes tit to a register.
7112 bool
7113 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding)
7114 {
7115 #if 0
7116     if ConditionPassed() then
7117         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7118         base = Align(PC,4);
7119         address = if add then (base + imm32) else (base - imm32);
7120         R[t] = SignExtend(MemU[address,1], 32);
7121 #endif
7122 
7123     bool success = false;
7124 
7125     if (ConditionPassed(opcode))
7126     {
7127         uint32_t t;
7128         uint32_t imm32;
7129         bool add;
7130 
7131         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7132         switch (encoding)
7133         {
7134             case eEncodingT1:
7135                 // if Rt == '1111' then SEE PLI;
7136                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7137                 t = Bits32 (opcode, 15, 12);
7138                 imm32 = Bits32 (opcode, 11, 0);
7139                 add = BitIsSet (opcode, 23);
7140 
7141                 // if t == 13 then UNPREDICTABLE;
7142                 if (t == 13)
7143                     return false;
7144 
7145                 break;
7146 
7147             case eEncodingA1:
7148             {
7149                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7150                 t = Bits32 (opcode, 15, 12);
7151                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7152                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7153                 imm32 = (imm4H << 4) | imm4L;
7154                 add = BitIsSet (opcode, 23);
7155 
7156                 // if t == 15 then UNPREDICTABLE;
7157                 if (t == 15)
7158                     return false;
7159 
7160                 break;
7161             }
7162 
7163             default:
7164                 return false;
7165         }
7166 
7167         // base = Align(PC,4);
7168         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7169         if (!success)
7170             return false;
7171         uint64_t base = AlignPC (pc_value);
7172 
7173         // address = if add then (base + imm32) else (base - imm32);
7174         addr_t address;
7175         if (add)
7176             address = base + imm32;
7177         else
7178             address = base - imm32;
7179 
7180         // R[t] = SignExtend(MemU[address,1], 32);
7181         RegisterInfo base_reg;
7182         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7183 
7184         EmulateInstruction::Context context;
7185         context.type = eContextRegisterLoad;
7186         context.SetRegisterPlusOffset (base_reg, address - base);
7187 
7188         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7189         if (!success)
7190             return false;
7191 
7192         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7193         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7194             return false;
7195     }
7196     return true;
7197 }
7198 
7199 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from
7200 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7201 // shifted left by 0, 1, 2, or 3 bits.
7202 bool
7203 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding)
7204 {
7205 #if 0
7206     if ConditionPassed() then
7207         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7208         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7209         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7210         address = if index then offset_addr else R[n];
7211         R[t] = SignExtend(MemU[address,1], 32);
7212         if wback then R[n] = offset_addr;
7213 #endif
7214 
7215     bool success = false;
7216 
7217     if (ConditionPassed(opcode))
7218     {
7219         uint32_t t;
7220         uint32_t n;
7221         uint32_t m;
7222         bool index;
7223         bool add;
7224         bool wback;
7225         ARM_ShifterType shift_t;
7226         uint32_t shift_n;
7227 
7228         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7229         switch (encoding)
7230         {
7231             case eEncodingT1:
7232                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7233                 t = Bits32 (opcode, 2, 0);
7234                 n = Bits32 (opcode, 5, 3);
7235                 m = Bits32 (opcode, 8, 6);
7236 
7237                 // index = TRUE; add = TRUE; wback = FALSE;
7238                 index = true;
7239                 add = true;
7240                 wback = false;
7241 
7242                 // (shift_t, shift_n) = (SRType_LSL, 0);
7243                 shift_t = SRType_LSL;
7244                 shift_n = 0;
7245 
7246                 break;
7247 
7248             case eEncodingT2:
7249                 // if Rt == '1111' then SEE PLI;
7250                 // if Rn == '1111' then SEE LDRSB (literal);
7251                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7252                 t = Bits32 (opcode, 15, 12);
7253                 n = Bits32 (opcode, 19, 16);
7254                 m = Bits32 (opcode, 3, 0);
7255 
7256                 // index = TRUE; add = TRUE; wback = FALSE;
7257                 index = true;
7258                 add = true;
7259                 wback = false;
7260 
7261                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7262                 shift_t = SRType_LSL;
7263                 shift_n = Bits32 (opcode, 5, 4);
7264 
7265                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7266                 if ((t == 13) || BadReg (m))
7267                     return false;
7268                 break;
7269 
7270             case eEncodingA1:
7271                 // if P == '0' && W == '1' then SEE LDRSBT;
7272                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7273                 t = Bits32 (opcode, 15, 12);
7274                 n = Bits32 (opcode, 19, 16);
7275                 m = Bits32 (opcode, 3, 0);
7276 
7277                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7278                 index = BitIsSet (opcode, 24);
7279                 add = BitIsSet (opcode, 23);
7280                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7281 
7282                 // (shift_t, shift_n) = (SRType_LSL, 0);
7283                 shift_t = SRType_LSL;
7284                 shift_n = 0;
7285 
7286                 // if t == 15 || m == 15 then UNPREDICTABLE;
7287                 if ((t == 15) || (m == 15))
7288                     return false;
7289 
7290                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7291                 if (wback && ((n == 15) || (n == t)))
7292                     return false;
7293                 break;
7294 
7295             default:
7296                 return false;
7297         }
7298 
7299         uint64_t Rm =  ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7300         if (!success)
7301             return false;
7302 
7303         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7304         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7305         if (!success)
7306             return false;
7307 
7308         addr_t offset_addr;
7309         addr_t address;
7310 
7311         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7312         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7313         if (!success)
7314             return false;
7315 
7316         if (add)
7317             offset_addr = Rn + offset;
7318         else
7319             offset_addr = Rn - offset;
7320 
7321         // address = if index then offset_addr else R[n];
7322         if (index)
7323             address = offset_addr;
7324         else
7325             address = Rn;
7326 
7327         // R[t] = SignExtend(MemU[address,1], 32);
7328         RegisterInfo base_reg;
7329         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7330         RegisterInfo offset_reg;
7331         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7332 
7333         EmulateInstruction::Context context;
7334         context.type = eContextRegisterLoad;
7335         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7336 
7337         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7338         if (!success)
7339             return false;
7340 
7341         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7342         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7343             return false;
7344 
7345         // if wback then R[n] = offset_addr;
7346         if (wback)
7347         {
7348             context.type = eContextAdjustBaseRegister;
7349             context.SetAddress (offset_addr);
7350             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7351                 return false;
7352         }
7353     }
7354     return true;
7355 }
7356 
7357 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from
7358 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed, or
7359 // pre-indexed addressing.
7360 bool
7361 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding)
7362 {
7363 #if 0
7364     if ConditionPassed() then
7365         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7366         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7367         address = if index then offset_addr else R[n];
7368         data = MemU[address,2];
7369         if wback then R[n] = offset_addr;
7370         if UnalignedSupport() || address<0> = '0' then
7371             R[t] = SignExtend(data, 32);
7372         else // Can only apply before ARMv7
7373             R[t] = bits(32) UNKNOWN;
7374 #endif
7375 
7376     bool success = false;
7377 
7378     if (ConditionPassed(opcode))
7379     {
7380         uint32_t t;
7381         uint32_t n;
7382         uint32_t imm32;
7383         bool index;
7384         bool add;
7385         bool wback;
7386 
7387         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7388         switch (encoding)
7389         {
7390             case eEncodingT1:
7391                 // if Rn == '1111' then SEE LDRSH (literal);
7392                 // if Rt == '1111' then SEE "Unallocated memory hints";
7393                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7394                 t = Bits32 (opcode, 15, 12);
7395                 n = Bits32 (opcode, 19, 16);
7396                 imm32 = Bits32 (opcode, 11, 0);
7397 
7398                 // index = TRUE; add = TRUE; wback = FALSE;
7399                 index = true;
7400                 add = true;
7401                 wback = false;
7402 
7403                 // if t == 13 then UNPREDICTABLE;
7404                 if (t == 13)
7405                     return false;
7406 
7407                 break;
7408 
7409             case eEncodingT2:
7410                 // if Rn == '1111' then SEE LDRSH (literal);
7411                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
7412                 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7413                 // if P == '0' && W == '0' then UNDEFINED;
7414                   if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7415                   return false;
7416 
7417                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7418                 t = Bits32 (opcode, 15, 12);
7419                 n = Bits32 (opcode, 19, 16);
7420                 imm32 = Bits32 (opcode, 7, 0);
7421 
7422                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7423                 index = BitIsSet (opcode, 10);
7424                 add = BitIsSet (opcode, 9);
7425                 wback = BitIsSet (opcode, 8);
7426 
7427                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7428                 if (BadReg (t) || (wback && (n == t)))
7429                     return false;
7430 
7431                 break;
7432 
7433             case eEncodingA1:
7434             {
7435                 // if Rn == '1111' then SEE LDRSH (literal);
7436                 // if P == '0' && W == '1' then SEE LDRSHT;
7437                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7438                 t = Bits32 (opcode, 15, 12);
7439                 n = Bits32 (opcode, 19, 16);
7440                 uint32_t imm4H = Bits32 (opcode, 11,8);
7441                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7442                 imm32 = (imm4H << 4) | imm4L;
7443 
7444                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7445                 index = BitIsSet (opcode, 24);
7446                 add = BitIsSet (opcode, 23);
7447                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7448 
7449                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7450                 if ((t == 15) || (wback && (n == t)))
7451                     return false;
7452 
7453                 break;
7454             }
7455 
7456             default:
7457                 return false;
7458         }
7459 
7460         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7461         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7462         if (!success)
7463             return false;
7464 
7465         addr_t offset_addr;
7466         if (add)
7467             offset_addr = Rn + imm32;
7468         else
7469             offset_addr = Rn - imm32;
7470 
7471         // address = if index then offset_addr else R[n];
7472         addr_t address;
7473         if (index)
7474             address = offset_addr;
7475         else
7476             address = Rn;
7477 
7478         // data = MemU[address,2];
7479         RegisterInfo base_reg;
7480         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7481 
7482         EmulateInstruction::Context context;
7483         context.type = eContextRegisterLoad;
7484         context.SetRegisterPlusOffset (base_reg, address - Rn);
7485 
7486         uint64_t data = MemURead (context, address, 2, 0, &success);
7487         if (!success)
7488             return false;
7489 
7490         // if wback then R[n] = offset_addr;
7491         if (wback)
7492         {
7493             context.type = eContextAdjustBaseRegister;
7494             context.SetAddress (offset_addr);
7495             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7496                 return false;
7497         }
7498 
7499         // if UnalignedSupport() || address<0> = '0' then
7500         if (UnalignedSupport() || BitIsClear (address, 0))
7501         {
7502             // R[t] = SignExtend(data, 32);
7503             int64_t signed_data = llvm::SignExtend64<16>(data);
7504             context.type = eContextRegisterLoad;
7505             context.SetRegisterPlusOffset (base_reg, address - Rn);
7506             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7507                 return false;
7508         }
7509         else // Can only apply before ARMv7
7510         {
7511             // R[t] = bits(32) UNKNOWN;
7512             WriteBits32Unknown (t);
7513         }
7514     }
7515     return true;
7516 }
7517 
7518 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory,
7519 // sign-extends it to from a 32-bit word, and writes it to a register.
7520 bool
7521 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding)
7522 {
7523 #if 0
7524     if ConditionPassed() then
7525         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7526         base = Align(PC,4);
7527         address = if add then (base + imm32) else (base - imm32);
7528         data = MemU[address,2];
7529         if UnalignedSupport() || address<0> = '0' then
7530             R[t] = SignExtend(data, 32);
7531         else // Can only apply before ARMv7
7532             R[t] = bits(32) UNKNOWN;
7533 #endif
7534 
7535     bool success = false;
7536 
7537     if (ConditionPassed(opcode))
7538     {
7539         uint32_t t;
7540         uint32_t imm32;
7541         bool add;
7542 
7543         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7544         switch (encoding)
7545         {
7546             case eEncodingT1:
7547                 // if Rt == '1111' then SEE "Unallocated memory hints";
7548                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7549                 t = Bits32  (opcode, 15, 12);
7550                 imm32 = Bits32 (opcode, 11, 0);
7551                 add = BitIsSet (opcode, 23);
7552 
7553                 // if t == 13 then UNPREDICTABLE;
7554                 if (t == 13)
7555                     return false;
7556 
7557                 break;
7558 
7559             case eEncodingA1:
7560             {
7561                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7562                 t = Bits32 (opcode, 15, 12);
7563                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7564                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7565                 imm32 = (imm4H << 4) | imm4L;
7566                 add = BitIsSet (opcode, 23);
7567 
7568                 // if t == 15 then UNPREDICTABLE;
7569                 if (t == 15)
7570                     return false;
7571 
7572                 break;
7573             }
7574             default:
7575                 return false;
7576         }
7577 
7578         // base = Align(PC,4);
7579         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7580         if (!success)
7581             return false;
7582 
7583         uint64_t base = AlignPC (pc_value);
7584 
7585         addr_t address;
7586         // address = if add then (base + imm32) else (base - imm32);
7587         if (add)
7588             address = base + imm32;
7589         else
7590             address = base - imm32;
7591 
7592         // data = MemU[address,2];
7593         RegisterInfo base_reg;
7594         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7595 
7596         EmulateInstruction::Context context;
7597         context.type = eContextRegisterLoad;
7598         context.SetRegisterPlusOffset (base_reg, imm32);
7599 
7600         uint64_t data = MemURead (context, address, 2, 0, &success);
7601         if (!success)
7602             return false;
7603 
7604         // if UnalignedSupport() || address<0> = '0' then
7605         if (UnalignedSupport() || BitIsClear (address, 0))
7606         {
7607             // R[t] = SignExtend(data, 32);
7608             int64_t signed_data = llvm::SignExtend64<16>(data);
7609             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7610                 return false;
7611         }
7612         else // Can only apply before ARMv7
7613         {
7614             // R[t] = bits(32) UNKNOWN;
7615             WriteBits32Unknown (t);
7616         }
7617     }
7618     return true;
7619 }
7620 
7621 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword
7622 // from memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7623 // shifted left by 0, 1, 2, or 3 bits.
7624 bool
7625 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding)
7626 {
7627 #if 0
7628     if ConditionPassed() then
7629         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7630         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7631         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7632         address = if index then offset_addr else R[n];
7633         data = MemU[address,2];
7634         if wback then R[n] = offset_addr;
7635         if UnalignedSupport() || address<0> = '0' then
7636             R[t] = SignExtend(data, 32);
7637         else // Can only apply before ARMv7
7638             R[t] = bits(32) UNKNOWN;
7639 #endif
7640 
7641     bool success = false;
7642 
7643     if (ConditionPassed(opcode))
7644     {
7645         uint32_t t;
7646         uint32_t n;
7647         uint32_t m;
7648         bool index;
7649         bool add;
7650         bool wback;
7651         ARM_ShifterType shift_t;
7652         uint32_t shift_n;
7653 
7654         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7655         switch (encoding)
7656         {
7657             case eEncodingT1:
7658                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
7659                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7660                 t = Bits32 (opcode, 2, 0);
7661                 n = Bits32 (opcode, 5, 3);
7662                 m = Bits32 (opcode, 8, 6);
7663 
7664                 // index = TRUE; add = TRUE; wback = FALSE;
7665                 index = true;
7666                 add = true;
7667                 wback = false;
7668 
7669                 // (shift_t, shift_n) = (SRType_LSL, 0);
7670                 shift_t = SRType_LSL;
7671                 shift_n = 0;
7672 
7673                 break;
7674 
7675             case eEncodingT2:
7676                 // if Rn == '1111' then SEE LDRSH (literal);
7677                 // if Rt == '1111' then SEE "Unallocated memory hints";
7678                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7679                 t = Bits32 (opcode, 15, 12);
7680                 n = Bits32 (opcode, 19, 16);
7681                 m = Bits32 (opcode, 3, 0);
7682 
7683                 // index = TRUE; add = TRUE; wback = FALSE;
7684                 index = true;
7685                 add = true;
7686                 wback = false;
7687 
7688                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7689                 shift_t = SRType_LSL;
7690                 shift_n = Bits32 (opcode, 5, 4);
7691 
7692                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7693                 if ((t == 13) || BadReg (m))
7694                     return false;
7695 
7696                 break;
7697 
7698             case eEncodingA1:
7699                 // if P == '0' && W == '1' then SEE LDRSHT;
7700                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7701                 t = Bits32 (opcode, 15, 12);
7702                 n = Bits32 (opcode, 19, 16);
7703                 m = Bits32 (opcode, 3, 0);
7704 
7705                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7706                 index = BitIsSet (opcode, 24);
7707                 add = BitIsSet (opcode, 23);
7708                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7709 
7710                 // (shift_t, shift_n) = (SRType_LSL, 0);
7711                 shift_t = SRType_LSL;
7712                 shift_n = 0;
7713 
7714                 // if t == 15 || m == 15 then UNPREDICTABLE;
7715                 if ((t == 15) || (m == 15))
7716                     return false;
7717 
7718                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7719                 if (wback && ((n == 15) || (n == t)))
7720                     return false;
7721 
7722                 break;
7723 
7724             default:
7725                 return false;
7726         }
7727 
7728         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7729         if (!success)
7730             return false;
7731 
7732         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7733         if (!success)
7734             return false;
7735 
7736         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7737         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7738         if (!success)
7739             return false;
7740 
7741         addr_t offset_addr;
7742         addr_t address;
7743 
7744         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7745         if (add)
7746             offset_addr = Rn + offset;
7747         else
7748             offset_addr = Rn - offset;
7749 
7750         // address = if index then offset_addr else R[n];
7751         if (index)
7752             address = offset_addr;
7753         else
7754             address = Rn;
7755 
7756         // data = MemU[address,2];
7757         RegisterInfo base_reg;
7758         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7759 
7760         RegisterInfo offset_reg;
7761         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7762 
7763         EmulateInstruction::Context context;
7764         context.type = eContextRegisterLoad;
7765         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7766 
7767         uint64_t data = MemURead (context, address, 2, 0, &success);
7768         if (!success)
7769             return false;
7770 
7771         // if wback then R[n] = offset_addr;
7772         if (wback)
7773         {
7774             context.type = eContextAdjustBaseRegister;
7775             context.SetAddress (offset_addr);
7776             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7777                 return false;
7778         }
7779 
7780         // if UnalignedSupport() || address<0> = '0' then
7781         if (UnalignedSupport() || BitIsClear (address, 0))
7782         {
7783             // R[t] = SignExtend(data, 32);
7784             context.type = eContextRegisterLoad;
7785             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7786 
7787             int64_t signed_data = llvm::SignExtend64<16>(data);
7788             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7789                 return false;
7790         }
7791         else // Can only apply before ARMv7
7792         {
7793             // R[t] = bits(32) UNKNOWN;
7794             WriteBits32Unknown (t);
7795         }
7796     }
7797     return true;
7798 }
7799 
7800 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7801 // register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7802 bool
7803 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding)
7804 {
7805 #if 0
7806     if ConditionPassed() then
7807         EncodingSpecificOperations();
7808         rotated = ROR(R[m], rotation);
7809         R[d] = SignExtend(rotated<7:0>, 32);
7810 #endif
7811 
7812     bool success = false;
7813 
7814     if (ConditionPassed(opcode))
7815     {
7816         uint32_t d;
7817         uint32_t m;
7818         uint32_t rotation;
7819 
7820         // EncodingSpecificOperations();
7821         switch (encoding)
7822         {
7823             case eEncodingT1:
7824                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7825                 d = Bits32 (opcode, 2, 0);
7826                 m = Bits32 (opcode, 5, 3);
7827                 rotation = 0;
7828 
7829                 break;
7830 
7831             case eEncodingT2:
7832                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7833                 d = Bits32 (opcode, 11, 8);
7834                 m = Bits32 (opcode, 3, 0);
7835                 rotation = Bits32 (opcode, 5, 4) << 3;
7836 
7837                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7838                 if (BadReg (d) || BadReg (m))
7839                     return false;
7840 
7841                 break;
7842 
7843             case eEncodingA1:
7844                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7845                 d = Bits32 (opcode, 15, 12);
7846                 m = Bits32 (opcode, 3, 0);
7847                 rotation = Bits32 (opcode, 11, 10) << 3;
7848 
7849                 // if d == 15 || m == 15 then UNPREDICTABLE;
7850                 if ((d == 15) || (m == 15))
7851                     return false;
7852 
7853                 break;
7854 
7855             default:
7856                 return false;
7857         }
7858 
7859         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7860         if (!success)
7861             return false;
7862 
7863         // rotated = ROR(R[m], rotation);
7864         uint64_t rotated = ROR (Rm, rotation, &success);
7865         if (!success)
7866             return false;
7867 
7868         // R[d] = SignExtend(rotated<7:0>, 32);
7869         int64_t data = llvm::SignExtend64<8>(rotated);
7870 
7871         RegisterInfo source_reg;
7872         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7873 
7874         EmulateInstruction::Context context;
7875         context.type = eContextRegisterLoad;
7876         context.SetRegister (source_reg);
7877 
7878         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7879             return false;
7880     }
7881     return true;
7882 }
7883 
7884 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7885 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7886 bool
7887 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding)
7888 {
7889 #if 0
7890     if ConditionPassed() then
7891         EncodingSpecificOperations();
7892         rotated = ROR(R[m], rotation);
7893         R[d] = SignExtend(rotated<15:0>, 32);
7894 #endif
7895 
7896     bool success = false;
7897 
7898     if (ConditionPassed(opcode))
7899     {
7900         uint32_t d;
7901         uint32_t m;
7902         uint32_t rotation;
7903 
7904         // EncodingSpecificOperations();
7905         switch (encoding)
7906         {
7907             case eEncodingT1:
7908                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7909                 d = Bits32 (opcode, 2, 0);
7910                 m = Bits32 (opcode, 5, 3);
7911                 rotation = 0;
7912 
7913                 break;
7914 
7915             case eEncodingT2:
7916                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7917                 d = Bits32 (opcode, 11, 8);
7918                 m = Bits32 (opcode, 3, 0);
7919                 rotation = Bits32 (opcode, 5, 4) << 3;
7920 
7921                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7922                 if (BadReg (d) || BadReg (m))
7923                     return false;
7924 
7925                 break;
7926 
7927             case eEncodingA1:
7928                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7929                 d = Bits32 (opcode, 15, 12);
7930                 m = Bits32 (opcode, 3, 0);
7931                 rotation = Bits32 (opcode, 11, 10) << 3;
7932 
7933                 // if d == 15 || m == 15 then UNPREDICTABLE;
7934                 if ((d == 15) || (m == 15))
7935                     return false;
7936 
7937                 break;
7938 
7939             default:
7940                 return false;
7941         }
7942 
7943         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7944         if (!success)
7945             return false;
7946 
7947         // rotated = ROR(R[m], rotation);
7948         uint64_t rotated = ROR (Rm, rotation, &success);
7949         if (!success)
7950             return false;
7951 
7952         // R[d] = SignExtend(rotated<15:0>, 32);
7953         RegisterInfo source_reg;
7954         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7955 
7956         EmulateInstruction::Context context;
7957         context.type = eContextRegisterLoad;
7958         context.SetRegister (source_reg);
7959 
7960         int64_t data = llvm::SignExtend64<16> (rotated);
7961         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7962             return false;
7963     }
7964 
7965     return true;
7966 }
7967 
7968 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination
7969 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7970 bool
7971 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding)
7972 {
7973 #if 0
7974     if ConditionPassed() then
7975         EncodingSpecificOperations();
7976         rotated = ROR(R[m], rotation);
7977         R[d] = ZeroExtend(rotated<7:0>, 32);
7978 #endif
7979 
7980     bool success = false;
7981 
7982     if (ConditionPassed(opcode))
7983     {
7984         uint32_t d;
7985         uint32_t m;
7986         uint32_t rotation;
7987 
7988         // EncodingSpecificOperations();
7989         switch (encoding)
7990         {
7991             case eEncodingT1:
7992                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7993                 d = Bits32 (opcode, 2, 0);
7994                 m = Bits32 (opcode, 5, 3);
7995                 rotation = 0;
7996 
7997                 break;
7998 
7999             case eEncodingT2:
8000                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8001                 d = Bits32 (opcode, 11, 8);
8002                 m = Bits32 (opcode, 3, 0);
8003                   rotation = Bits32 (opcode, 5, 4) << 3;
8004 
8005                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8006                 if (BadReg (d) || BadReg (m))
8007                   return false;
8008 
8009                 break;
8010 
8011             case eEncodingA1:
8012                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8013                 d = Bits32 (opcode, 15, 12);
8014                 m = Bits32 (opcode, 3, 0);
8015                 rotation = Bits32 (opcode, 11, 10) << 3;
8016 
8017                 // if d == 15 || m == 15 then UNPREDICTABLE;
8018                 if ((d == 15) || (m == 15))
8019                     return false;
8020 
8021                 break;
8022 
8023             default:
8024                 return false;
8025         }
8026 
8027         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8028         if (!success)
8029             return false;
8030 
8031         // rotated = ROR(R[m], rotation);
8032         uint64_t rotated = ROR (Rm, rotation, &success);
8033         if (!success)
8034             return false;
8035 
8036         // R[d] = ZeroExtend(rotated<7:0>, 32);
8037         RegisterInfo source_reg;
8038         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8039 
8040         EmulateInstruction::Context context;
8041         context.type = eContextRegisterLoad;
8042         context.SetRegister (source_reg);
8043 
8044         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0)))
8045             return false;
8046     }
8047     return true;
8048 }
8049 
8050 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination
8051 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
8052 bool
8053 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding)
8054 {
8055 #if 0
8056     if ConditionPassed() then
8057         EncodingSpecificOperations();
8058         rotated = ROR(R[m], rotation);
8059         R[d] = ZeroExtend(rotated<15:0>, 32);
8060 #endif
8061 
8062     bool success = false;
8063 
8064     if (ConditionPassed(opcode))
8065     {
8066         uint32_t d;
8067         uint32_t m;
8068         uint32_t rotation;
8069 
8070         switch (encoding)
8071         {
8072             case eEncodingT1:
8073                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8074                 d = Bits32 (opcode, 2, 0);
8075                 m = Bits32 (opcode, 5, 3);
8076                 rotation = 0;
8077 
8078                 break;
8079 
8080             case eEncodingT2:
8081                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8082                 d = Bits32 (opcode, 11, 8);
8083                 m = Bits32 (opcode, 3, 0);
8084                 rotation = Bits32 (opcode, 5, 4) << 3;
8085 
8086                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8087                 if (BadReg (d) || BadReg (m))
8088                   return false;
8089 
8090                 break;
8091 
8092             case eEncodingA1:
8093                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8094                 d = Bits32 (opcode, 15, 12);
8095                 m = Bits32 (opcode, 3, 0);
8096                 rotation = Bits32 (opcode, 11, 10) << 3;
8097 
8098                 // if d == 15 || m == 15 then UNPREDICTABLE;
8099                 if ((d == 15) || (m == 15))
8100                     return false;
8101 
8102                 break;
8103 
8104             default:
8105                 return false;
8106         }
8107 
8108         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8109         if (!success)
8110             return false;
8111 
8112         // rotated = ROR(R[m], rotation);
8113         uint64_t rotated = ROR (Rm, rotation, &success);
8114         if (!success)
8115             return false;
8116 
8117         // R[d] = ZeroExtend(rotated<15:0>, 32);
8118         RegisterInfo source_reg;
8119         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8120 
8121         EmulateInstruction::Context context;
8122         context.type = eContextRegisterLoad;
8123         context.SetRegister (source_reg);
8124 
8125         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0)))
8126             return false;
8127     }
8128     return true;
8129 }
8130 
8131 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following
8132 // word respectively.
8133 bool
8134 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding)
8135 {
8136 #if 0
8137     if ConditionPassed() then
8138         EncodingSpecificOperations();
8139         if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8140             UNPREDICTABLE;
8141         else
8142             address = if increment then R[n] else R[n]-8;
8143             if wordhigher then address = address+4;
8144             CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8145             BranchWritePC(MemA[address,4]);
8146             if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8147 #endif
8148 
8149     bool success = false;
8150 
8151     if (ConditionPassed(opcode))
8152     {
8153         uint32_t n;
8154         bool wback;
8155         bool increment;
8156         bool wordhigher;
8157 
8158         // EncodingSpecificOperations();
8159         switch (encoding)
8160         {
8161             case eEncodingT1:
8162                 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE;
8163                 n = Bits32 (opcode, 19, 16);
8164                 wback = BitIsSet (opcode, 21);
8165                 increment = false;
8166                 wordhigher = false;
8167 
8168                 // if n == 15 then UNPREDICTABLE;
8169                 if (n == 15)
8170                     return false;
8171 
8172                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8173                 if (InITBlock() && !LastInITBlock())
8174                     return false;
8175 
8176                 break;
8177 
8178             case eEncodingT2:
8179                 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8180                 n = Bits32 (opcode, 19, 16);
8181                 wback = BitIsSet (opcode, 21);
8182                 increment = true;
8183                 wordhigher = false;
8184 
8185                 // if n == 15 then UNPREDICTABLE;
8186                 if (n == 15)
8187                     return false;
8188 
8189                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8190                 if (InITBlock() && !LastInITBlock())
8191                     return false;
8192 
8193                 break;
8194 
8195             case eEncodingA1:
8196                 // n = UInt(Rn);
8197                 n = Bits32 (opcode, 19, 16);
8198 
8199                 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8200                 wback = BitIsSet (opcode, 21);
8201                 increment = BitIsSet (opcode, 23);
8202                 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23));
8203 
8204                 // if n == 15 then UNPREDICTABLE;
8205                 if (n == 15)
8206                     return false;
8207 
8208                 break;
8209 
8210             default:
8211                 return false;
8212         }
8213 
8214         // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8215         if (!CurrentModeIsPrivileged ())
8216             // UNPREDICTABLE;
8217             return false;
8218         else
8219         {
8220             uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8221             if (!success)
8222                 return false;
8223 
8224             addr_t address;
8225             // address = if increment then R[n] else R[n]-8;
8226             if (increment)
8227                 address = Rn;
8228             else
8229                 address = Rn - 8;
8230 
8231             // if wordhigher then address = address+4;
8232             if (wordhigher)
8233                 address = address + 4;
8234 
8235             // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8236             RegisterInfo base_reg;
8237             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8238 
8239             EmulateInstruction::Context context;
8240             context.type = eContextReturnFromException;
8241             context.SetRegisterPlusOffset (base_reg, address - Rn);
8242 
8243             uint64_t data = MemARead (context, address + 4, 4, 0, &success);
8244             if (!success)
8245                 return false;
8246 
8247             CPSRWriteByInstr (data, 15, true);
8248 
8249             // BranchWritePC(MemA[address,4]);
8250             uint64_t data2 = MemARead (context, address, 4, 0, &success);
8251             if (!success)
8252                 return false;
8253 
8254             BranchWritePC (context, data2);
8255 
8256             // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8257             if (wback)
8258             {
8259                 context.type = eContextAdjustBaseRegister;
8260                 if (increment)
8261                 {
8262                     context.SetOffset (8);
8263                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8))
8264                         return false;
8265                 }
8266                 else
8267                 {
8268                     context.SetOffset (-8);
8269                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8))
8270                         return false;
8271                 }
8272             } // if wback
8273         }
8274     } // if ConditionPassed()
8275     return true;
8276 }
8277 
8278 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
8279 // and writes the result to the destination register.  It can optionally update the condition flags based on
8280 // the result.
8281 bool
8282 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding)
8283 {
8284 #if 0
8285     // ARM pseudo code...
8286     if ConditionPassed() then
8287         EncodingSpecificOperations();
8288         result = R[n] EOR imm32;
8289         if d == 15 then         // Can only occur for ARM encoding
8290             ALUWritePC(result); // setflags is always FALSE here
8291         else
8292             R[d] = result;
8293             if setflags then
8294                 APSR.N = result<31>;
8295                 APSR.Z = IsZeroBit(result);
8296                 APSR.C = carry;
8297                 // APSR.V unchanged
8298 #endif
8299 
8300     bool success = false;
8301 
8302     if (ConditionPassed(opcode))
8303     {
8304         uint32_t Rd, Rn;
8305         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8306         bool setflags;
8307         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8308         switch (encoding)
8309         {
8310         case eEncodingT1:
8311             Rd = Bits32(opcode, 11, 8);
8312             Rn = Bits32(opcode, 19, 16);
8313             setflags = BitIsSet(opcode, 20);
8314             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8315             // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8316             if (Rd == 15 && setflags)
8317                 return EmulateTEQImm (opcode, eEncodingT1);
8318             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8319                 return false;
8320             break;
8321         case eEncodingA1:
8322             Rd = Bits32(opcode, 15, 12);
8323             Rn = Bits32(opcode, 19, 16);
8324             setflags = BitIsSet(opcode, 20);
8325             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8326 
8327             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8328             if (Rd == 15 && setflags)
8329                 return EmulateSUBSPcLrEtc (opcode, encoding);
8330             break;
8331         default:
8332             return false;
8333         }
8334 
8335         // Read the first operand.
8336         uint32_t val1 = ReadCoreReg(Rn, &success);
8337         if (!success)
8338             return false;
8339 
8340         uint32_t result = val1 ^ imm32;
8341 
8342         EmulateInstruction::Context context;
8343         context.type = EmulateInstruction::eContextImmediate;
8344         context.SetNoArgs ();
8345 
8346         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8347             return false;
8348     }
8349     return true;
8350 }
8351 
8352 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an
8353 // optionally-shifted register value, and writes the result to the destination register.
8354 // It can optionally update the condition flags based on the result.
8355 bool
8356 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding)
8357 {
8358 #if 0
8359     // ARM pseudo code...
8360     if ConditionPassed() then
8361         EncodingSpecificOperations();
8362         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8363         result = R[n] EOR shifted;
8364         if d == 15 then         // Can only occur for ARM encoding
8365             ALUWritePC(result); // setflags is always FALSE here
8366         else
8367             R[d] = result;
8368             if setflags then
8369                 APSR.N = result<31>;
8370                 APSR.Z = IsZeroBit(result);
8371                 APSR.C = carry;
8372                 // APSR.V unchanged
8373 #endif
8374 
8375     bool success = false;
8376 
8377     if (ConditionPassed(opcode))
8378     {
8379         uint32_t Rd, Rn, Rm;
8380         ARM_ShifterType shift_t;
8381         uint32_t shift_n; // the shift applied to the value read from Rm
8382         bool setflags;
8383         uint32_t carry;
8384         switch (encoding)
8385         {
8386         case eEncodingT1:
8387             Rd = Rn = Bits32(opcode, 2, 0);
8388             Rm = Bits32(opcode, 5, 3);
8389             setflags = !InITBlock();
8390             shift_t = SRType_LSL;
8391             shift_n = 0;
8392             break;
8393         case eEncodingT2:
8394             Rd = Bits32(opcode, 11, 8);
8395             Rn = Bits32(opcode, 19, 16);
8396             Rm = Bits32(opcode, 3, 0);
8397             setflags = BitIsSet(opcode, 20);
8398             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8399             // if Rd == '1111' && S == '1' then SEE TEQ (register);
8400             if (Rd == 15 && setflags)
8401                 return EmulateTEQReg (opcode, eEncodingT1);
8402             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8403                 return false;
8404             break;
8405         case eEncodingA1:
8406             Rd = Bits32(opcode, 15, 12);
8407             Rn = Bits32(opcode, 19, 16);
8408             Rm = Bits32(opcode, 3, 0);
8409             setflags = BitIsSet(opcode, 20);
8410             shift_n = DecodeImmShiftARM(opcode, shift_t);
8411 
8412             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8413             if (Rd == 15 && setflags)
8414                 return EmulateSUBSPcLrEtc (opcode, encoding);
8415             break;
8416         default:
8417             return false;
8418         }
8419 
8420         // Read the first operand.
8421         uint32_t val1 = ReadCoreReg(Rn, &success);
8422         if (!success)
8423             return false;
8424 
8425         // Read the second operand.
8426         uint32_t val2 = ReadCoreReg(Rm, &success);
8427         if (!success)
8428             return false;
8429 
8430         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8431         if (!success)
8432             return false;
8433         uint32_t result = val1 ^ shifted;
8434 
8435         EmulateInstruction::Context context;
8436         context.type = EmulateInstruction::eContextImmediate;
8437         context.SetNoArgs ();
8438 
8439         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8440             return false;
8441     }
8442     return true;
8443 }
8444 
8445 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and
8446 // writes the result to the destination register.  It can optionally update the condition flags based
8447 // on the result.
8448 bool
8449 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding)
8450 {
8451 #if 0
8452     // ARM pseudo code...
8453     if ConditionPassed() then
8454         EncodingSpecificOperations();
8455         result = R[n] OR imm32;
8456         if d == 15 then         // Can only occur for ARM encoding
8457             ALUWritePC(result); // setflags is always FALSE here
8458         else
8459             R[d] = result;
8460             if setflags then
8461                 APSR.N = result<31>;
8462                 APSR.Z = IsZeroBit(result);
8463                 APSR.C = carry;
8464                 // APSR.V unchanged
8465 #endif
8466 
8467     bool success = false;
8468 
8469     if (ConditionPassed(opcode))
8470     {
8471         uint32_t Rd, Rn;
8472         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8473         bool setflags;
8474         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8475         switch (encoding)
8476         {
8477         case eEncodingT1:
8478             Rd = Bits32(opcode, 11, 8);
8479             Rn = Bits32(opcode, 19, 16);
8480             setflags = BitIsSet(opcode, 20);
8481             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8482             // if Rn == '1111' then SEE MOV (immediate);
8483             if (Rn == 15)
8484                 return EmulateMOVRdImm (opcode, eEncodingT2);
8485             if (BadReg(Rd) || Rn == 13)
8486                 return false;
8487             break;
8488         case eEncodingA1:
8489             Rd = Bits32(opcode, 15, 12);
8490             Rn = Bits32(opcode, 19, 16);
8491             setflags = BitIsSet(opcode, 20);
8492             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8493 
8494             if (Rd == 15 && setflags)
8495                 return EmulateSUBSPcLrEtc (opcode, encoding);
8496             break;
8497         default:
8498             return false;
8499         }
8500 
8501         // Read the first operand.
8502         uint32_t val1 = ReadCoreReg(Rn, &success);
8503         if (!success)
8504             return false;
8505 
8506         uint32_t result = val1 | imm32;
8507 
8508         EmulateInstruction::Context context;
8509         context.type = EmulateInstruction::eContextImmediate;
8510         context.SetNoArgs ();
8511 
8512         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8513             return false;
8514     }
8515     return true;
8516 }
8517 
8518 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register
8519 // value, and writes the result to the destination register.  It can optionally update the condition flags based
8520 // on the result.
8521 bool
8522 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding)
8523 {
8524 #if 0
8525     // ARM pseudo code...
8526     if ConditionPassed() then
8527         EncodingSpecificOperations();
8528         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8529         result = R[n] OR shifted;
8530         if d == 15 then         // Can only occur for ARM encoding
8531             ALUWritePC(result); // setflags is always FALSE here
8532         else
8533             R[d] = result;
8534             if setflags then
8535                 APSR.N = result<31>;
8536                 APSR.Z = IsZeroBit(result);
8537                 APSR.C = carry;
8538                 // APSR.V unchanged
8539 #endif
8540 
8541     bool success = false;
8542 
8543     if (ConditionPassed(opcode))
8544     {
8545         uint32_t Rd, Rn, Rm;
8546         ARM_ShifterType shift_t;
8547         uint32_t shift_n; // the shift applied to the value read from Rm
8548         bool setflags;
8549         uint32_t carry;
8550         switch (encoding)
8551         {
8552         case eEncodingT1:
8553             Rd = Rn = Bits32(opcode, 2, 0);
8554             Rm = Bits32(opcode, 5, 3);
8555             setflags = !InITBlock();
8556             shift_t = SRType_LSL;
8557             shift_n = 0;
8558             break;
8559         case eEncodingT2:
8560             Rd = Bits32(opcode, 11, 8);
8561             Rn = Bits32(opcode, 19, 16);
8562             Rm = Bits32(opcode, 3, 0);
8563             setflags = BitIsSet(opcode, 20);
8564             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8565             // if Rn == '1111' then SEE MOV (register);
8566             if (Rn == 15)
8567                 return EmulateMOVRdRm (opcode, eEncodingT3);
8568             if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
8569                 return false;
8570             break;
8571         case eEncodingA1:
8572             Rd = Bits32(opcode, 15, 12);
8573             Rn = Bits32(opcode, 19, 16);
8574             Rm = Bits32(opcode, 3, 0);
8575             setflags = BitIsSet(opcode, 20);
8576             shift_n = DecodeImmShiftARM(opcode, shift_t);
8577 
8578             if (Rd == 15 && setflags)
8579                 return EmulateSUBSPcLrEtc (opcode, encoding);
8580             break;
8581         default:
8582             return false;
8583         }
8584 
8585         // Read the first operand.
8586         uint32_t val1 = ReadCoreReg(Rn, &success);
8587         if (!success)
8588             return false;
8589 
8590         // Read the second operand.
8591         uint32_t val2 = ReadCoreReg(Rm, &success);
8592         if (!success)
8593             return false;
8594 
8595         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8596         if (!success)
8597             return false;
8598         uint32_t result = val1 | shifted;
8599 
8600         EmulateInstruction::Context context;
8601         context.type = EmulateInstruction::eContextImmediate;
8602         context.SetNoArgs ();
8603 
8604         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8605             return false;
8606     }
8607     return true;
8608 }
8609 
8610 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to
8611 // the destination register. It can optionally update the condition flags based on the result.
8612 bool
8613 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding)
8614 {
8615 #if 0
8616     // ARM pseudo code...
8617     if ConditionPassed() then
8618         EncodingSpecificOperations();
8619         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
8620         if d == 15 then         // Can only occur for ARM encoding
8621             ALUWritePC(result); // setflags is always FALSE here
8622         else
8623             R[d] = result;
8624             if setflags then
8625                 APSR.N = result<31>;
8626                 APSR.Z = IsZeroBit(result);
8627                 APSR.C = carry;
8628                 APSR.V = overflow;
8629 #endif
8630 
8631     bool success = false;
8632 
8633     uint32_t Rd; // the destination register
8634     uint32_t Rn; // the first operand
8635     bool setflags;
8636     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8637     switch (encoding) {
8638     case eEncodingT1:
8639         Rd = Bits32(opcode, 2, 0);
8640         Rn = Bits32(opcode, 5, 3);
8641         setflags = !InITBlock();
8642         imm32 = 0;
8643         break;
8644     case eEncodingT2:
8645         Rd = Bits32(opcode, 11, 8);
8646         Rn = Bits32(opcode, 19, 16);
8647         setflags = BitIsSet(opcode, 20);
8648         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8649         if (BadReg(Rd) || BadReg(Rn))
8650             return false;
8651         break;
8652     case eEncodingA1:
8653         Rd = Bits32(opcode, 15, 12);
8654         Rn = Bits32(opcode, 19, 16);
8655         setflags = BitIsSet(opcode, 20);
8656         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8657 
8658         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8659         if (Rd == 15 && setflags)
8660             return EmulateSUBSPcLrEtc (opcode, encoding);
8661         break;
8662     default:
8663         return false;
8664     }
8665     // Read the register value from the operand register Rn.
8666     uint32_t reg_val = ReadCoreReg(Rn, &success);
8667     if (!success)
8668         return false;
8669 
8670     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
8671 
8672     EmulateInstruction::Context context;
8673     context.type = EmulateInstruction::eContextImmediate;
8674     context.SetNoArgs ();
8675 
8676     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8677         return false;
8678 
8679     return true;
8680 }
8681 
8682 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the
8683 // result to the destination register. It can optionally update the condition flags based on the result.
8684 bool
8685 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding)
8686 {
8687 #if 0
8688     // ARM pseudo code...
8689     if ConditionPassed() then
8690         EncodingSpecificOperations();
8691         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8692         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
8693         if d == 15 then         // Can only occur for ARM encoding
8694             ALUWritePC(result); // setflags is always FALSE here
8695         else
8696             R[d] = result;
8697             if setflags then
8698                 APSR.N = result<31>;
8699                 APSR.Z = IsZeroBit(result);
8700                 APSR.C = carry;
8701                 APSR.V = overflow;
8702 #endif
8703 
8704     bool success = false;
8705 
8706     uint32_t Rd; // the destination register
8707     uint32_t Rn; // the first operand
8708     uint32_t Rm; // the second operand
8709     bool setflags;
8710     ARM_ShifterType shift_t;
8711     uint32_t shift_n; // the shift applied to the value read from Rm
8712     switch (encoding) {
8713     case eEncodingT1:
8714         Rd = Bits32(opcode, 11, 8);
8715         Rn = Bits32(opcode, 19, 16);
8716         Rm = Bits32(opcode, 3, 0);
8717         setflags = BitIsSet(opcode, 20);
8718         shift_n = DecodeImmShiftThumb(opcode, shift_t);
8719         // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
8720         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8721             return false;
8722         break;
8723     case eEncodingA1:
8724         Rd = Bits32(opcode, 15, 12);
8725         Rn = Bits32(opcode, 19, 16);
8726         Rm = Bits32(opcode, 3, 0);
8727         setflags = BitIsSet(opcode, 20);
8728         shift_n = DecodeImmShiftARM(opcode, shift_t);
8729 
8730         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8731         if (Rd == 15 && setflags)
8732             return EmulateSUBSPcLrEtc (opcode, encoding);
8733         break;
8734     default:
8735         return false;
8736     }
8737     // Read the register value from register Rn.
8738     uint32_t val1 = ReadCoreReg(Rn, &success);
8739     if (!success)
8740         return false;
8741 
8742     // Read the register value from register Rm.
8743     uint32_t val2 = ReadCoreReg(Rm, &success);
8744     if (!success)
8745         return false;
8746 
8747     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8748     if (!success)
8749         return false;
8750     AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
8751 
8752     EmulateInstruction::Context context;
8753     context.type = EmulateInstruction::eContextImmediate;
8754     context.SetNoArgs();
8755     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8756         return false;
8757 
8758     return true;
8759 }
8760 
8761 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from
8762 // an immediate value, and writes the result to the destination register. It can optionally update the condition
8763 // flags based on the result.
8764 bool
8765 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding)
8766 {
8767 #if 0
8768     // ARM pseudo code...
8769     if ConditionPassed() then
8770         EncodingSpecificOperations();
8771         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
8772         if d == 15 then
8773             ALUWritePC(result); // setflags is always FALSE here
8774         else
8775             R[d] = result;
8776             if setflags then
8777                 APSR.N = result<31>;
8778                 APSR.Z = IsZeroBit(result);
8779                 APSR.C = carry;
8780                 APSR.V = overflow;
8781 #endif
8782 
8783     bool success = false;
8784 
8785     uint32_t Rd; // the destination register
8786     uint32_t Rn; // the first operand
8787     bool setflags;
8788     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8789     switch (encoding) {
8790     case eEncodingA1:
8791         Rd = Bits32(opcode, 15, 12);
8792         Rn = Bits32(opcode, 19, 16);
8793         setflags = BitIsSet(opcode, 20);
8794         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8795 
8796         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8797         if (Rd == 15 && setflags)
8798             return EmulateSUBSPcLrEtc  (opcode, encoding);
8799         break;
8800     default:
8801         return false;
8802     }
8803     // Read the register value from the operand register Rn.
8804     uint32_t reg_val = ReadCoreReg(Rn, &success);
8805     if (!success)
8806         return false;
8807 
8808     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
8809 
8810     EmulateInstruction::Context context;
8811     context.type = EmulateInstruction::eContextImmediate;
8812     context.SetNoArgs ();
8813 
8814     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8815         return false;
8816 
8817     return true;
8818 }
8819 
8820 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an
8821 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the
8822 // condition flags based on the result.
8823 bool
8824 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding)
8825 {
8826 #if 0
8827     // ARM pseudo code...
8828     if ConditionPassed() then
8829         EncodingSpecificOperations();
8830         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8831         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
8832         if d == 15 then
8833             ALUWritePC(result); // setflags is always FALSE here
8834         else
8835             R[d] = result;
8836             if setflags then
8837                 APSR.N = result<31>;
8838                 APSR.Z = IsZeroBit(result);
8839                 APSR.C = carry;
8840                 APSR.V = overflow;
8841 #endif
8842 
8843     bool success = false;
8844 
8845     uint32_t Rd; // the destination register
8846     uint32_t Rn; // the first operand
8847     uint32_t Rm; // the second operand
8848     bool setflags;
8849     ARM_ShifterType shift_t;
8850     uint32_t shift_n; // the shift applied to the value read from Rm
8851     switch (encoding) {
8852     case eEncodingA1:
8853         Rd = Bits32(opcode, 15, 12);
8854         Rn = Bits32(opcode, 19, 16);
8855         Rm = Bits32(opcode, 3, 0);
8856         setflags = BitIsSet(opcode, 20);
8857         shift_n = DecodeImmShiftARM(opcode, shift_t);
8858 
8859         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8860         if (Rd == 15 && setflags)
8861             return EmulateSUBSPcLrEtc (opcode, encoding);
8862         break;
8863     default:
8864         return false;
8865     }
8866     // Read the register value from register Rn.
8867     uint32_t val1 = ReadCoreReg(Rn, &success);
8868     if (!success)
8869         return false;
8870 
8871     // Read the register value from register Rm.
8872     uint32_t val2 = ReadCoreReg(Rm, &success);
8873     if (!success)
8874         return false;
8875 
8876     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8877     if (!success)
8878         return false;
8879     AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
8880 
8881     EmulateInstruction::Context context;
8882     context.type = EmulateInstruction::eContextImmediate;
8883     context.SetNoArgs();
8884     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8885         return false;
8886 
8887     return true;
8888 }
8889 
8890 // Subtract with Carry (immediate) subtracts an immediate value and the value of
8891 // NOT (Carry flag) from a register value, and writes the result to the destination register.
8892 // It can optionally update the condition flags based on the result.
8893 bool
8894 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding)
8895 {
8896 #if 0
8897     // ARM pseudo code...
8898     if ConditionPassed() then
8899         EncodingSpecificOperations();
8900         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
8901         if d == 15 then         // Can only occur for ARM encoding
8902             ALUWritePC(result); // setflags is always FALSE here
8903         else
8904             R[d] = result;
8905             if setflags then
8906                 APSR.N = result<31>;
8907                 APSR.Z = IsZeroBit(result);
8908                 APSR.C = carry;
8909                 APSR.V = overflow;
8910 #endif
8911 
8912     bool success = false;
8913 
8914     uint32_t Rd; // the destination register
8915     uint32_t Rn; // the first operand
8916     bool setflags;
8917     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8918     switch (encoding) {
8919     case eEncodingT1:
8920         Rd = Bits32(opcode, 11, 8);
8921         Rn = Bits32(opcode, 19, 16);
8922         setflags = BitIsSet(opcode, 20);
8923         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8924         if (BadReg(Rd) || BadReg(Rn))
8925             return false;
8926         break;
8927     case eEncodingA1:
8928         Rd = Bits32(opcode, 15, 12);
8929         Rn = Bits32(opcode, 19, 16);
8930         setflags = BitIsSet(opcode, 20);
8931         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8932 
8933         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8934         if (Rd == 15 && setflags)
8935             return EmulateSUBSPcLrEtc (opcode, encoding);
8936         break;
8937     default:
8938         return false;
8939     }
8940     // Read the register value from the operand register Rn.
8941     uint32_t reg_val = ReadCoreReg(Rn, &success);
8942     if (!success)
8943         return false;
8944 
8945     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
8946 
8947     EmulateInstruction::Context context;
8948     context.type = EmulateInstruction::eContextImmediate;
8949     context.SetNoArgs ();
8950 
8951     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8952         return false;
8953 
8954     return true;
8955 }
8956 
8957 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of
8958 // NOT (Carry flag) from a register value, and writes the result to the destination register.
8959 // It can optionally update the condition flags based on the result.
8960 bool
8961 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding)
8962 {
8963 #if 0
8964     // ARM pseudo code...
8965     if ConditionPassed() then
8966         EncodingSpecificOperations();
8967         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8968         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
8969         if d == 15 then         // Can only occur for ARM encoding
8970             ALUWritePC(result); // setflags is always FALSE here
8971         else
8972             R[d] = result;
8973             if setflags then
8974                 APSR.N = result<31>;
8975                 APSR.Z = IsZeroBit(result);
8976                 APSR.C = carry;
8977                 APSR.V = overflow;
8978 #endif
8979 
8980     bool success = false;
8981 
8982     uint32_t Rd; // the destination register
8983     uint32_t Rn; // the first operand
8984     uint32_t Rm; // the second operand
8985     bool setflags;
8986     ARM_ShifterType shift_t;
8987     uint32_t shift_n; // the shift applied to the value read from Rm
8988     switch (encoding) {
8989     case eEncodingT1:
8990         Rd = Rn = Bits32(opcode, 2, 0);
8991         Rm = Bits32(opcode, 5, 3);
8992         setflags = !InITBlock();
8993         shift_t = SRType_LSL;
8994         shift_n = 0;
8995         break;
8996     case eEncodingT2:
8997         Rd = Bits32(opcode, 11, 8);
8998         Rn = Bits32(opcode, 19, 16);
8999         Rm = Bits32(opcode, 3, 0);
9000         setflags = BitIsSet(opcode, 20);
9001         shift_n = DecodeImmShiftThumb(opcode, shift_t);
9002         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9003             return false;
9004         break;
9005     case eEncodingA1:
9006         Rd = Bits32(opcode, 15, 12);
9007         Rn = Bits32(opcode, 19, 16);
9008         Rm = Bits32(opcode, 3, 0);
9009         setflags = BitIsSet(opcode, 20);
9010         shift_n = DecodeImmShiftARM(opcode, shift_t);
9011 
9012         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9013         if (Rd == 15 && setflags)
9014             return EmulateSUBSPcLrEtc (opcode, encoding);
9015         break;
9016     default:
9017         return false;
9018     }
9019     // Read the register value from register Rn.
9020     uint32_t val1 = ReadCoreReg(Rn, &success);
9021     if (!success)
9022         return false;
9023 
9024     // Read the register value from register Rm.
9025     uint32_t val2 = ReadCoreReg(Rm, &success);
9026     if (!success)
9027         return false;
9028 
9029     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9030     if (!success)
9031         return false;
9032     AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
9033 
9034     EmulateInstruction::Context context;
9035     context.type = EmulateInstruction::eContextImmediate;
9036     context.SetNoArgs();
9037     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9038         return false;
9039 
9040     return true;
9041 }
9042 
9043 // This instruction subtracts an immediate value from a register value, and writes the result
9044 // to the destination register.  It can optionally update the condition flags based on the result.
9045 bool
9046 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding)
9047 {
9048 #if 0
9049     // ARM pseudo code...
9050     if ConditionPassed() then
9051         EncodingSpecificOperations();
9052         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9053         R[d] = result;
9054         if setflags then
9055             APSR.N = result<31>;
9056             APSR.Z = IsZeroBit(result);
9057             APSR.C = carry;
9058             APSR.V = overflow;
9059 #endif
9060 
9061     bool success = false;
9062 
9063     uint32_t Rd; // the destination register
9064     uint32_t Rn; // the first operand
9065     bool setflags;
9066     uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9067     switch (encoding) {
9068     case eEncodingT1:
9069         Rd = Bits32(opcode, 2, 0);
9070         Rn = Bits32(opcode, 5, 3);
9071         setflags = !InITBlock();
9072         imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9073         break;
9074     case eEncodingT2:
9075         Rd = Rn = Bits32(opcode, 10, 8);
9076         setflags = !InITBlock();
9077         imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9078         break;
9079     case eEncodingT3:
9080         Rd = Bits32(opcode, 11, 8);
9081         Rn = Bits32(opcode, 19, 16);
9082         setflags = BitIsSet(opcode, 20);
9083         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9084 
9085         // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9086         if (Rd == 15 && setflags)
9087             return EmulateCMPImm (opcode, eEncodingT2);
9088 
9089         // if Rn == '1101' then SEE SUB (SP minus immediate);
9090         if (Rn == 13)
9091             return EmulateSUBSPImm (opcode, eEncodingT2);
9092 
9093         // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9094         if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9095             return false;
9096         break;
9097     case eEncodingT4:
9098         Rd = Bits32(opcode, 11, 8);
9099         Rn = Bits32(opcode, 19, 16);
9100         setflags = BitIsSet(opcode, 20);
9101         imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9102 
9103         // if Rn == '1111' then SEE ADR;
9104         if (Rn == 15)
9105             return EmulateADR (opcode, eEncodingT2);
9106 
9107         // if Rn == '1101' then SEE SUB (SP minus immediate);
9108         if (Rn == 13)
9109             return EmulateSUBSPImm (opcode, eEncodingT3);
9110 
9111         if (BadReg(Rd))
9112             return false;
9113         break;
9114     default:
9115         return false;
9116     }
9117     // Read the register value from the operand register Rn.
9118     uint32_t reg_val = ReadCoreReg(Rn, &success);
9119     if (!success)
9120         return false;
9121 
9122     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9123 
9124     EmulateInstruction::Context context;
9125     context.type = EmulateInstruction::eContextImmediate;
9126     context.SetNoArgs ();
9127 
9128     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9129         return false;
9130 
9131     return true;
9132 }
9133 
9134 // This instruction subtracts an immediate value from a register value, and writes the result
9135 // to the destination register.  It can optionally update the condition flags based on the result.
9136 bool
9137 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9138 {
9139 #if 0
9140     // ARM pseudo code...
9141     if ConditionPassed() then
9142         EncodingSpecificOperations();
9143         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9144         if d == 15 then
9145             ALUWritePC(result); // setflags is always FALSE here
9146         else
9147             R[d] = result;
9148             if setflags then
9149                 APSR.N = result<31>;
9150                 APSR.Z = IsZeroBit(result);
9151                 APSR.C = carry;
9152                 APSR.V = overflow;
9153 #endif
9154 
9155     bool success = false;
9156 
9157     uint32_t Rd; // the destination register
9158     uint32_t Rn; // the first operand
9159     bool setflags;
9160     uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9161     switch (encoding) {
9162     case eEncodingA1:
9163         Rd = Bits32(opcode, 15, 12);
9164         Rn = Bits32(opcode, 19, 16);
9165         setflags = BitIsSet(opcode, 20);
9166         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9167 
9168         // if Rn == '1111' && S == '0' then SEE ADR;
9169         if (Rn == 15 && !setflags)
9170             return EmulateADR (opcode, eEncodingA2);
9171 
9172         // if Rn == '1101' then SEE SUB (SP minus immediate);
9173         if (Rn == 13)
9174             return EmulateSUBSPImm (opcode, eEncodingA1);
9175 
9176         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9177         if (Rd == 15 && setflags)
9178             return EmulateSUBSPcLrEtc (opcode, encoding);
9179         break;
9180     default:
9181         return false;
9182     }
9183     // Read the register value from the operand register Rn.
9184     uint32_t reg_val = ReadCoreReg(Rn, &success);
9185     if (!success)
9186         return false;
9187 
9188     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9189 
9190     EmulateInstruction::Context context;
9191     context.type = EmulateInstruction::eContextImmediate;
9192     context.SetNoArgs ();
9193 
9194     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9195         return false;
9196 
9197     return true;
9198 }
9199 
9200 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an
9201 // immediate value.  It updates the condition flags based on the result, and discards the result.
9202 bool
9203 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding)
9204 {
9205 #if 0
9206     // ARM pseudo code...
9207     if ConditionPassed() then
9208         EncodingSpecificOperations();
9209         result = R[n] EOR imm32;
9210         APSR.N = result<31>;
9211         APSR.Z = IsZeroBit(result);
9212         APSR.C = carry;
9213         // APSR.V unchanged
9214 #endif
9215 
9216     bool success = false;
9217 
9218     if (ConditionPassed(opcode))
9219     {
9220         uint32_t Rn;
9221         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9222         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9223         switch (encoding)
9224         {
9225         case eEncodingT1:
9226             Rn = Bits32(opcode, 19, 16);
9227             imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9228             if (BadReg(Rn))
9229                 return false;
9230             break;
9231         case eEncodingA1:
9232             Rn = Bits32(opcode, 19, 16);
9233             imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9234             break;
9235         default:
9236             return false;
9237         }
9238 
9239         // Read the first operand.
9240         uint32_t val1 = ReadCoreReg(Rn, &success);
9241         if (!success)
9242             return false;
9243 
9244         uint32_t result = val1 ^ imm32;
9245 
9246         EmulateInstruction::Context context;
9247         context.type = EmulateInstruction::eContextImmediate;
9248         context.SetNoArgs ();
9249 
9250         if (!WriteFlags(context, result, carry))
9251             return false;
9252     }
9253     return true;
9254 }
9255 
9256 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an
9257 // optionally-shifted register value.  It updates the condition flags based on the result, and discards
9258 // the result.
9259 bool
9260 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding)
9261 {
9262 #if 0
9263     // ARM pseudo code...
9264     if ConditionPassed() then
9265         EncodingSpecificOperations();
9266         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9267         result = R[n] EOR shifted;
9268         APSR.N = result<31>;
9269         APSR.Z = IsZeroBit(result);
9270         APSR.C = carry;
9271         // APSR.V unchanged
9272 #endif
9273 
9274     bool success = false;
9275 
9276     if (ConditionPassed(opcode))
9277     {
9278         uint32_t Rn, Rm;
9279         ARM_ShifterType shift_t;
9280         uint32_t shift_n; // the shift applied to the value read from Rm
9281         uint32_t carry;
9282         switch (encoding)
9283         {
9284         case eEncodingT1:
9285             Rn = Bits32(opcode, 19, 16);
9286             Rm = Bits32(opcode, 3, 0);
9287             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9288             if (BadReg(Rn) || BadReg(Rm))
9289                 return false;
9290             break;
9291         case eEncodingA1:
9292             Rn = Bits32(opcode, 19, 16);
9293             Rm = Bits32(opcode, 3, 0);
9294             shift_n = DecodeImmShiftARM(opcode, shift_t);
9295             break;
9296         default:
9297             return false;
9298         }
9299 
9300         // Read the first operand.
9301         uint32_t val1 = ReadCoreReg(Rn, &success);
9302         if (!success)
9303             return false;
9304 
9305         // Read the second operand.
9306         uint32_t val2 = ReadCoreReg(Rm, &success);
9307         if (!success)
9308             return false;
9309 
9310         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9311         if (!success)
9312             return false;
9313         uint32_t result = val1 ^ shifted;
9314 
9315         EmulateInstruction::Context context;
9316         context.type = EmulateInstruction::eContextImmediate;
9317         context.SetNoArgs ();
9318 
9319         if (!WriteFlags(context, result, carry))
9320             return false;
9321     }
9322     return true;
9323 }
9324 
9325 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value.
9326 // It updates the condition flags based on the result, and discards the result.
9327 bool
9328 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding)
9329 {
9330 #if 0
9331     // ARM pseudo code...
9332     if ConditionPassed() then
9333         EncodingSpecificOperations();
9334         result = R[n] AND imm32;
9335         APSR.N = result<31>;
9336         APSR.Z = IsZeroBit(result);
9337         APSR.C = carry;
9338         // APSR.V unchanged
9339 #endif
9340 
9341     bool success = false;
9342 
9343     if (ConditionPassed(opcode))
9344     {
9345         uint32_t Rn;
9346         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9347         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9348         switch (encoding)
9349         {
9350         case eEncodingT1:
9351             Rn = Bits32(opcode, 19, 16);
9352             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9353             if (BadReg(Rn))
9354                 return false;
9355             break;
9356         case eEncodingA1:
9357             Rn = Bits32(opcode, 19, 16);
9358             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9359             break;
9360         default:
9361             return false;
9362         }
9363 
9364         // Read the first operand.
9365         uint32_t val1 = ReadCoreReg(Rn, &success);
9366         if (!success)
9367             return false;
9368 
9369         uint32_t result = val1 & imm32;
9370 
9371         EmulateInstruction::Context context;
9372         context.type = EmulateInstruction::eContextImmediate;
9373         context.SetNoArgs ();
9374 
9375         if (!WriteFlags(context, result, carry))
9376             return false;
9377     }
9378     return true;
9379 }
9380 
9381 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value.
9382 // It updates the condition flags based on the result, and discards the result.
9383 bool
9384 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding)
9385 {
9386 #if 0
9387     // ARM pseudo code...
9388     if ConditionPassed() then
9389         EncodingSpecificOperations();
9390         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9391         result = R[n] AND shifted;
9392         APSR.N = result<31>;
9393         APSR.Z = IsZeroBit(result);
9394         APSR.C = carry;
9395         // APSR.V unchanged
9396 #endif
9397 
9398     bool success = false;
9399 
9400     if (ConditionPassed(opcode))
9401     {
9402         uint32_t Rn, Rm;
9403         ARM_ShifterType shift_t;
9404         uint32_t shift_n; // the shift applied to the value read from Rm
9405         uint32_t carry;
9406         switch (encoding)
9407         {
9408         case eEncodingT1:
9409             Rn = Bits32(opcode, 2, 0);
9410             Rm = Bits32(opcode, 5, 3);
9411             shift_t = SRType_LSL;
9412             shift_n = 0;
9413             break;
9414         case eEncodingT2:
9415             Rn = Bits32(opcode, 19, 16);
9416             Rm = Bits32(opcode, 3, 0);
9417             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9418             if (BadReg(Rn) || BadReg(Rm))
9419                 return false;
9420             break;
9421         case eEncodingA1:
9422             Rn = Bits32(opcode, 19, 16);
9423             Rm = Bits32(opcode, 3, 0);
9424             shift_n = DecodeImmShiftARM(opcode, shift_t);
9425             break;
9426         default:
9427             return false;
9428         }
9429 
9430         // Read the first operand.
9431         uint32_t val1 = ReadCoreReg(Rn, &success);
9432         if (!success)
9433             return false;
9434 
9435         // Read the second operand.
9436         uint32_t val2 = ReadCoreReg(Rm, &success);
9437         if (!success)
9438             return false;
9439 
9440         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9441         if (!success)
9442             return false;
9443         uint32_t result = val1 & shifted;
9444 
9445         EmulateInstruction::Context context;
9446         context.type = EmulateInstruction::eContextImmediate;
9447         context.SetNoArgs ();
9448 
9449         if (!WriteFlags(context, result, carry))
9450             return false;
9451     }
9452     return true;
9453 }
9454 
9455 // A8.6.216 SUB (SP minus register)
9456 bool
9457 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding)
9458 {
9459 #if 0
9460     if ConditionPassed() then
9461         EncodingSpecificOperations();
9462         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9463         (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9464         if d == 15 then // Can only occur for ARM encoding
9465             ALUWritePC(result); // setflags is always FALSE here
9466         else
9467             R[d] = result;
9468             if setflags then
9469                 APSR.N = result<31>;
9470                 APSR.Z = IsZeroBit(result);
9471                 APSR.C = carry;
9472                 APSR.V = overflow;
9473 #endif
9474 
9475     bool success = false;
9476 
9477     if (ConditionPassed(opcode))
9478     {
9479         uint32_t d;
9480         uint32_t m;
9481         bool setflags;
9482         ARM_ShifterType shift_t;
9483         uint32_t shift_n;
9484 
9485         switch (encoding)
9486         {
9487             case eEncodingT1:
9488                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9489                 d = Bits32 (opcode, 11, 8);
9490                 m = Bits32 (opcode, 3, 0);
9491                 setflags = BitIsSet (opcode, 20);
9492 
9493                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9494                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9495 
9496                 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE;
9497                 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
9498                     return false;
9499 
9500                 // if d == 15 || BadReg(m) then UNPREDICTABLE;
9501                 if ((d == 15) || BadReg (m))
9502                     return false;
9503                 break;
9504 
9505             case eEncodingA1:
9506                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9507                 d = Bits32 (opcode, 15, 12);
9508                 m = Bits32 (opcode, 3, 0);
9509                 setflags = BitIsSet (opcode, 20);
9510 
9511                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9512                 if (d == 15 && setflags)
9513                     EmulateSUBSPcLrEtc (opcode, encoding);
9514 
9515                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9516                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9517                 break;
9518 
9519             default:
9520                 return false;
9521         }
9522 
9523         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9524         uint32_t Rm = ReadCoreReg (m, &success);
9525         if (!success)
9526             return false;
9527 
9528         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9529         if (!success)
9530             return false;
9531 
9532         // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9533         uint32_t sp_val = ReadCoreReg (SP_REG, &success);
9534         if (!success)
9535             return false;
9536 
9537         AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1);
9538 
9539         EmulateInstruction::Context context;
9540         context.type = eContextArithmetic;
9541         RegisterInfo sp_reg;
9542         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
9543         RegisterInfo dwarf_reg;
9544         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
9545         context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
9546 
9547         if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9548             return false;
9549     }
9550     return true;
9551 }
9552 
9553 
9554 // A8.6.7 ADD (register-shifted register)
9555 bool
9556 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding)
9557 {
9558 #if 0
9559     if ConditionPassed() then
9560         EncodingSpecificOperations();
9561         shift_n = UInt(R[s]<7:0>);
9562         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9563         (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9564         R[d] = result;
9565         if setflags then
9566             APSR.N = result<31>;
9567             APSR.Z = IsZeroBit(result);
9568             APSR.C = carry;
9569             APSR.V = overflow;
9570 #endif
9571 
9572     bool success = false;
9573 
9574     if (ConditionPassed(opcode))
9575     {
9576         uint32_t d;
9577         uint32_t n;
9578         uint32_t m;
9579         uint32_t s;
9580         bool setflags;
9581         ARM_ShifterType shift_t;
9582 
9583         switch (encoding)
9584         {
9585             case eEncodingA1:
9586                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
9587                 d = Bits32 (opcode, 15, 12);
9588                 n = Bits32 (opcode, 19, 16);
9589                 m = Bits32 (opcode, 3, 0);
9590                 s = Bits32 (opcode, 11, 8);
9591 
9592                 // setflags = (S == �1�); shift_t = DecodeRegShift(type);
9593                 setflags = BitIsSet (opcode, 20);
9594                 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5));
9595 
9596                 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
9597                 if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
9598                     return false;
9599                 break;
9600 
9601             default:
9602                 return false;
9603         }
9604 
9605         // shift_n = UInt(R[s]<7:0>);
9606         uint32_t Rs = ReadCoreReg (s, &success);
9607         if (!success)
9608             return false;
9609 
9610         uint32_t shift_n = Bits32 (Rs, 7, 0);
9611 
9612         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9613         uint32_t Rm = ReadCoreReg (m, &success);
9614         if (!success)
9615             return false;
9616 
9617         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9618         if (!success)
9619             return false;
9620 
9621         // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9622         uint32_t Rn = ReadCoreReg (n, &success);
9623         if (!success)
9624             return false;
9625 
9626         AddWithCarryResult res = AddWithCarry (Rn, shifted, 0);
9627 
9628         // R[d] = result;
9629         EmulateInstruction::Context context;
9630         context.type = eContextArithmetic;
9631         RegisterInfo reg_n;
9632         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9633         RegisterInfo reg_m;
9634         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9635 
9636         context.SetRegisterRegisterOperands (reg_n, reg_m);
9637 
9638         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result))
9639             return false;
9640 
9641         // if setflags then
9642             // APSR.N = result<31>;
9643             // APSR.Z = IsZeroBit(result);
9644             // APSR.C = carry;
9645             // APSR.V = overflow;
9646         if (setflags)
9647             return WriteFlags (context, res.result, res.carry_out, res.overflow);
9648     }
9649     return true;
9650 }
9651 
9652 // A8.6.213 SUB (register)
9653 bool
9654 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding)
9655 {
9656 #if 0
9657     if ConditionPassed() then
9658         EncodingSpecificOperations();
9659         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9660         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9661         if d == 15 then // Can only occur for ARM encoding
9662             ALUWritePC(result); // setflags is always FALSE here
9663         else
9664             R[d] = result;
9665             if setflags then
9666                 APSR.N = result<31>;
9667                 APSR.Z = IsZeroBit(result);
9668                 APSR.C = carry;
9669                 APSR.V = overflow;
9670 #endif
9671 
9672     bool success = false;
9673 
9674     if (ConditionPassed(opcode))
9675     {
9676         uint32_t d;
9677         uint32_t n;
9678         uint32_t m;
9679         bool setflags;
9680         ARM_ShifterType shift_t;
9681         uint32_t shift_n;
9682 
9683         switch (encoding)
9684         {
9685             case eEncodingT1:
9686                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
9687                 d = Bits32 (opcode, 2, 0);
9688                 n = Bits32 (opcode, 5, 3);
9689                 m = Bits32 (opcode, 8, 6);
9690                 setflags = !InITBlock();
9691 
9692                 // (shift_t, shift_n) = (SRType_LSL, 0);
9693                 shift_t = SRType_LSL;
9694                 shift_n = 0;
9695 
9696                 break;
9697 
9698             case eEncodingT2:
9699                 // if Rd == �1111� && S == �1� then SEE CMP (register);
9700                 // if Rn == �1101� then SEE SUB (SP minus register);
9701                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9702                 d = Bits32 (opcode, 11, 8);
9703                 n = Bits32 (opcode, 19, 16);
9704                 m = Bits32 (opcode, 3, 0);
9705                 setflags = BitIsSet (opcode, 20);
9706 
9707                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9708                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9709 
9710                 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE;
9711                 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m))
9712                     return false;
9713 
9714                 break;
9715 
9716             case eEncodingA1:
9717                 // if Rn == �1101� then SEE SUB (SP minus register);
9718                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9719                 d = Bits32 (opcode, 15, 12);
9720                 n = Bits32 (opcode, 19, 16);
9721                 m = Bits32 (opcode, 3, 0);
9722                 setflags = BitIsSet (opcode, 20);
9723 
9724                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9725                 if ((d == 15) && setflags)
9726                     EmulateSUBSPcLrEtc (opcode, encoding);
9727 
9728                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9729                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9730 
9731                 break;
9732 
9733             default:
9734                 return false;
9735         }
9736 
9737         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9738         uint32_t Rm = ReadCoreReg (m, &success);
9739         if (!success)
9740             return false;
9741 
9742         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9743         if (!success)
9744             return false;
9745 
9746         // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9747         uint32_t Rn = ReadCoreReg (n, &success);
9748         if (!success)
9749             return false;
9750 
9751         AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1);
9752 
9753         // if d == 15 then // Can only occur for ARM encoding
9754             // ALUWritePC(result); // setflags is always FALSE here
9755         // else
9756             // R[d] = result;
9757             // if setflags then
9758                 // APSR.N = result<31>;
9759                 // APSR.Z = IsZeroBit(result);
9760                 // APSR.C = carry;
9761                 // APSR.V = overflow;
9762 
9763         EmulateInstruction::Context context;
9764         context.type = eContextArithmetic;
9765         RegisterInfo reg_n;
9766         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9767         RegisterInfo reg_m;
9768         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9769         context.SetRegisterRegisterOperands (reg_n, reg_m);
9770 
9771         if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9772             return false;
9773     }
9774     return true;
9775 }
9776 
9777 // A8.6.202 STREX
9778 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a
9779 // word from a register to memory if the executing processor has exclusive access to the memory addressed.
9780 bool
9781 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding)
9782 {
9783 #if 0
9784     if ConditionPassed() then
9785         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9786         address = R[n] + imm32;
9787         if ExclusiveMonitorsPass(address,4) then
9788             MemA[address,4] = R[t];
9789             R[d] = 0;
9790         else
9791             R[d] = 1;
9792 #endif
9793 
9794     bool success = false;
9795 
9796     if (ConditionPassed(opcode))
9797     {
9798         uint32_t d;
9799         uint32_t t;
9800         uint32_t n;
9801         uint32_t imm32;
9802         const uint32_t addr_byte_size = GetAddressByteSize();
9803 
9804         switch (encoding)
9805         {
9806             case eEncodingT1:
9807                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
9808                 d = Bits32 (opcode, 11, 8);
9809                 t = Bits32 (opcode, 15, 12);
9810                 n = Bits32 (opcode, 19, 16);
9811                 imm32 = Bits32 (opcode, 7, 0) << 2;
9812 
9813                 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
9814                 if (BadReg (d) || BadReg (t) || (n == 15))
9815                   return false;
9816 
9817                 // if d == n || d == t then UNPREDICTABLE;
9818                 if ((d == n) || (d == t))
9819                   return false;
9820 
9821                 break;
9822 
9823             case eEncodingA1:
9824                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset
9825                 d = Bits32 (opcode, 15, 12);
9826                 t = Bits32 (opcode, 3, 0);
9827                 n = Bits32 (opcode, 19, 16);
9828                 imm32 = 0;
9829 
9830                 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
9831                 if ((d == 15) || (t == 15) || (n == 15))
9832                     return false;
9833 
9834                 // if d == n || d == t then UNPREDICTABLE;
9835                 if ((d == n) || (d == t))
9836                     return false;
9837 
9838                 break;
9839 
9840             default:
9841                 return false;
9842         }
9843 
9844         // address = R[n] + imm32;
9845         uint32_t Rn = ReadCoreReg (n, &success);
9846         if (!success)
9847             return false;
9848 
9849         addr_t address = Rn + imm32;
9850 
9851         RegisterInfo base_reg;
9852         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9853         RegisterInfo data_reg;
9854         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9855         EmulateInstruction::Context context;
9856         context.type = eContextRegisterStore;
9857         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32);
9858 
9859         // if ExclusiveMonitorsPass(address,4) then
9860         // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this
9861         //                                                         always return true.
9862         if (true)
9863         {
9864             // MemA[address,4] = R[t];
9865             uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
9866             if (!success)
9867                 return false;
9868 
9869             if (!MemAWrite (context, address, Rt, addr_byte_size))
9870                 return false;
9871 
9872             // R[d] = 0;
9873             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0))
9874                 return false;
9875         }
9876         else
9877         {
9878             // R[d] = 1;
9879             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
9880                 return false;
9881         }
9882     }
9883     return true;
9884 }
9885 
9886 // A8.6.197 STRB (immediate, ARM)
9887 bool
9888 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9889 {
9890 #if 0
9891     if ConditionPassed() then
9892         EncodingSpecificOperations();
9893         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9894         address = if index then offset_addr else R[n];
9895         MemU[address,1] = R[t]<7:0>;
9896         if wback then R[n] = offset_addr;
9897 #endif
9898 
9899     bool success = false;
9900 
9901     if (ConditionPassed(opcode))
9902     {
9903         uint32_t t;
9904         uint32_t n;
9905         uint32_t imm32;
9906         bool index;
9907         bool add;
9908         bool wback;
9909 
9910         switch (encoding)
9911         {
9912             case eEncodingA1:
9913                 // if P == �0� && W == �1� then SEE STRBT;
9914                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9915                 t = Bits32 (opcode, 15, 12);
9916                 n = Bits32 (opcode, 19, 16);
9917                 imm32 = Bits32 (opcode, 11, 0);
9918 
9919                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9920                 index = BitIsSet (opcode, 24);
9921                 add = BitIsSet (opcode, 23);
9922                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9923 
9924                 // if t == 15 then UNPREDICTABLE;
9925                 if (t == 15)
9926                     return false;
9927 
9928                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9929                 if (wback && ((n == 15) || (n == t)))
9930                     return false;
9931 
9932                 break;
9933 
9934             default:
9935                 return false;
9936         }
9937 
9938         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9939         uint32_t Rn = ReadCoreReg (n, &success);
9940         if (!success)
9941             return false;
9942 
9943         addr_t offset_addr;
9944         if (add)
9945             offset_addr = Rn + imm32;
9946         else
9947             offset_addr = Rn - imm32;
9948 
9949         // address = if index then offset_addr else R[n];
9950         addr_t address;
9951         if (index)
9952             address = offset_addr;
9953         else
9954             address = Rn;
9955 
9956         // MemU[address,1] = R[t]<7:0>;
9957         uint32_t Rt = ReadCoreReg (t, &success);
9958         if (!success)
9959             return false;
9960 
9961         RegisterInfo base_reg;
9962         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9963         RegisterInfo data_reg;
9964         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9965         EmulateInstruction::Context context;
9966         context.type = eContextRegisterStore;
9967         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
9968 
9969         if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1))
9970             return false;
9971 
9972         // if wback then R[n] = offset_addr;
9973         if (wback)
9974         {
9975             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
9976                 return false;
9977         }
9978     }
9979     return true;
9980 }
9981 
9982 // A8.6.194 STR (immediate, ARM)
9983 bool
9984 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding)
9985 {
9986 #if 0
9987     if ConditionPassed() then
9988         EncodingSpecificOperations();
9989         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9990         address = if index then offset_addr else R[n];
9991         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
9992         if wback then R[n] = offset_addr;
9993 #endif
9994 
9995     bool success = false;
9996 
9997     if (ConditionPassed(opcode))
9998     {
9999         uint32_t t;
10000         uint32_t n;
10001         uint32_t imm32;
10002         bool index;
10003         bool add;
10004         bool wback;
10005 
10006         const uint32_t addr_byte_size = GetAddressByteSize();
10007 
10008         switch (encoding)
10009         {
10010             case eEncodingA1:
10011                 // if P == �0� && W == �1� then SEE STRT;
10012                 // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH;
10013                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10014                 t = Bits32 (opcode, 15, 12);
10015                 n = Bits32 (opcode, 19, 16);
10016                 imm32 = Bits32 (opcode, 11, 0);
10017 
10018                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10019                 index = BitIsSet (opcode, 24);
10020                 add = BitIsSet (opcode, 23);
10021                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10022 
10023                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10024                 if (wback && ((n == 15) || (n == t)))
10025                     return false;
10026 
10027                 break;
10028 
10029             default:
10030                 return false;
10031         }
10032 
10033         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10034         uint32_t Rn = ReadCoreReg (n, &success);
10035         if (!success)
10036             return false;
10037 
10038         addr_t offset_addr;
10039         if (add)
10040             offset_addr = Rn + imm32;
10041         else
10042             offset_addr = Rn - imm32;
10043 
10044         // address = if index then offset_addr else R[n];
10045         addr_t address;
10046         if (index)
10047             address = offset_addr;
10048         else
10049             address = Rn;
10050 
10051         RegisterInfo base_reg;
10052         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10053         RegisterInfo data_reg;
10054         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10055         EmulateInstruction::Context context;
10056         context.type = eContextRegisterStore;
10057         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10058 
10059         // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10060         uint32_t Rt = ReadCoreReg (t, &success);
10061         if (!success)
10062             return false;
10063 
10064         if (t == 15)
10065         {
10066             uint32_t pc_value = ReadCoreReg (PC_REG, &success);
10067             if (!success)
10068                 return false;
10069 
10070             if (!MemUWrite (context, address, pc_value, addr_byte_size))
10071                 return false;
10072         }
10073         else
10074         {
10075             if (!MemUWrite (context, address, Rt, addr_byte_size))
10076                   return false;
10077         }
10078 
10079         // if wback then R[n] = offset_addr;
10080         if (wback)
10081         {
10082             context.type = eContextAdjustBaseRegister;
10083             context.SetImmediate (offset_addr);
10084 
10085             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10086                 return false;
10087         }
10088     }
10089     return true;
10090 }
10091 
10092 // A8.6.66 LDRD (immediate)
10093 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two
10094 // words from memory, and writes them to two registers.  It can use offset, post-indexed, or pre-indexed addressing.
10095 bool
10096 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding)
10097 {
10098 #if 0
10099     if ConditionPassed() then
10100         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10101         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10102         address = if index then offset_addr else R[n];
10103         R[t] = MemA[address,4];
10104         R[t2] = MemA[address+4,4];
10105         if wback then R[n] = offset_addr;
10106 #endif
10107 
10108     bool success = false;
10109 
10110     if (ConditionPassed(opcode))
10111     {
10112         uint32_t t;
10113         uint32_t t2;
10114         uint32_t n;
10115         uint32_t imm32;
10116         bool index;
10117         bool add;
10118         bool wback;
10119 
10120         switch (encoding)
10121         {
10122             case eEncodingT1:
10123                 //if P == �0� && W == �0� then SEE �Related encodings�;
10124                 //if Rn == �1111� then SEE LDRD (literal);
10125                 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10126                 t = Bits32 (opcode, 15, 12);
10127                 t2 = Bits32 (opcode, 11, 8);
10128                 n = Bits32 (opcode, 19, 16);
10129                 imm32 = Bits32 (opcode, 7, 0) << 2;
10130 
10131                 //index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10132                 index = BitIsSet (opcode, 24);
10133                 add = BitIsSet (opcode, 23);
10134                 wback = BitIsSet (opcode, 21);
10135 
10136                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10137                 if (wback && ((n == t) || (n == t2)))
10138                     return false;
10139 
10140                 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10141                 if (BadReg (t) || BadReg (t2) || (t == t2))
10142                     return false;
10143 
10144                 break;
10145 
10146             case eEncodingA1:
10147                 //if Rn == �1111� then SEE LDRD (literal);
10148                 //if Rt<0> == �1� then UNPREDICTABLE;
10149                 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10150                 t = Bits32 (opcode, 15, 12);
10151                 if (BitIsSet (t, 0))
10152                     return false;
10153                 t2 = t + 1;
10154                 n = Bits32 (opcode, 19, 16);
10155                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10156 
10157                 //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10158                 index = BitIsSet (opcode, 24);
10159                 add = BitIsSet (opcode, 23);
10160                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10161 
10162                 //if P == �0� && W == �1� then UNPREDICTABLE;
10163                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10164                     return false;
10165 
10166                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10167                 if (wback && ((n == t) || (n == t2)))
10168                     return false;
10169 
10170                 //if t2 == 15 then UNPREDICTABLE;
10171                 if (t2 == 15)
10172                     return false;
10173 
10174                 break;
10175 
10176             default:
10177                 return false;
10178         }
10179 
10180         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10181         uint32_t Rn = ReadCoreReg (n, &success);
10182         if (!success)
10183             return false;
10184 
10185         addr_t offset_addr;
10186         if (add)
10187                   offset_addr = Rn + imm32;
10188         else
10189             offset_addr = Rn - imm32;
10190 
10191         //address = if index then offset_addr else R[n];
10192         addr_t address;
10193         if (index)
10194             address = offset_addr;
10195         else
10196             address = Rn;
10197 
10198         //R[t] = MemA[address,4];
10199         RegisterInfo base_reg;
10200         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10201 
10202         EmulateInstruction::Context context;
10203         context.type = eContextRegisterLoad;
10204         context.SetRegisterPlusOffset (base_reg, address - Rn);
10205 
10206         const uint32_t addr_byte_size = GetAddressByteSize();
10207         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10208         if (!success)
10209             return false;
10210 
10211         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10212             return false;
10213 
10214         //R[t2] = MemA[address+4,4];
10215 
10216         context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10217         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10218         if (!success)
10219             return false;
10220 
10221         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10222             return false;
10223 
10224         //if wback then R[n] = offset_addr;
10225         if (wback)
10226         {
10227             context.type = eContextAdjustBaseRegister;
10228             context.SetAddress (offset_addr);
10229 
10230             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10231                 return false;
10232         }
10233     }
10234     return true;
10235 }
10236 
10237 // A8.6.68 LDRD (register)
10238 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two
10239 // words from memory, and writes them to two registers.  It can use offset, post-indexed or pre-indexed addressing.
10240 bool
10241 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding)
10242 {
10243 #if 0
10244     if ConditionPassed() then
10245         EncodingSpecificOperations();
10246         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10247         address = if index then offset_addr else R[n];
10248         R[t] = MemA[address,4];
10249         R[t2] = MemA[address+4,4];
10250         if wback then R[n] = offset_addr;
10251 #endif
10252 
10253     bool success = false;
10254 
10255     if (ConditionPassed(opcode))
10256     {
10257         uint32_t t;
10258         uint32_t t2;
10259         uint32_t n;
10260         uint32_t m;
10261         bool index;
10262         bool add;
10263         bool wback;
10264 
10265         switch (encoding)
10266         {
10267             case eEncodingA1:
10268                 // if Rt<0> == �1� then UNPREDICTABLE;
10269                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10270                 t = Bits32 (opcode, 15, 12);
10271                 if (BitIsSet (t, 0))
10272                     return false;
10273                 t2 = t + 1;
10274                 n = Bits32 (opcode, 19, 16);
10275                 m = Bits32 (opcode, 3, 0);
10276 
10277                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10278                 index = BitIsSet (opcode, 24);
10279                 add = BitIsSet (opcode, 23);
10280                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10281 
10282                 // if P == �0� && W == �1� then UNPREDICTABLE;
10283                   if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10284                   return false;
10285 
10286                 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10287                   if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10288                   return false;
10289 
10290                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10291                   if (wback && ((n == 15) || (n == t) || (n == t2)))
10292                   return false;
10293 
10294                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10295                 if ((ArchVersion() < 6) && wback && (m == n))
10296                   return false;
10297                 break;
10298 
10299             default:
10300                 return false;
10301         }
10302 
10303         uint32_t Rn = ReadCoreReg (n, &success);
10304         if (!success)
10305             return false;
10306         RegisterInfo base_reg;
10307         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10308 
10309         uint32_t Rm = ReadCoreReg (m, &success);
10310         if (!success)
10311             return false;
10312         RegisterInfo offset_reg;
10313         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10314 
10315         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10316         addr_t offset_addr;
10317         if (add)
10318             offset_addr = Rn + Rm;
10319         else
10320             offset_addr = Rn - Rm;
10321 
10322         // address = if index then offset_addr else R[n];
10323         addr_t address;
10324         if (index)
10325             address = offset_addr;
10326         else
10327             address = Rn;
10328 
10329         EmulateInstruction::Context context;
10330         context.type = eContextRegisterLoad;
10331         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
10332 
10333         // R[t] = MemA[address,4];
10334         const uint32_t addr_byte_size = GetAddressByteSize();
10335         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10336         if (!success)
10337             return false;
10338 
10339         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10340             return false;
10341 
10342         // R[t2] = MemA[address+4,4];
10343 
10344         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10345         if (!success)
10346             return false;
10347 
10348         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10349             return false;
10350 
10351         // if wback then R[n] = offset_addr;
10352         if (wback)
10353         {
10354             context.type = eContextAdjustBaseRegister;
10355             context.SetAddress (offset_addr);
10356 
10357             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10358                 return false;
10359         }
10360     }
10361     return true;
10362 }
10363 
10364 // A8.6.200 STRD (immediate)
10365 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and
10366 // stores two words from two registers to memory.  It can use offset, post-indexed, or pre-indexed addressing.
10367 bool
10368 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding)
10369 {
10370 #if 0
10371     if ConditionPassed() then
10372         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10373         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10374         address = if index then offset_addr else R[n];
10375         MemA[address,4] = R[t];
10376         MemA[address+4,4] = R[t2];
10377         if wback then R[n] = offset_addr;
10378 #endif
10379 
10380     bool success = false;
10381 
10382     if (ConditionPassed(opcode))
10383     {
10384         uint32_t t;
10385         uint32_t t2;
10386         uint32_t n;
10387         uint32_t imm32;
10388         bool index;
10389         bool add;
10390         bool wback;
10391 
10392         switch (encoding)
10393         {
10394             case eEncodingT1:
10395                 // if P == �0� && W == �0� then SEE �Related encodings�;
10396                 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10397                 t = Bits32 (opcode, 15, 12);
10398                 t2 = Bits32 (opcode, 11, 8);
10399                 n = Bits32 (opcode, 19, 16);
10400                 imm32 = Bits32 (opcode, 7, 0) << 2;
10401 
10402                 // index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10403                 index = BitIsSet (opcode, 24);
10404                 add = BitIsSet (opcode, 23);
10405                 wback = BitIsSet (opcode, 21);
10406 
10407                 // if wback && (n == t || n == t2) then UNPREDICTABLE;
10408                 if (wback && ((n == t) || (n == t2)))
10409                     return false;
10410 
10411                 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10412                 if ((n == 15) || BadReg (t) || BadReg (t2))
10413                     return false;
10414 
10415                 break;
10416 
10417             case eEncodingA1:
10418                 // if Rt<0> == �1� then UNPREDICTABLE;
10419                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10420                 t = Bits32 (opcode, 15, 12);
10421                 if (BitIsSet (t, 0))
10422                     return false;
10423 
10424                 t2 = t + 1;
10425                 n = Bits32 (opcode, 19, 16);
10426                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10427 
10428                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10429                 index = BitIsSet (opcode, 24);
10430                 add = BitIsSet (opcode, 23);
10431                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10432 
10433                 // if P == �0� && W == �1� then UNPREDICTABLE;
10434                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10435                     return false;
10436 
10437                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10438                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10439                     return false;
10440 
10441                 // if t2 == 15 then UNPREDICTABLE;
10442                 if (t2 == 15)
10443                     return false;
10444 
10445                 break;
10446 
10447             default:
10448                 return false;
10449         }
10450 
10451         RegisterInfo base_reg;
10452         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10453 
10454         uint32_t Rn = ReadCoreReg (n, &success);
10455         if (!success)
10456             return false;
10457 
10458         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10459         addr_t offset_addr;
10460         if (add)
10461             offset_addr = Rn + imm32;
10462         else
10463             offset_addr = Rn - imm32;
10464 
10465         //address = if index then offset_addr else R[n];
10466         addr_t address;
10467         if (index)
10468             address = offset_addr;
10469         else
10470             address = Rn;
10471 
10472         //MemA[address,4] = R[t];
10473         RegisterInfo data_reg;
10474         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10475 
10476         uint32_t data = ReadCoreReg (t, &success);
10477         if (!success)
10478             return false;
10479 
10480         EmulateInstruction::Context context;
10481         context.type = eContextRegisterStore;
10482         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10483 
10484         const uint32_t addr_byte_size = GetAddressByteSize();
10485 
10486         if (!MemAWrite (context, address, data, addr_byte_size))
10487             return false;
10488 
10489         //MemA[address+4,4] = R[t2];
10490         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10491         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10492 
10493         data = ReadCoreReg (t2, &success);
10494         if (!success)
10495             return false;
10496 
10497         if (!MemAWrite (context, address + 4, data, addr_byte_size))
10498             return false;
10499 
10500         //if wback then R[n] = offset_addr;
10501         if (wback)
10502         {
10503             context.type = eContextAdjustBaseRegister;
10504             context.SetAddress (offset_addr);
10505 
10506             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10507                 return false;
10508         }
10509     }
10510     return true;
10511 }
10512 
10513 
10514 // A8.6.201 STRD (register)
10515 bool
10516 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding)
10517 {
10518 #if 0
10519     if ConditionPassed() then
10520         EncodingSpecificOperations();
10521         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10522         address = if index then offset_addr else R[n];
10523         MemA[address,4] = R[t];
10524         MemA[address+4,4] = R[t2];
10525         if wback then R[n] = offset_addr;
10526 #endif
10527 
10528     bool success = false;
10529 
10530     if (ConditionPassed(opcode))
10531     {
10532         uint32_t t;
10533         uint32_t t2;
10534         uint32_t n;
10535         uint32_t m;
10536         bool index;
10537         bool add;
10538         bool wback;
10539 
10540         switch (encoding)
10541         {
10542             case eEncodingA1:
10543                 // if Rt<0> == �1� then UNPREDICTABLE;
10544                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10545                 t = Bits32 (opcode, 15, 12);
10546                 if (BitIsSet (t, 0))
10547                    return false;
10548 
10549                 t2 = t+1;
10550                 n = Bits32 (opcode, 19, 16);
10551                 m = Bits32 (opcode, 3, 0);
10552 
10553                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10554                 index = BitIsSet (opcode, 24);
10555                 add = BitIsSet (opcode, 23);
10556                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10557 
10558                 // if P == �0� && W == �1� then UNPREDICTABLE;
10559                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10560                    return false;
10561 
10562                 // if t2 == 15 || m == 15 then UNPREDICTABLE;
10563                 if ((t2 == 15) || (m == 15))
10564                    return false;
10565 
10566                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10567                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10568                    return false;
10569 
10570                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10571                 if ((ArchVersion() < 6) && wback && (m == n))
10572                    return false;
10573 
10574                 break;
10575 
10576             default:
10577                 return false;
10578         }
10579 
10580         RegisterInfo base_reg;
10581         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10582         RegisterInfo offset_reg;
10583         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10584         RegisterInfo data_reg;
10585 
10586         uint32_t Rn = ReadCoreReg (n, &success);
10587         if (!success)
10588             return false;
10589 
10590         uint32_t Rm = ReadCoreReg (m, &success);
10591         if (!success)
10592             return false;
10593 
10594         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10595         addr_t offset_addr;
10596         if (add)
10597             offset_addr = Rn + Rm;
10598         else
10599             offset_addr = Rn - Rm;
10600 
10601         // address = if index then offset_addr else R[n];
10602         addr_t address;
10603         if (index)
10604             address = offset_addr;
10605         else
10606             address = Rn;
10607                           // MemA[address,4] = R[t];
10608         uint32_t Rt = ReadCoreReg (t, &success);
10609         if (!success)
10610             return false;
10611 
10612         EmulateInstruction::Context context;
10613         context.type = eContextRegisterStore;
10614         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10615         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10616 
10617         const uint32_t addr_byte_size = GetAddressByteSize();
10618 
10619         if (!MemAWrite (context, address, Rt, addr_byte_size))
10620             return false;
10621 
10622         // MemA[address+4,4] = R[t2];
10623         uint32_t Rt2 = ReadCoreReg (t2, &success);
10624         if (!success)
10625             return false;
10626 
10627         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10628 
10629         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10630 
10631         if (!MemAWrite (context, address + 4, Rt2, addr_byte_size))
10632             return false;
10633 
10634         // if wback then R[n] = offset_addr;
10635         if (wback)
10636         {
10637             context.type = eContextAdjustBaseRegister;
10638             context.SetAddress (offset_addr);
10639 
10640             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10641                 return false;
10642 
10643         }
10644     }
10645     return true;
10646 }
10647 
10648 // A8.6.319 VLDM
10649 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from
10650 // an ARM core register.
10651 bool
10652 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding)
10653 {
10654 #if 0
10655     if ConditionPassed() then
10656         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10657         address = if add then R[n] else R[n]-imm32;
10658         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10659         for r = 0 to regs-1
10660             if single_regs then
10661                 S[d+r] = MemA[address,4]; address = address+4;
10662             else
10663                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10664                 // Combine the word-aligned words in the correct order for current endianness.
10665                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10666 #endif
10667 
10668     bool success = false;
10669 
10670     if (ConditionPassed(opcode))
10671     {
10672         bool single_regs;
10673         bool add;
10674         bool wback;
10675         uint32_t d;
10676         uint32_t n;
10677         uint32_t imm32;
10678         uint32_t regs;
10679 
10680         switch (encoding)
10681         {
10682             case eEncodingT1:
10683             case eEncodingA1:
10684                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10685                 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10686                 // if P == �1� && W == �0� then SEE VLDR;
10687                 // if P == U && W == �1� then UNDEFINED;
10688                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10689                     return false;
10690 
10691                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10692                 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10693                 single_regs = false;
10694                 add = BitIsSet (opcode, 23);
10695                 wback = BitIsSet (opcode, 21);
10696 
10697                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10698                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10699                 n = Bits32 (opcode, 19, 16);
10700                 imm32 = Bits32 (opcode, 7, 0) << 2;
10701 
10702                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�.
10703                 regs = Bits32 (opcode, 7, 0) / 2;
10704 
10705                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10706                 if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
10707                     return false;
10708 
10709                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10710                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10711                     return false;
10712 
10713                 break;
10714 
10715             case eEncodingT2:
10716             case eEncodingA2:
10717                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10718                 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10719                 // if P == �1� && W == �0� then SEE VLDR;
10720                 // if P == U && W == �1� then UNDEFINED;
10721                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10722                     return false;
10723 
10724                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10725                 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10726                 single_regs = true;
10727                 add = BitIsSet (opcode, 23);
10728                 wback = BitIsSet (opcode, 21);
10729                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10730                 n = Bits32 (opcode, 19, 16);
10731 
10732                 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10733                 imm32 = Bits32 (opcode, 7, 0) << 2;
10734                 regs = Bits32 (opcode, 7, 0);
10735 
10736                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10737                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10738                     return false;
10739 
10740                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10741                 if ((regs == 0) || ((d + regs) > 32))
10742                     return false;
10743                 break;
10744 
10745             default:
10746                 return false;
10747         }
10748 
10749         RegisterInfo base_reg;
10750         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10751 
10752         uint32_t Rn = ReadCoreReg (n, &success);
10753         if (!success)
10754             return false;
10755 
10756         // address = if add then R[n] else R[n]-imm32;
10757         addr_t address;
10758         if (add)
10759             address = Rn;
10760         else
10761             address = Rn - imm32;
10762 
10763         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10764         EmulateInstruction::Context context;
10765 
10766         if (wback)
10767         {
10768             uint32_t value;
10769             if (add)
10770                 value = Rn + imm32;
10771             else
10772                 value = Rn - imm32;
10773 
10774             context.type = eContextAdjustBaseRegister;
10775             context.SetImmediateSigned (value - Rn);
10776             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10777                 return false;
10778 
10779         }
10780 
10781         const uint32_t addr_byte_size = GetAddressByteSize();
10782         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10783 
10784         context.type = eContextRegisterLoad;
10785 
10786         // for r = 0 to regs-1
10787         for (uint32_t r = 0; r < regs; ++r)
10788         {
10789             if (single_regs)
10790             {
10791                 // S[d+r] = MemA[address,4]; address = address+4;
10792                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10793 
10794                 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10795                 if (!success)
10796                     return false;
10797 
10798                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10799                     return false;
10800 
10801                 address = address + 4;
10802             }
10803             else
10804             {
10805                 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10806                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10807                 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10808                 if (!success)
10809                     return false;
10810 
10811                 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10812                 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10813                 if (!success)
10814                     return false;
10815 
10816                 address = address + 8;
10817                 // // Combine the word-aligned words in the correct order for current endianness.
10818                 // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10819                 uint64_t data;
10820                 if (GetByteOrder() == eByteOrderBig)
10821                 {
10822                     data = word1;
10823                     data = (data << 32) | word2;
10824                 }
10825                 else
10826                 {
10827                     data = word2;
10828                     data = (data << 32) | word1;
10829                 }
10830 
10831                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10832                     return false;
10833             }
10834         }
10835     }
10836     return true;
10837 }
10838 
10839 // A8.6.399 VSTM
10840 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an
10841 // ARM core register.
10842 bool
10843 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding)
10844 {
10845 #if 0
10846     if ConditionPassed() then
10847         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10848         address = if add then R[n] else R[n]-imm32;
10849         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10850         for r = 0 to regs-1
10851             if single_regs then
10852                 MemA[address,4] = S[d+r]; address = address+4;
10853             else
10854                 // Store as two word-aligned words in the correct order for current endianness.
10855                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10856                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10857                 address = address+8;
10858 #endif
10859 
10860     bool success = false;
10861 
10862     if (ConditionPassed (opcode))
10863     {
10864         bool single_regs;
10865         bool add;
10866         bool wback;
10867         uint32_t d;
10868         uint32_t n;
10869         uint32_t imm32;
10870         uint32_t regs;
10871 
10872         switch (encoding)
10873         {
10874             case eEncodingT1:
10875             case eEncodingA1:
10876                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10877                 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10878                 // if P == �1� && W == �0� then SEE VSTR;
10879                 // if P == U && W == �1� then UNDEFINED;
10880                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10881                     return false;
10882 
10883                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10884                 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10885                 single_regs = false;
10886                 add = BitIsSet (opcode, 23);
10887                 wback = BitIsSet (opcode, 21);
10888 
10889                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10890                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10891                 n = Bits32 (opcode, 19, 16);
10892                 imm32 = Bits32 (opcode, 7, 0) << 2;
10893 
10894                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�.
10895                 regs = Bits32 (opcode, 7, 0) / 2;
10896 
10897                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10898                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10899                     return false;
10900 
10901                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10902                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10903                     return false;
10904 
10905                 break;
10906 
10907             case eEncodingT2:
10908             case eEncodingA2:
10909                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10910                 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10911                 // if P == �1� && W == �0� then SEE VSTR;
10912                 // if P == U && W == �1� then UNDEFINED;
10913                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10914                     return false;
10915 
10916                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10917                 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10918                 single_regs = true;
10919                 add = BitIsSet (opcode, 23);
10920                 wback = BitIsSet (opcode, 21);
10921                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10922                 n = Bits32 (opcode, 19, 16);
10923 
10924                 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10925                 imm32 = Bits32 (opcode, 7, 0) << 2;
10926                 regs = Bits32 (opcode, 7, 0);
10927 
10928                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10929                 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM)))
10930                     return false;
10931 
10932                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10933                 if ((regs == 0) || ((d + regs) > 32))
10934                     return false;
10935 
10936                 break;
10937 
10938             default:
10939                 return false;
10940         }
10941 
10942         RegisterInfo base_reg;
10943         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10944 
10945         uint32_t Rn = ReadCoreReg (n, &success);
10946         if (!success)
10947             return false;
10948 
10949         // address = if add then R[n] else R[n]-imm32;
10950         addr_t address;
10951         if (add)
10952             address = Rn;
10953         else
10954             address = Rn - imm32;
10955 
10956         EmulateInstruction::Context context;
10957         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10958         if (wback)
10959         {
10960             uint32_t value;
10961             if (add)
10962                 value = Rn + imm32;
10963             else
10964                 value = Rn - imm32;
10965 
10966             context.type = eContextAdjustBaseRegister;
10967             context.SetRegisterPlusOffset (base_reg, value - Rn);
10968 
10969             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10970                 return false;
10971         }
10972 
10973         const uint32_t addr_byte_size = GetAddressByteSize();
10974         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10975 
10976         context.type = eContextRegisterStore;
10977         // for r = 0 to regs-1
10978         for (uint32_t r = 0; r < regs; ++r)
10979         {
10980 
10981             if (single_regs)
10982             {
10983                 // MemA[address,4] = S[d+r]; address = address+4;
10984                 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10985                 if (!success)
10986                     return false;
10987 
10988                 RegisterInfo data_reg;
10989                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
10990                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10991                 if (!MemAWrite (context, address, data, addr_byte_size))
10992                     return false;
10993 
10994                 address = address + 4;
10995             }
10996             else
10997             {
10998                 // // Store as two word-aligned words in the correct order for current endianness.
10999                 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
11000                 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
11001                 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
11002                 if (!success)
11003                     return false;
11004 
11005                 RegisterInfo data_reg;
11006                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
11007 
11008                 if (GetByteOrder() == eByteOrderBig)
11009                 {
11010                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11011                     if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11012                         return false;
11013 
11014                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11015                     if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size))
11016                         return false;
11017                 }
11018                 else
11019                 {
11020                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11021                     if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11022                         return false;
11023 
11024                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11025                     if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11026                         return false;
11027                 }
11028                 // address = address+8;
11029                 address = address + 8;
11030             }
11031         }
11032     }
11033     return true;
11034 }
11035 
11036 // A8.6.320
11037 // This instruction loads a single extension register from memory, using an address from an ARM core register, with
11038 // an optional offset.
11039 bool
11040 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
11041 {
11042 #if 0
11043     if ConditionPassed() then
11044         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11045         base = if n == 15 then Align(PC,4) else R[n];
11046         address = if add then (base + imm32) else (base - imm32);
11047         if single_reg then
11048             S[d] = MemA[address,4];
11049         else
11050             word1 = MemA[address,4]; word2 = MemA[address+4,4];
11051             // Combine the word-aligned words in the correct order for current endianness.
11052             D[d] = if BigEndian() then word1:word2 else word2:word1;
11053 #endif
11054 
11055     bool success = false;
11056 
11057     if (ConditionPassed (opcode))
11058     {
11059         bool single_reg;
11060         bool add;
11061         uint32_t imm32;
11062         uint32_t d;
11063         uint32_t n;
11064 
11065         switch (encoding)
11066         {
11067             case eEncodingT1:
11068             case eEncodingA1:
11069                 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11070                 single_reg = false;
11071                 add = BitIsSet (opcode, 23);
11072                 imm32 = Bits32 (opcode, 7, 0) << 2;
11073 
11074                 // d = UInt(D:Vd); n = UInt(Rn);
11075                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11076                 n = Bits32 (opcode, 19, 16);
11077 
11078                 break;
11079 
11080             case eEncodingT2:
11081             case eEncodingA2:
11082                 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11083                 single_reg = true;
11084                 add = BitIsSet (opcode, 23);
11085                 imm32 = Bits32 (opcode, 7, 0) << 2;
11086 
11087                 // d = UInt(Vd:D); n = UInt(Rn);
11088                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11089                 n = Bits32 (opcode, 19, 16);
11090 
11091                 break;
11092 
11093             default:
11094                 return false;
11095         }
11096         RegisterInfo base_reg;
11097         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11098 
11099         uint32_t Rn = ReadCoreReg (n, &success);
11100         if (!success)
11101             return false;
11102 
11103         // base = if n == 15 then Align(PC,4) else R[n];
11104         uint32_t base;
11105         if (n == 15)
11106             base = AlignPC (Rn);
11107         else
11108             base = Rn;
11109 
11110         // address = if add then (base + imm32) else (base - imm32);
11111         addr_t address;
11112         if (add)
11113             address = base + imm32;
11114         else
11115             address = base - imm32;
11116 
11117         const uint32_t addr_byte_size = GetAddressByteSize();
11118         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11119 
11120         EmulateInstruction::Context context;
11121         context.type = eContextRegisterLoad;
11122         context.SetRegisterPlusOffset (base_reg, address - base);
11123 
11124         if (single_reg)
11125         {
11126             // S[d] = MemA[address,4];
11127             uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
11128             if (!success)
11129                 return false;
11130 
11131             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data))
11132                 return false;
11133         }
11134         else
11135         {
11136             // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11137             uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
11138             if (!success)
11139                 return false;
11140 
11141             context.SetRegisterPlusOffset (base_reg, (address + 4) - base);
11142             uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
11143             if (!success)
11144                 return false;
11145             // // Combine the word-aligned words in the correct order for current endianness.
11146             // D[d] = if BigEndian() then word1:word2 else word2:word1;
11147             uint64_t data64;
11148             if (GetByteOrder() == eByteOrderBig)
11149             {
11150                 data64 = word1;
11151                 data64 = (data64 << 32) | word2;
11152             }
11153             else
11154             {
11155                 data64 = word2;
11156                 data64 = (data64 << 32) | word1;
11157             }
11158 
11159             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64))
11160                 return false;
11161         }
11162     }
11163     return true;
11164 }
11165 
11166 // A8.6.400 VSTR
11167 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an
11168 // optional offset.
11169 bool
11170 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
11171 {
11172 #if 0
11173     if ConditionPassed() then
11174         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11175         address = if add then (R[n] + imm32) else (R[n] - imm32);
11176         if single_reg then
11177             MemA[address,4] = S[d];
11178         else
11179             // Store as two word-aligned words in the correct order for current endianness.
11180             MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11181             MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11182 #endif
11183 
11184     bool success = false;
11185 
11186     if (ConditionPassed (opcode))
11187     {
11188         bool single_reg;
11189         bool add;
11190         uint32_t imm32;
11191         uint32_t d;
11192         uint32_t n;
11193 
11194         switch (encoding)
11195         {
11196             case eEncodingT1:
11197             case eEncodingA1:
11198                 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11199                 single_reg = false;
11200                 add = BitIsSet (opcode, 23);
11201                 imm32 = Bits32 (opcode, 7, 0) << 2;
11202 
11203                 // d = UInt(D:Vd); n = UInt(Rn);
11204                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11205                 n = Bits32 (opcode, 19, 16);
11206 
11207                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11208                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11209                     return false;
11210 
11211                 break;
11212 
11213             case eEncodingT2:
11214             case eEncodingA2:
11215                 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11216                 single_reg = true;
11217                 add = BitIsSet (opcode, 23);
11218                 imm32 = Bits32 (opcode, 7, 0) << 2;
11219 
11220                 // d = UInt(Vd:D); n = UInt(Rn);
11221                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11222                 n = Bits32 (opcode, 19, 16);
11223 
11224                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11225                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11226                     return false;
11227 
11228                 break;
11229 
11230             default:
11231                 return false;
11232         }
11233 
11234         RegisterInfo base_reg;
11235         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11236 
11237         uint32_t Rn = ReadCoreReg (n, &success);
11238         if (!success)
11239             return false;
11240 
11241         // address = if add then (R[n] + imm32) else (R[n] - imm32);
11242         addr_t address;
11243         if (add)
11244             address = Rn + imm32;
11245         else
11246             address = Rn - imm32;
11247 
11248         const uint32_t addr_byte_size = GetAddressByteSize();
11249         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11250 
11251         RegisterInfo data_reg;
11252         GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg);
11253         EmulateInstruction::Context context;
11254         context.type = eContextRegisterStore;
11255         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11256 
11257         if (single_reg)
11258         {
11259             // MemA[address,4] = S[d];
11260             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11261             if (!success)
11262                 return false;
11263 
11264             if (!MemAWrite (context, address, data, addr_byte_size))
11265                 return false;
11266         }
11267         else
11268         {
11269             // // Store as two word-aligned words in the correct order for current endianness.
11270             // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11271             // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11272             uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11273             if (!success)
11274                 return false;
11275 
11276             if (GetByteOrder() == eByteOrderBig)
11277             {
11278                 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11279                     return false;
11280 
11281                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11282                 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size))
11283                     return false;
11284             }
11285             else
11286             {
11287                 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11288                     return false;
11289 
11290                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11291                 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11292                     return false;
11293             }
11294         }
11295     }
11296     return true;
11297 }
11298 
11299 // A8.6.307 VLDI1 (multiple single elements)
11300 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving.  Every
11301 // element of each register is loaded.
11302 bool
11303 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding)
11304 {
11305 #if 0
11306     if ConditionPassed() then
11307         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11308         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11309         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11310         for r = 0 to regs-1
11311             for e = 0 to elements-1
11312                 Elem[D[d+r],e,esize] = MemU[address,ebytes];
11313                 address = address + ebytes;
11314 #endif
11315 
11316     bool success = false;
11317 
11318     if (ConditionPassed (opcode))
11319     {
11320         uint32_t regs;
11321         uint32_t alignment;
11322         uint32_t ebytes;
11323         uint32_t esize;
11324         uint32_t elements;
11325         uint32_t d;
11326         uint32_t n;
11327         uint32_t m;
11328         bool wback;
11329         bool register_index;
11330 
11331         switch (encoding)
11332         {
11333             case eEncodingT1:
11334             case eEncodingA1:
11335             {
11336                 // case type of
11337                     // when �0111�
11338                         // regs = 1; if align<1> == �1� then UNDEFINED;
11339                     // when �1010�
11340                         // regs = 2; if align == �11� then UNDEFINED;
11341                     // when �0110�
11342                         // regs = 3; if align<1> == �1� then UNDEFINED;
11343                     // when �0010�
11344                         // regs = 4;
11345                     // otherwise
11346                         // SEE �Related encodings�;
11347                 uint32_t type = Bits32 (opcode, 11, 8);
11348                 uint32_t align = Bits32 (opcode, 5, 4);
11349                 if (type == 7) // '0111'
11350                 {
11351                     regs = 1;
11352                     if (BitIsSet (align, 1))
11353                         return false;
11354                 }
11355                 else if (type == 10) // '1010'
11356                 {
11357                     regs = 2;
11358                     if (align == 3)
11359                         return false;
11360 
11361                 }
11362                 else if (type == 6) // '0110'
11363                 {
11364                     regs = 3;
11365                     if (BitIsSet (align, 1))
11366                         return false;
11367                 }
11368                 else if (type == 2) // '0010'
11369                 {
11370                     regs = 4;
11371                 }
11372                 else
11373                     return false;
11374 
11375                 // alignment = if align == �00� then 1 else 4 << UInt(align);
11376                 if (align == 0)
11377                     alignment = 1;
11378                 else
11379                     alignment = 4 << align;
11380 
11381                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11382                 ebytes = 1 << Bits32 (opcode, 7, 6);
11383                 esize = 8 * ebytes;
11384                 elements = 8 / ebytes;
11385 
11386                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11387                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11388                 n = Bits32 (opcode, 19, 15);
11389                 m = Bits32 (opcode, 3, 0);
11390 
11391                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11392                 wback = (m != 15);
11393                 register_index = ((m != 15) && (m != 13));
11394 
11395                 // if d+regs > 32 then UNPREDICTABLE;
11396                 if ((d + regs) > 32)
11397                     return false;
11398             }
11399                 break;
11400 
11401             default:
11402                 return false;
11403         }
11404 
11405         RegisterInfo base_reg;
11406         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11407 
11408         uint32_t Rn = ReadCoreReg (n, &success);
11409         if (!success)
11410             return false;
11411 
11412         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11413         addr_t address = Rn;
11414         if ((address % alignment) != 0)
11415             return false;
11416 
11417         EmulateInstruction::Context context;
11418         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11419         if (wback)
11420         {
11421             uint32_t Rm = ReadCoreReg (m, &success);
11422             if (!success)
11423                 return false;
11424 
11425             uint32_t offset;
11426             if (register_index)
11427                 offset = Rm;
11428             else
11429                 offset = 8 * regs;
11430 
11431             uint32_t value = Rn + offset;
11432             context.type = eContextAdjustBaseRegister;
11433             context.SetRegisterPlusOffset (base_reg, offset);
11434 
11435             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11436                 return false;
11437 
11438         }
11439 
11440         // for r = 0 to regs-1
11441         for (uint32_t r = 0; r < regs; ++r)
11442         {
11443             // for e = 0 to elements-1
11444             uint64_t assembled_data = 0;
11445             for (uint32_t e = 0; e < elements; ++e)
11446             {
11447                 // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11448                 context.type = eContextRegisterLoad;
11449                 context.SetRegisterPlusOffset (base_reg, address - Rn);
11450                 uint64_t data = MemURead (context, address, ebytes, 0, &success);
11451                 if (!success)
11452                     return false;
11453 
11454                 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data
11455 
11456                 // address = address + ebytes;
11457                 address = address + ebytes;
11458             }
11459             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data))
11460                 return false;
11461         }
11462     }
11463     return true;
11464 }
11465 
11466 // A8.6.308 VLD1 (single element to one lane)
11467 //
11468 bool
11469 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding)
11470 {
11471 #if 0
11472     if ConditionPassed() then
11473         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11474         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11475         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11476         Elem[D[d],index,esize] = MemU[address,ebytes];
11477 #endif
11478 
11479     bool success = false;
11480 
11481     if (ConditionPassed (opcode))
11482     {
11483         uint32_t ebytes;
11484         uint32_t esize;
11485         uint32_t index;
11486         uint32_t alignment;
11487         uint32_t d;
11488         uint32_t n;
11489         uint32_t m;
11490         bool wback;
11491         bool register_index;
11492 
11493         switch (encoding)
11494         {
11495             case eEncodingT1:
11496             case eEncodingA1:
11497             {
11498                 uint32_t size = Bits32 (opcode, 11, 10);
11499                 uint32_t index_align = Bits32 (opcode, 7, 4);
11500                 // if size == �11� then SEE VLD1 (single element to all lanes);
11501                 if (size == 3)
11502                    return EmulateVLD1SingleAll (opcode, encoding);
11503                 // case size of
11504                 if (size == 0) // when '00'
11505                 {
11506                     // if index_align<0> != �0� then UNDEFINED;
11507                     if (BitIsClear (index_align, 0))
11508                         return false;
11509 
11510                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11511                     ebytes = 1;
11512                     esize = 8;
11513                     index = Bits32 (index_align, 3, 1);
11514                     alignment = 1;
11515                 }
11516                 else if (size == 1) // when �01�
11517                 {
11518                     // if index_align<1> != �0� then UNDEFINED;
11519                     if (BitIsClear (index_align, 1))
11520                         return false;
11521 
11522                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11523                     ebytes = 2;
11524                     esize = 16;
11525                     index = Bits32 (index_align, 3, 2);
11526 
11527                     // alignment = if index_align<0> == �0� then 1 else 2;
11528                     if (BitIsClear (index_align, 0))
11529                         alignment = 1;
11530                     else
11531                         alignment = 2;
11532                 }
11533                 else if (size == 2) // when �10�
11534                 {
11535                     // if index_align<2> != �0� then UNDEFINED;
11536                     if (BitIsClear (index_align, 2))
11537                         return false;
11538 
11539                     // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11540                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11541                         return false;
11542 
11543                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11544                     ebytes = 4;
11545                     esize = 32;
11546                     index = Bit32 (index_align, 3);
11547 
11548                     // alignment = if index_align<1:0> == �00� then 1 else 4;
11549                     if (Bits32 (index_align, 1, 0) == 0)
11550                         alignment = 1;
11551                     else
11552                         alignment = 4;
11553                 }
11554                 else
11555                 {
11556                     return false;
11557                 }
11558                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11559                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11560                 n = Bits32 (opcode, 19, 16);
11561                 m = Bits32 (opcode, 3, 0);
11562 
11563                 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
11564                 wback = (m != 15);
11565                 register_index = ((m != 15) && (m != 13));
11566 
11567                 if (n == 15)
11568                     return false;
11569 
11570             }
11571                 break;
11572 
11573             default:
11574                 return false;
11575         }
11576 
11577         RegisterInfo base_reg;
11578         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11579 
11580         uint32_t Rn = ReadCoreReg (n, &success);
11581         if (!success)
11582             return false;
11583 
11584         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11585         addr_t address = Rn;
11586         if ((address % alignment) != 0)
11587             return false;
11588 
11589         EmulateInstruction::Context context;
11590         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11591         if (wback)
11592         {
11593             uint32_t Rm = ReadCoreReg (m, &success);
11594             if (!success)
11595                 return false;
11596 
11597             uint32_t offset;
11598             if (register_index)
11599                 offset = Rm;
11600             else
11601                 offset = ebytes;
11602 
11603             uint32_t value = Rn + offset;
11604 
11605             context.type = eContextAdjustBaseRegister;
11606             context.SetRegisterPlusOffset (base_reg, offset);
11607 
11608             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11609                 return false;
11610         }
11611 
11612         // Elem[D[d],index,esize] = MemU[address,ebytes];
11613         uint32_t element = MemURead (context, address, esize, 0, &success);
11614         if (!success)
11615             return false;
11616 
11617         element = element << (index * esize);
11618 
11619         uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11620         if (!success)
11621             return false;
11622 
11623         uint64_t all_ones = -1;
11624         uint64_t mask = all_ones << ((index+1) * esize);  // mask is all 1's to left of where 'element' goes, & all 0's
11625                                                           // at element & to the right of element.
11626         if (index > 0)
11627             mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes.
11628                                                                      // now mask should be 0's where element goes & 1's
11629                                                                      // everywhere else.
11630 
11631         uint64_t masked_reg = reg_data & mask;  // Take original reg value & zero out 'element' bits
11632         reg_data = masked_reg & element;        // Put 'element' into those bits in reg_data.
11633 
11634         context.type = eContextRegisterLoad;
11635         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data))
11636             return false;
11637     }
11638     return true;
11639 }
11640 
11641 // A8.6.391 VST1 (multiple single elements)
11642 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four registers, without
11643 // interleaving.  Every element of each register is stored.
11644 bool
11645 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding)
11646 {
11647 #if 0
11648     if ConditionPassed() then
11649         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11650         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11651         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11652         for r = 0 to regs-1
11653             for e = 0 to elements-1
11654                 MemU[address,ebytes] = Elem[D[d+r],e,esize];
11655                 address = address + ebytes;
11656 #endif
11657 
11658     bool success = false;
11659 
11660     if (ConditionPassed (opcode))
11661     {
11662         uint32_t regs;
11663         uint32_t alignment;
11664         uint32_t ebytes;
11665         uint32_t esize;
11666         uint32_t elements;
11667         uint32_t d;
11668         uint32_t n;
11669         uint32_t m;
11670         bool wback;
11671         bool register_index;
11672 
11673         switch (encoding)
11674         {
11675             case eEncodingT1:
11676             case eEncodingA1:
11677             {
11678                 uint32_t type = Bits32 (opcode, 11, 8);
11679                 uint32_t align = Bits32 (opcode, 5, 4);
11680 
11681                 // case type of
11682                 if (type == 7)    // when �0111�
11683                 {
11684                     // regs = 1; if align<1> == �1� then UNDEFINED;
11685                     regs = 1;
11686                     if (BitIsSet (align, 1))
11687                         return false;
11688                 }
11689                 else if (type == 10) // when �1010�
11690                 {
11691                     // regs = 2; if align == �11� then UNDEFINED;
11692                     regs = 2;
11693                     if (align == 3)
11694                         return false;
11695                 }
11696                 else if (type == 6) // when �0110�
11697                 {
11698                     // regs = 3; if align<1> == �1� then UNDEFINED;
11699                     regs = 3;
11700                     if (BitIsSet (align, 1))
11701                         return false;
11702                 }
11703                 else if (type == 2) // when �0010�
11704                     // regs = 4;
11705                     regs = 4;
11706                 else // otherwise
11707                     // SEE �Related encodings�;
11708                     return false;
11709 
11710                 // alignment = if align == �00� then 1 else 4 << UInt(align);
11711                 if (align == 0)
11712                     alignment = 1;
11713                 else
11714                     alignment = 4 << align;
11715 
11716                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11717                 ebytes = 1 << Bits32 (opcode,7, 6);
11718                 esize = 8 * ebytes;
11719                 elements = 8 / ebytes;
11720 
11721                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11722                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11723                 n = Bits32 (opcode, 19, 16);
11724                 m = Bits32 (opcode, 3, 0);
11725 
11726                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11727                 wback = (m != 15);
11728                 register_index = ((m != 15) && (m != 13));
11729 
11730                 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11731                 if ((d + regs) > 32)
11732                     return false;
11733 
11734                 if (n == 15)
11735                     return false;
11736 
11737             }
11738                 break;
11739 
11740             default:
11741                 return false;
11742         }
11743 
11744         RegisterInfo base_reg;
11745         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11746 
11747         uint32_t Rn = ReadCoreReg (n, &success);
11748         if (!success)
11749             return false;
11750 
11751         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11752         addr_t address = Rn;
11753         if ((address % alignment) != 0)
11754             return false;
11755 
11756         EmulateInstruction::Context context;
11757         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11758         if (wback)
11759         {
11760             uint32_t Rm = ReadCoreReg (m, &success);
11761             if (!success)
11762                 return false;
11763 
11764             uint32_t offset;
11765             if (register_index)
11766                 offset = Rm;
11767             else
11768                 offset = 8 * regs;
11769 
11770             context.type = eContextAdjustBaseRegister;
11771             context.SetRegisterPlusOffset (base_reg, offset);
11772 
11773             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11774                 return false;
11775         }
11776 
11777         RegisterInfo data_reg;
11778         context.type = eContextRegisterStore;
11779         // for r = 0 to regs-1
11780         for (uint32_t r = 0; r < regs; ++r)
11781         {
11782             GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
11783             uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
11784             if (!success)
11785                 return false;
11786 
11787              // for e = 0 to elements-1
11788             for (uint32_t e = 0; e < elements; ++e)
11789             {
11790                 // MemU[address,ebytes] = Elem[D[d+r],e,esize];
11791                 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize);
11792 
11793                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11794                 if (!MemUWrite (context, address, word, ebytes))
11795                     return false;
11796 
11797                 // address = address + ebytes;
11798                 address = address + ebytes;
11799             }
11800         }
11801     }
11802     return true;
11803 }
11804 
11805 // A8.6.392 VST1 (single element from one lane)
11806 // This instruction stores one element to memory from one element of a register.
11807 bool
11808 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding)
11809 {
11810 #if 0
11811     if ConditionPassed() then
11812         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11813         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11814         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11815         MemU[address,ebytes] = Elem[D[d],index,esize];
11816 #endif
11817 
11818     bool success = false;
11819 
11820     if (ConditionPassed (opcode))
11821     {
11822         uint32_t ebytes;
11823         uint32_t esize;
11824         uint32_t index;
11825         uint32_t alignment;
11826         uint32_t d;
11827         uint32_t n;
11828         uint32_t m;
11829         bool wback;
11830         bool register_index;
11831 
11832         switch (encoding)
11833         {
11834             case eEncodingT1:
11835             case eEncodingA1:
11836             {
11837                 uint32_t size = Bits32 (opcode, 11, 10);
11838                 uint32_t index_align = Bits32 (opcode, 7, 4);
11839 
11840                 // if size == �11� then UNDEFINED;
11841                 if (size == 3)
11842                     return false;
11843 
11844                 // case size of
11845                 if (size == 0) // when �00�
11846                 {
11847                     // if index_align<0> != �0� then UNDEFINED;
11848                     if (BitIsClear (index_align, 0))
11849                         return false;
11850                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11851                     ebytes = 1;
11852                     esize = 8;
11853                     index = Bits32 (index_align, 3, 1);
11854                     alignment = 1;
11855                 }
11856                 else if (size == 1) // when �01�
11857                 {
11858                     // if index_align<1> != �0� then UNDEFINED;
11859                     if (BitIsClear (index_align, 1))
11860                         return false;
11861 
11862                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11863                     ebytes = 2;
11864                     esize = 16;
11865                     index = Bits32 (index_align, 3, 2);
11866 
11867                     // alignment = if index_align<0> == �0� then 1 else 2;
11868                     if (BitIsClear (index_align, 0))
11869                         alignment = 1;
11870                     else
11871                         alignment = 2;
11872                 }
11873                 else if (size == 2) // when �10�
11874                 {
11875                     // if index_align<2> != �0� then UNDEFINED;
11876                     if (BitIsClear (index_align, 2))
11877                         return false;
11878 
11879                     // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11880                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11881                         return false;
11882 
11883                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11884                     ebytes = 4;
11885                     esize = 32;
11886                     index = Bit32 (index_align, 3);
11887 
11888                     // alignment = if index_align<1:0> == �00� then 1 else 4;
11889                     if (Bits32 (index_align, 1, 0) == 0)
11890                         alignment = 1;
11891                     else
11892                         alignment = 4;
11893                 }
11894                 else
11895                 {
11896                     return false;
11897                 }
11898                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11899                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11900                 n = Bits32 (opcode, 19, 16);
11901                 m = Bits32 (opcode, 3, 0);
11902 
11903                 // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15 then UNPREDICTABLE;
11904                 wback = (m != 15);
11905                 register_index = ((m != 15) && (m != 13));
11906 
11907                 if (n == 15)
11908                     return false;
11909             }
11910                 break;
11911 
11912             default:
11913                 return false;
11914         }
11915 
11916         RegisterInfo base_reg;
11917         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11918 
11919         uint32_t Rn = ReadCoreReg (n, &success);
11920         if (!success)
11921             return false;
11922 
11923         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11924         addr_t address = Rn;
11925         if ((address % alignment) != 0)
11926             return false;
11927 
11928         EmulateInstruction::Context context;
11929         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11930         if (wback)
11931         {
11932             uint32_t Rm = ReadCoreReg (m, &success);
11933             if (!success)
11934                 return false;
11935 
11936             uint32_t offset;
11937             if (register_index)
11938                 offset = Rm;
11939             else
11940                 offset = ebytes;
11941 
11942             context.type = eContextAdjustBaseRegister;
11943             context.SetRegisterPlusOffset (base_reg, offset);
11944 
11945             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11946                 return false;
11947         }
11948 
11949         // MemU[address,ebytes] = Elem[D[d],index,esize];
11950         uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11951         if (!success)
11952             return false;
11953 
11954         uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1,  index * esize);
11955 
11956         RegisterInfo data_reg;
11957         GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg);
11958         context.type = eContextRegisterStore;
11959         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11960 
11961         if (!MemUWrite (context, address, word, ebytes))
11962             return false;
11963     }
11964     return true;
11965 }
11966 
11967 // A8.6.309 VLD1 (single element to all lanes)
11968 // This instruction loads one element from memory into every element of one or two vectors.
11969 bool
11970 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding)
11971 {
11972 #if 0
11973     if ConditionPassed() then
11974         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11975         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11976         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11977         replicated_element = Replicate(MemU[address,ebytes], elements);
11978         for r = 0 to regs-1
11979             D[d+r] = replicated_element;
11980 #endif
11981 
11982     bool success = false;
11983 
11984     if (ConditionPassed (opcode))
11985     {
11986         uint32_t ebytes;
11987         uint32_t elements;
11988         uint32_t regs;
11989         uint32_t alignment;
11990         uint32_t d;
11991         uint32_t n;
11992         uint32_t m;
11993         bool wback;
11994         bool register_index;
11995 
11996         switch (encoding)
11997         {
11998             case eEncodingT1:
11999             case eEncodingA1:
12000             {
12001                 //if size == �11� || (size == �00� && a == �1�) then UNDEFINED;
12002                 uint32_t size = Bits32 (opcode, 7, 6);
12003                 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4)))
12004                     return false;
12005 
12006                 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2;
12007                 ebytes = 1 << size;
12008                 elements = 8 / ebytes;
12009                 if (BitIsClear (opcode, 5))
12010                     regs = 1;
12011                 else
12012                     regs = 2;
12013 
12014                 //alignment = if a == �0� then 1 else ebytes;
12015                 if (BitIsClear (opcode, 4))
12016                     alignment = 1;
12017                 else
12018                     alignment = ebytes;
12019 
12020                 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12021                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
12022                 n = Bits32 (opcode, 19, 16);
12023                 m = Bits32 (opcode, 3, 0);
12024 
12025                 //wback = (m != 15); register_index = (m != 15 && m != 13);
12026                 wback = (m != 15);
12027                 register_index = ((m != 15) && (m != 13));
12028 
12029                 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12030                 if ((d + regs) > 32)
12031                     return false;
12032 
12033                 if (n == 15)
12034                     return false;
12035             }
12036             break;
12037 
12038             default:
12039                 return false;
12040         }
12041 
12042         RegisterInfo base_reg;
12043         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12044 
12045         uint32_t Rn = ReadCoreReg (n, &success);
12046         if (!success)
12047             return false;
12048 
12049         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12050         addr_t address = Rn;
12051         if ((address % alignment) != 0)
12052             return false;
12053 
12054         EmulateInstruction::Context context;
12055         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12056         if (wback)
12057         {
12058             uint32_t Rm = ReadCoreReg (m, &success);
12059             if (!success)
12060                 return false;
12061 
12062             uint32_t offset;
12063             if (register_index)
12064                 offset = Rm;
12065             else
12066                 offset = ebytes;
12067 
12068             context.type = eContextAdjustBaseRegister;
12069             context.SetRegisterPlusOffset (base_reg, offset);
12070 
12071             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
12072                 return false;
12073         }
12074 
12075         // replicated_element = Replicate(MemU[address,ebytes], elements);
12076 
12077         context.type = eContextRegisterLoad;
12078         uint64_t word = MemURead (context, address, ebytes, 0, &success);
12079         if (!success)
12080             return false;
12081 
12082         uint64_t replicated_element = 0;
12083         uint32_t esize = ebytes * 8;
12084         for (uint32_t e = 0; e < elements; ++e)
12085             replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0);
12086 
12087         // for r = 0 to regs-1
12088         for (uint32_t r = 0; r < regs; ++r)
12089         {
12090             // D[d+r] = replicated_element;
12091             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element))
12092                 return false;
12093         }
12094     }
12095     return true;
12096 }
12097 
12098 // B6.2.13 SUBS PC, LR and related instructions
12099 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack.  It subtracts the
12100 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR.
12101 bool
12102 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding)
12103 {
12104 #if 0
12105     if ConditionPassed() then
12106         EncodingSpecificOperations();
12107         if CurrentInstrSet() == InstrSet_ThumbEE then
12108             UNPREDICTABLE;
12109         operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12110         case opcode of
12111             when0000result = R[n] AND operand2; // AND
12112             when0001result = R[n] EOR operand2; // EOR
12113             when0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12114             when0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12115             when0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12116             when0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12117             when0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12118             when0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12119             when1100result = R[n] OR operand2; // ORR
12120             when1101result = operand2; // MOV
12121             when1110result = R[n] AND NOT(operand2); // BIC
12122             when1111result = NOT(operand2); // MVN
12123         CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12124         BranchWritePC(result);
12125 #endif
12126 
12127     bool success = false;
12128 
12129     if (ConditionPassed (opcode))
12130     {
12131         uint32_t n;
12132         uint32_t m;
12133         uint32_t imm32;
12134         bool register_form;
12135         ARM_ShifterType shift_t;
12136         uint32_t shift_n;
12137         uint32_t code;
12138 
12139         switch (encoding)
12140         {
12141             case eEncodingT1:
12142                 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
12143                 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB
12144                 n = 14;
12145                 imm32 = Bits32 (opcode, 7, 0);
12146                 register_form = false;
12147                 code = 2;
12148 
12149                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12150                 if (InITBlock() && !LastInITBlock())
12151                     return false;
12152 
12153                 break;
12154 
12155             case eEncodingA1:
12156                 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12157                 n = Bits32 (opcode, 19, 16);
12158                 imm32 = ARMExpandImm (opcode);
12159                 register_form = false;
12160                 code = Bits32 (opcode, 24, 21);
12161 
12162                 break;
12163 
12164             case eEncodingA2:
12165                 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12166                 n = Bits32 (opcode, 19, 16);
12167                 m = Bits32 (opcode, 3, 0);
12168                 register_form = true;
12169 
12170                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12171                 shift_n = DecodeImmShiftARM (opcode, shift_t);
12172 
12173                 break;
12174 
12175             default:
12176                 return false;
12177         }
12178 
12179         // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12180         uint32_t operand2;
12181         if (register_form)
12182         {
12183             uint32_t Rm = ReadCoreReg (m, &success);
12184             if (!success)
12185                 return false;
12186 
12187             operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success);
12188             if (!success)
12189                 return false;
12190         }
12191         else
12192         {
12193             operand2 = imm32;
12194         }
12195 
12196         uint32_t Rn = ReadCoreReg (n, &success);
12197         if (!success)
12198             return false;
12199 
12200         AddWithCarryResult result;
12201 
12202         // case opcode of
12203         switch (code)
12204         {
12205             case 0: // when �0000�
12206                 // result = R[n] AND operand2; // AND
12207                 result.result = Rn & operand2;
12208                 break;
12209 
12210             case 1: // when �0001�
12211                 // result = R[n] EOR operand2; // EOR
12212                 result.result = Rn ^ operand2;
12213                 break;
12214 
12215             case 2: // when �0010�
12216                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12217                 result = AddWithCarry (Rn, ~(operand2), 1);
12218                 break;
12219 
12220             case 3: // when �0011�
12221                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12222                 result = AddWithCarry (~(Rn), operand2, 1);
12223                 break;
12224 
12225             case 4: // when �0100�
12226                 // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12227                 result = AddWithCarry (Rn, operand2, 0);
12228                 break;
12229 
12230             case 5: // when �0101�
12231                 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12232                 result = AddWithCarry (Rn, operand2, APSR_C);
12233                 break;
12234 
12235             case 6: // when �0110�
12236                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12237                 result = AddWithCarry (Rn, ~(operand2), APSR_C);
12238                 break;
12239 
12240             case 7: // when �0111�
12241                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12242                 result = AddWithCarry (~(Rn), operand2, APSR_C);
12243                 break;
12244 
12245             case 10: // when �1100�
12246                 // result = R[n] OR operand2; // ORR
12247                 result.result = Rn | operand2;
12248                 break;
12249 
12250             case 11: // when �1101�
12251                 // result = operand2; // MOV
12252                 result.result = operand2;
12253                 break;
12254 
12255             case 12: // when �1110�
12256                 // result = R[n] AND NOT(operand2); // BIC
12257                 result.result = Rn & ~(operand2);
12258                 break;
12259 
12260             case 15: // when �1111�
12261                 // result = NOT(operand2); // MVN
12262                 result.result = ~(operand2);
12263                 break;
12264 
12265             default:
12266                 return false;
12267         }
12268         // CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12269 
12270         // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for
12271         // the best.
12272         uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12273         if (!success)
12274             return false;
12275 
12276         CPSRWriteByInstr (spsr, 15, true);
12277 
12278         // BranchWritePC(result);
12279         EmulateInstruction::Context context;
12280         context.type = eContextAdjustPC;
12281         context.SetImmediate (result.result);
12282 
12283         BranchWritePC (context, result.result);
12284     }
12285     return true;
12286 }
12287 
12288 EmulateInstructionARM::ARMOpcode*
12289 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12290 {
12291     static ARMOpcode
12292     g_arm_opcodes[] =
12293     {
12294         //----------------------------------------------------------------------
12295         // Prologue instructions
12296         //----------------------------------------------------------------------
12297 
12298         // push register(s)
12299         { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12300         { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
12301 
12302         // set r7 to point to a stack offset
12303         { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
12304         { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12305         // copy the stack pointer to ip
12306         { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
12307         { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
12308         { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12309 
12310         // adjust the stack pointer
12311         { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12312         { 0x0fef0010, 0x004d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12313 
12314         // push one register
12315         // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12316         { 0x0e5f0000, 0x040d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
12317 
12318         // vector push consecutive extension register(s)
12319         { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12320         { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12321 
12322         //----------------------------------------------------------------------
12323         // Epilogue instructions
12324         //----------------------------------------------------------------------
12325 
12326         { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12327         { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12328         { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12329         { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12330 
12331         //----------------------------------------------------------------------
12332         // Supervisor Call (previously Software Interrupt)
12333         //----------------------------------------------------------------------
12334         { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12335 
12336         //----------------------------------------------------------------------
12337         // Branch instructions
12338         //----------------------------------------------------------------------
12339         { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
12340         // To resolve ambiguity, "blx <label>" should come before "bl <label>".
12341         { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12342         { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12343         { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12344         // for example, "bx lr"
12345         { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12346         // bxj
12347         { 0x0ffffff0, 0x012fff20, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12348 
12349         //----------------------------------------------------------------------
12350         // Data-processing instructions
12351         //----------------------------------------------------------------------
12352         // adc (immediate)
12353         { 0x0fe00000, 0x02a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12354         // adc (register)
12355         { 0x0fe00010, 0x00a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12356         // add (immediate)
12357         { 0x0fe00000, 0x02800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
12358         // add (register)
12359         { 0x0fe00010, 0x00800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12360         // add (register-shifted register)
12361         { 0x0fe00090, 0x00800010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12362         // adr
12363         { 0x0fff0000, 0x028f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12364         { 0x0fff0000, 0x024f0000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12365         // and (immediate)
12366         { 0x0fe00000, 0x02000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12367         // and (register)
12368         { 0x0fe00010, 0x00000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12369         // bic (immediate)
12370         { 0x0fe00000, 0x03c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12371         // bic (register)
12372         { 0x0fe00010, 0x01c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12373         // eor (immediate)
12374         { 0x0fe00000, 0x02200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12375         // eor (register)
12376         { 0x0fe00010, 0x00200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12377         // orr (immediate)
12378         { 0x0fe00000, 0x03800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12379         // orr (register)
12380         { 0x0fe00010, 0x01800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12381         // rsb (immediate)
12382         { 0x0fe00000, 0x02600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12383         // rsb (register)
12384         { 0x0fe00010, 0x00600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12385         // rsc (immediate)
12386         { 0x0fe00000, 0x02e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12387         // rsc (register)
12388         { 0x0fe00010, 0x00e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12389         // sbc (immediate)
12390         { 0x0fe00000, 0x02c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12391         // sbc (register)
12392         { 0x0fe00010, 0x00c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12393         // sub (immediate, ARM)
12394         { 0x0fe00000, 0x02400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
12395         // sub (sp minus immediate)
12396         { 0x0fef0000, 0x024d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12397         // sub (register)
12398         { 0x0fe00010, 0x00400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12399         // teq (immediate)
12400         { 0x0ff0f000, 0x03300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12401         // teq (register)
12402         { 0x0ff0f010, 0x01300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12403         // tst (immediate)
12404         { 0x0ff0f000, 0x03100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12405         // tst (register)
12406         { 0x0ff0f010, 0x01100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12407 
12408         // mov (immediate)
12409         { 0x0fef0000, 0x03a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12410         { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
12411         // mov (register)
12412         { 0x0fef0ff0, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12413         // mvn (immediate)
12414         { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12415         // mvn (register)
12416         { 0x0fef0010, 0x01e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12417         // cmn (immediate)
12418         { 0x0ff0f000, 0x03700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12419         // cmn (register)
12420         { 0x0ff0f010, 0x01700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12421         // cmp (immediate)
12422         { 0x0ff0f000, 0x03500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
12423         // cmp (register)
12424         { 0x0ff0f010, 0x01500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
12425         // asr (immediate)
12426         { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
12427         // asr (register)
12428         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
12429         // lsl (immediate)
12430         { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
12431         // lsl (register)
12432         { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
12433         // lsr (immediate)
12434         { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
12435         // lsr (register)
12436         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
12437         // rrx is a special case encoding of ror (immediate)
12438         { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
12439         // ror (immediate)
12440         { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
12441         // ror (register)
12442         { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
12443         // mul
12444         { 0x0fe000f0, 0x00000090, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
12445 
12446         // subs pc, lr and related instructions
12447         { 0x0e10f000, 0x0210f000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" },
12448         { 0x0e10f010, 0x0010f000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" },
12449 
12450         //----------------------------------------------------------------------
12451         // Load instructions
12452         //----------------------------------------------------------------------
12453         { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12454         { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
12455         { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12456         { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
12457         { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
12458         { 0x0e500010, 0x06100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
12459         { 0x0e5f0000, 0x045f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
12460         { 0xfe500010, 0x06500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
12461         { 0x0e5f00f0, 0x005f00b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12462         { 0x0e5000f0, 0x001000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"  },
12463         { 0x0e5000f0, 0x005000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
12464         { 0x0e5f00f0, 0x005f00d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
12465         { 0x0e5000f0, 0x001000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12466         { 0x0e5000f0, 0x005000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
12467         { 0x0e5f00f0, 0x005f00f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12468         { 0x0e5000f0, 0x001000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12469         { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
12470         { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12471         { 0x0e100f00, 0x0c100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12472         { 0x0e100f00, 0x0c100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12473         { 0x0f300f00, 0x0d100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12474         { 0x0f300f00, 0x0d100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12475         { 0xffb00000, 0xf4200000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12476         { 0xffb00300, 0xf4a00000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12477         { 0xffb00f00, 0xf4a00c00, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12478 
12479         //----------------------------------------------------------------------
12480         // Store instructions
12481         //----------------------------------------------------------------------
12482         { 0x0fd00000, 0x08800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12483         { 0x0fd00000, 0x08000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
12484         { 0x0fd00000, 0x09000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12485         { 0x0fd00000, 0x09800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
12486         { 0x0e500010, 0x06000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
12487         { 0x0e5000f0, 0x000000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
12488         { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
12489         { 0x0e500000, 0x04400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12490         { 0x0e500000, 0x04000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12491         { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
12492         { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12493         { 0x0e100f00, 0x0c000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12494         { 0x0e100f00, 0x0c000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12495         { 0x0f300f00, 0x0d000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
12496         { 0x0f300f00, 0x0d000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
12497         { 0xffb00000, 0xf4000000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12498         { 0xffb00300, 0xf4800000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12499 
12500         //----------------------------------------------------------------------
12501         // Other instructions
12502         //----------------------------------------------------------------------
12503         { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
12504         { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
12505         { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
12506         { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
12507         { 0xfe500000, 0xf8100000, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
12508 
12509     };
12510     static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes);
12511 
12512     for (size_t i=0; i<k_num_arm_opcodes; ++i)
12513     {
12514         if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
12515             (g_arm_opcodes[i].variants & arm_isa) != 0)
12516             return &g_arm_opcodes[i];
12517     }
12518     return NULL;
12519 }
12520 
12521 
12522 EmulateInstructionARM::ARMOpcode*
12523 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12524 {
12525 
12526     static ARMOpcode
12527     g_thumb_opcodes[] =
12528     {
12529         //----------------------------------------------------------------------
12530         // Prologue instructions
12531         //----------------------------------------------------------------------
12532 
12533         // push register(s)
12534         { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12535         { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
12536         { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
12537 
12538         // set r7 to point to a stack offset
12539         { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
12540         // copy the stack pointer to r7
12541         { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
12542         // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
12543         { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
12544 
12545         // PC-relative load into register (see also EmulateADDSPRm)
12546         { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
12547 
12548         // adjust the stack pointer
12549         { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
12550         { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
12551         { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
12552         { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
12553         { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12554 
12555         // vector push consecutive extension register(s)
12556         { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12557         { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12558 
12559         //----------------------------------------------------------------------
12560         // Epilogue instructions
12561         //----------------------------------------------------------------------
12562 
12563         { 0xfffff800, 0x0000a800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
12564         { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
12565         { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12566         { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
12567         { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
12568         { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12569         { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12570 
12571         //----------------------------------------------------------------------
12572         // Supervisor Call (previously Software Interrupt)
12573         //----------------------------------------------------------------------
12574         { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
12575 
12576         //----------------------------------------------------------------------
12577         // If Then makes up to four following instructions conditional.
12578         //----------------------------------------------------------------------
12579         // The next 5 opcode _must_ come before the if then instruction
12580         { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"},
12581         { 0xffffffff, 0x0000bf10, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
12582         { 0xffffffff, 0x0000bf20, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
12583         { 0xffffffff, 0x0000bf30, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
12584         { 0xffffffff, 0x0000bf40, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
12585         { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
12586 
12587         //----------------------------------------------------------------------
12588         // Branch instructions
12589         //----------------------------------------------------------------------
12590         // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
12591         { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
12592         { 0xfffff800, 0x0000e000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
12593         { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
12594         { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
12595         // J1 == J2 == 1
12596         { 0xf800d000, 0xf000d000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12597         // J1 == J2 == 1
12598         { 0xf800d001, 0xf000c000, ARMV5_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12599         { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12600         // for example, "bx lr"
12601         { 0xffffff87, 0x00004700, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12602         // bxj
12603         { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12604         // compare and branch
12605         { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
12606         // table branch byte
12607         { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
12608         // table branch halfword
12609         { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
12610 
12611         //----------------------------------------------------------------------
12612         // Data-processing instructions
12613         //----------------------------------------------------------------------
12614         // adc (immediate)
12615         { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
12616         // adc (register)
12617         { 0xffffffc0, 0x00004140, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
12618         { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12619         // add (register)
12620         { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
12621         // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
12622         { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
12623         // adr
12624         { 0xfffff800, 0x0000a000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12625         { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12626         { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12627         // and (immediate)
12628         { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
12629         // and (register)
12630         { 0xffffffc0, 0x00004000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
12631         { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12632         // bic (immediate)
12633         { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
12634         // bic (register)
12635         { 0xffffffc0, 0x00004380, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
12636         { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12637         // eor (immediate)
12638         { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
12639         // eor (register)
12640         { 0xffffffc0, 0x00004040, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
12641         { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12642         // orr (immediate)
12643         { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
12644         // orr (register)
12645         { 0xffffffc0, 0x00004300, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
12646         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12647         // rsb (immediate)
12648         { 0xffffffc0, 0x00004240, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
12649         { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
12650         // rsb (register)
12651         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12652         // sbc (immediate)
12653         { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12654         // sbc (register)
12655         { 0xffffffc0, 0x00004180, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
12656         { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12657         // add (immediate, Thumb)
12658         { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
12659         { 0xfffff800, 0x00003000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
12660         { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
12661         { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
12662         // sub (immediate, Thumb)
12663         { 0xfffffe00, 0x00001e00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
12664         { 0xfffff800, 0x00003800, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
12665         { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
12666         { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
12667         // sub (sp minus immediate)
12668         { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
12669         { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
12670         // sub (register)
12671         { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
12672         { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
12673         // teq (immediate)
12674         { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
12675         // teq (register)
12676         { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12677         // tst (immediate)
12678         { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
12679         // tst (register)
12680         { 0xffffffc0, 0x00004200, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
12681         { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
12682 
12683 
12684         // move from high register to high register
12685         { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
12686         // move from low register to low register
12687         { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
12688         // mov{s}<c>.w <Rd>, <Rm>
12689         { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
12690         // move immediate
12691         { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
12692         { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
12693         { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
12694         // mvn (immediate)
12695         { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
12696         // mvn (register)
12697         { 0xffffffc0, 0x000043c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
12698         { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
12699         // cmn (immediate)
12700         { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12701         // cmn (register)
12702         { 0xffffffc0, 0x000042c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
12703         { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12704         // cmp (immediate)
12705         { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
12706         { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
12707         // cmp (register) (Rn and Rm both from r0-r7)
12708         { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12709         // cmp (register) (Rn and Rm not both from r0-r7)
12710         { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12711         // asr (immediate)
12712         { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
12713         { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
12714         // asr (register)
12715         { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
12716         { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12717         // lsl (immediate)
12718         { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
12719         { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
12720         // lsl (register)
12721         { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
12722         { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
12723         // lsr (immediate)
12724         { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
12725         { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
12726         // lsr (register)
12727         { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
12728         { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12729         // rrx is a special case encoding of ror (immediate)
12730         { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
12731         // ror (immediate)
12732         { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
12733         // ror (register)
12734         { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
12735         { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
12736         // mul
12737         { 0xffffffc0, 0x00004340, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
12738         // mul
12739         { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
12740 
12741         // subs pc, lr and related instructions
12742         { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" },
12743 
12744         //----------------------------------------------------------------------
12745         // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table;
12746         // otherwise the wrong instructions will be selected.
12747         //----------------------------------------------------------------------
12748 
12749         { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
12750         { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
12751 
12752         //----------------------------------------------------------------------
12753         // Load instructions
12754         //----------------------------------------------------------------------
12755         { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12756         { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
12757         { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12758         { 0xfffff800, 0x00006800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
12759         { 0xfffff800, 0x00009800, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
12760         { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
12761         { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
12762                   // Thumb2 PC-relative load into register
12763         { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
12764         { 0xfffffe00, 0x00005800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
12765         { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
12766         { 0xfffff800, 0x00007800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
12767         { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12768         { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" },
12769         { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
12770         { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
12771         { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
12772         { 0xfffff800, 0x00008800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"  },
12773         { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12774         { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"  },
12775         { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12776         { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
12777         { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12778         { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
12779         { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12780         { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
12781         { 0xfffffe00, 0x00005600, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
12782         { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"  },
12783         { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
12784         { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12785         { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12786         { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
12787         { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12788         { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
12789         { 0xfe100f00, 0xec100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12790         { 0xfe100f00, 0xec100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
12791         { 0xffe00f00, 0xed100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12792         { 0xff300f00, 0xed100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
12793         { 0xffb00000, 0xf9200000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12794         { 0xffb00300, 0xf9a00000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12795         { 0xffb00f00, 0xf9a00c00, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12796 
12797         //----------------------------------------------------------------------
12798         // Store instructions
12799         //----------------------------------------------------------------------
12800         { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12801         { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
12802         { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12803         { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
12804         { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
12805         { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
12806         { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
12807         { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
12808         { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
12809         { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
12810         { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
12811         { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
12812         { 0xfffffe00, 0x00005200, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
12813         { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12814         { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
12815         { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
12816         { 0xfe100f00, 0xec000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12817         { 0xfea00f00, 0xec000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12818         { 0xff300f00, 0xed000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12819         { 0xff300f00, 0xed000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12820         { 0xffb00000, 0xf9000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12821         { 0xffb00300, 0xf9800000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12822 
12823         //----------------------------------------------------------------------
12824         // Other instructions
12825         //----------------------------------------------------------------------
12826         { 0xffffffc0, 0x0000b240, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
12827         { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12828         { 0xffffffc0, 0x0000b200, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
12829         { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12830         { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
12831         { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12832         { 0xffffffc0, 0x0000b280, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
12833         { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12834     };
12835 
12836     const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes);
12837     for (size_t i=0; i<k_num_thumb_opcodes; ++i)
12838     {
12839         if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
12840             (g_thumb_opcodes[i].variants & arm_isa) != 0)
12841             return &g_thumb_opcodes[i];
12842     }
12843     return NULL;
12844 }
12845 
12846 bool
12847 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
12848 {
12849     m_arch = arch;
12850     m_arm_isa = 0;
12851     const char *arch_cstr = arch.GetArchitectureName ();
12852     if (arch_cstr)
12853     {
12854         if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
12855         else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
12856         else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
12857         else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
12858         else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
12859         else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
12860         else if (0 == ::strcasecmp(arch_cstr, "armv7s"))    m_arm_isa = ARMv7S;
12861         else if (0 == ::strcasecmp(arch_cstr, "arm"))       m_arm_isa = ARMvAll;
12862         else if (0 == ::strcasecmp(arch_cstr, "thumb"))     m_arm_isa = ARMvAll;
12863         else if (0 == ::strncasecmp(arch_cstr,"armv4", 5))  m_arm_isa = ARMv4;
12864         else if (0 == ::strncasecmp(arch_cstr,"armv6", 5))  m_arm_isa = ARMv6;
12865         else if (0 == ::strncasecmp(arch_cstr,"armv7", 5))  m_arm_isa = ARMv7;
12866         else if (0 == ::strncasecmp(arch_cstr,"armv8", 5))  m_arm_isa = ARMv8;
12867     }
12868     return m_arm_isa != 0;
12869 }
12870 
12871 bool
12872 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
12873 {
12874     if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
12875     {
12876         if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
12877             m_opcode_mode = eModeThumb;
12878         else
12879         {
12880             AddressClass addr_class = inst_addr.GetAddressClass();
12881 
12882             if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
12883                 m_opcode_mode = eModeARM;
12884             else if (addr_class == eAddressClassCodeAlternateISA)
12885                 m_opcode_mode = eModeThumb;
12886             else
12887                 return false;
12888         }
12889         if (m_opcode_mode == eModeThumb)
12890             m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
12891         else
12892             m_opcode_cpsr = CPSR_MODE_USR;
12893         return true;
12894     }
12895     return false;
12896 }
12897 
12898 bool
12899 EmulateInstructionARM::ReadInstruction ()
12900 {
12901     bool success = false;
12902     m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
12903     if (success)
12904     {
12905         addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
12906         if (success)
12907         {
12908             Context read_inst_context;
12909             read_inst_context.type = eContextReadOpcode;
12910             read_inst_context.SetNoArgs ();
12911 
12912             if (m_opcode_cpsr & MASK_CPSR_T)
12913             {
12914                 m_opcode_mode = eModeThumb;
12915                 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
12916 
12917                 if (success)
12918                 {
12919                     if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
12920                     {
12921                         m_opcode.SetOpcode16 (thumb_opcode, GetByteOrder());
12922                     }
12923                     else
12924                     {
12925                         m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success), GetByteOrder());
12926                     }
12927                 }
12928             }
12929             else
12930             {
12931                 m_opcode_mode = eModeARM;
12932                 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success), GetByteOrder());
12933             }
12934         }
12935     }
12936     if (!success)
12937     {
12938         m_opcode_mode = eModeInvalid;
12939         m_addr = LLDB_INVALID_ADDRESS;
12940     }
12941     return success;
12942 }
12943 
12944 uint32_t
12945 EmulateInstructionARM::ArchVersion ()
12946 {
12947     return m_arm_isa;
12948 }
12949 
12950 bool
12951 EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional)
12952 {
12953    // If we are ignoring conditions, then always return true.
12954    // this allows us to iterate over disassembly code and still
12955    // emulate an instruction even if we don't have all the right
12956    // bits set in the CPSR register...
12957     if (m_ignore_conditions)
12958         return true;
12959 
12960     if (is_conditional)
12961         *is_conditional = true;
12962 
12963     const uint32_t cond = CurrentCond (opcode);
12964 
12965     if (cond == UINT32_MAX)
12966         return false;
12967 
12968     bool result = false;
12969     switch (UnsignedBits(cond, 3, 1))
12970     {
12971     case 0:
12972 		if (m_opcode_cpsr == 0)
12973 			result = true;
12974         else
12975             result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
12976 		break;
12977     case 1:
12978         if (m_opcode_cpsr == 0)
12979             result = true;
12980         else
12981             result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
12982 		break;
12983     case 2:
12984         if (m_opcode_cpsr == 0)
12985             result = true;
12986         else
12987             result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
12988 		break;
12989     case 3:
12990         if (m_opcode_cpsr == 0)
12991             result = true;
12992         else
12993             result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
12994 		break;
12995     case 4:
12996         if (m_opcode_cpsr == 0)
12997             result = true;
12998         else
12999             result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13000 		break;
13001     case 5:
13002         if (m_opcode_cpsr == 0)
13003             result = true;
13004         else
13005 		{
13006             bool n = (m_opcode_cpsr & MASK_CPSR_N);
13007             bool v = (m_opcode_cpsr & MASK_CPSR_V);
13008             result = n == v;
13009         }
13010         break;
13011     case 6:
13012         if (m_opcode_cpsr == 0)
13013             result = true;
13014         else
13015 		{
13016             bool n = (m_opcode_cpsr & MASK_CPSR_N);
13017             bool v = (m_opcode_cpsr & MASK_CPSR_V);
13018             result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13019         }
13020         break;
13021     case 7:
13022         // Always execute (cond == 0b1110, or the special 0b1111 which gives
13023         // opcodes different meanings, but always means execution happens.
13024         if (is_conditional)
13025             *is_conditional = false;
13026         result = true;
13027         break;
13028     }
13029 
13030     if (cond & 1)
13031         result = !result;
13032     return result;
13033 }
13034 
13035 uint32_t
13036 EmulateInstructionARM::CurrentCond (const uint32_t opcode)
13037 {
13038     switch (m_opcode_mode)
13039     {
13040     case eModeInvalid:
13041         break;
13042 
13043     case eModeARM:
13044         return UnsignedBits(opcode, 31, 28);
13045 
13046     case eModeThumb:
13047         // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
13048         // 'cond' field of the encoding.
13049         {
13050             const uint32_t byte_size = m_opcode.GetByteSize();
13051             if (byte_size == 2)
13052             {
13053                 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f)
13054                     return Bits32(opcode, 11, 7);
13055             }
13056             else if (byte_size == 4)
13057             {
13058                 if (Bits32(opcode, 31, 27) == 0x1e &&
13059                     Bits32(opcode, 15, 14) == 0x02 &&
13060                     Bits32(opcode, 12, 12) == 0x00 &&
13061                     Bits32(opcode, 25, 22) <= 0x0d)
13062                 {
13063                     return Bits32(opcode, 25, 22);
13064                 }
13065             }
13066             else
13067                 // We have an invalid thumb instruction, let's bail out.
13068                 break;
13069 
13070             return m_it_session.GetCond();
13071         }
13072     }
13073     return UINT32_MAX;  // Return invalid value
13074 }
13075 
13076 bool
13077 EmulateInstructionARM::InITBlock()
13078 {
13079     return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13080 }
13081 
13082 bool
13083 EmulateInstructionARM::LastInITBlock()
13084 {
13085     return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13086 }
13087 
13088 bool
13089 EmulateInstructionARM::BadMode (uint32_t mode)
13090 {
13091 
13092     switch (mode)
13093     {
13094         case 16: return false; // '10000'
13095         case 17: return false; // '10001'
13096         case 18: return false; // '10010'
13097         case 19: return false; // '10011'
13098         case 22: return false; // '10110'
13099         case 23: return false; // '10111'
13100         case 27: return false; // '11011'
13101         case 31: return false; // '11111'
13102         default: return true;
13103     }
13104     return true;
13105 }
13106 
13107 bool
13108 EmulateInstructionARM::CurrentModeIsPrivileged ()
13109 {
13110     uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
13111 
13112     if (BadMode (mode))
13113         return false;
13114 
13115     if (mode == 16)
13116         return false;
13117 
13118     return true;
13119 }
13120 
13121 void
13122 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
13123 {
13124     bool privileged = CurrentModeIsPrivileged();
13125 
13126     uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20;
13127 
13128     if (BitIsSet (bytemask, 3))
13129     {
13130         tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
13131         if (affect_execstate)
13132             tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
13133     }
13134 
13135     if (BitIsSet (bytemask, 2))
13136     {
13137         tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
13138     }
13139 
13140     if (BitIsSet (bytemask, 1))
13141     {
13142         if (affect_execstate)
13143             tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
13144         tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
13145         if (privileged)
13146             tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
13147     }
13148 
13149     if (BitIsSet (bytemask, 0))
13150     {
13151         if (privileged)
13152             tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
13153         if (affect_execstate)
13154             tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
13155         if (privileged)
13156             tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
13157     }
13158 
13159     m_opcode_cpsr = tmp_cpsr;
13160 }
13161 
13162 
13163 bool
13164 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
13165 {
13166     addr_t target;
13167 
13168     // Check the current instruction set.
13169     if (CurrentInstrSet() == eModeARM)
13170         target = addr & 0xfffffffc;
13171     else
13172         target = addr & 0xfffffffe;
13173 
13174     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13175         return false;
13176 
13177     return true;
13178 }
13179 
13180 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
13181 bool
13182 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
13183 {
13184     addr_t target;
13185     // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
13186     // we want to record it and issue a WriteRegister callback so the clients
13187     // can track the mode changes accordingly.
13188     bool cpsr_changed = false;
13189 
13190     if (BitIsSet(addr, 0))
13191     {
13192         if (CurrentInstrSet() != eModeThumb)
13193         {
13194             SelectInstrSet(eModeThumb);
13195             cpsr_changed = true;
13196         }
13197         target = addr & 0xfffffffe;
13198         context.SetISA (eModeThumb);
13199     }
13200     else if (BitIsClear(addr, 1))
13201     {
13202         if (CurrentInstrSet() != eModeARM)
13203         {
13204             SelectInstrSet(eModeARM);
13205             cpsr_changed = true;
13206         }
13207         target = addr & 0xfffffffc;
13208         context.SetISA (eModeARM);
13209     }
13210     else
13211         return false; // address<1:0> == '10' => UNPREDICTABLE
13212 
13213     if (cpsr_changed)
13214     {
13215         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13216             return false;
13217     }
13218     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13219         return false;
13220 
13221     return true;
13222 }
13223 
13224 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
13225 bool
13226 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
13227 {
13228     if (ArchVersion() >= ARMv5T)
13229         return BXWritePC(context, addr);
13230     else
13231         return BranchWritePC((const Context)context, addr);
13232 }
13233 
13234 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
13235 bool
13236 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
13237 {
13238     if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
13239         return BXWritePC(context, addr);
13240     else
13241         return BranchWritePC((const Context)context, addr);
13242 }
13243 
13244 EmulateInstructionARM::Mode
13245 EmulateInstructionARM::CurrentInstrSet ()
13246 {
13247     return m_opcode_mode;
13248 }
13249 
13250 // Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
13251 // ReadInstruction() is performed.  This function has a side effect of updating
13252 // the m_new_inst_cpsr member variable if necessary.
13253 bool
13254 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
13255 {
13256     m_new_inst_cpsr = m_opcode_cpsr;
13257     switch (arm_or_thumb)
13258     {
13259     default:
13260         return false;
13261     case eModeARM:
13262         // Clear the T bit.
13263         m_new_inst_cpsr &= ~MASK_CPSR_T;
13264         break;
13265     case eModeThumb:
13266         // Set the T bit.
13267         m_new_inst_cpsr |= MASK_CPSR_T;
13268         break;
13269     }
13270     return true;
13271 }
13272 
13273 // This function returns TRUE if the processor currently provides support for
13274 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
13275 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
13276 bool
13277 EmulateInstructionARM::UnalignedSupport()
13278 {
13279     return (ArchVersion() >= ARMv7);
13280 }
13281 
13282 // The main addition and subtraction instructions can produce status information
13283 // about both unsigned carry and signed overflow conditions.  This status
13284 // information can be used to synthesize multi-word additions and subtractions.
13285 EmulateInstructionARM::AddWithCarryResult
13286 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
13287 {
13288     uint32_t result;
13289     uint8_t carry_out;
13290     uint8_t overflow;
13291 
13292     uint64_t unsigned_sum = x + y + carry_in;
13293     int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
13294 
13295     result = UnsignedBits(unsigned_sum, 31, 0);
13296 //    carry_out = (result == unsigned_sum ? 0 : 1);
13297     overflow = ((int32_t)result == signed_sum ? 0 : 1);
13298 
13299     if (carry_in)
13300         carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0;
13301     else
13302         carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0;
13303 
13304     AddWithCarryResult res = { result, carry_out, overflow };
13305     return res;
13306 }
13307 
13308 uint32_t
13309 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
13310 {
13311     lldb::RegisterKind reg_kind;
13312     uint32_t reg_num;
13313     switch (num)
13314     {
13315     case SP_REG:
13316         reg_kind = eRegisterKindGeneric;
13317         reg_num  = LLDB_REGNUM_GENERIC_SP;
13318         break;
13319     case LR_REG:
13320         reg_kind = eRegisterKindGeneric;
13321         reg_num  = LLDB_REGNUM_GENERIC_RA;
13322         break;
13323     case PC_REG:
13324         reg_kind = eRegisterKindGeneric;
13325         reg_num  = LLDB_REGNUM_GENERIC_PC;
13326         break;
13327     default:
13328         if (num < SP_REG)
13329         {
13330             reg_kind = eRegisterKindDWARF;
13331             reg_num  = dwarf_r0 + num;
13332         }
13333         else
13334         {
13335             //assert(0 && "Invalid register number");
13336             *success = false;
13337             return UINT32_MAX;
13338         }
13339         break;
13340     }
13341 
13342     // Read our register.
13343     uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
13344 
13345     // When executing an ARM instruction , PC reads as the address of the current
13346     // instruction plus 8.
13347     // When executing a Thumb instruction , PC reads as the address of the current
13348     // instruction plus 4.
13349     if (num == 15)
13350     {
13351         if (CurrentInstrSet() == eModeARM)
13352             val += 8;
13353         else
13354             val += 4;
13355     }
13356 
13357     return val;
13358 }
13359 
13360 // Write the result to the ARM core register Rd, and optionally update the
13361 // condition flags based on the result.
13362 //
13363 // This helper method tries to encapsulate the following pseudocode from the
13364 // ARM Architecture Reference Manual:
13365 //
13366 // if d == 15 then         // Can only occur for encoding A1
13367 //     ALUWritePC(result); // setflags is always FALSE here
13368 // else
13369 //     R[d] = result;
13370 //     if setflags then
13371 //         APSR.N = result<31>;
13372 //         APSR.Z = IsZeroBit(result);
13373 //         APSR.C = carry;
13374 //         // APSR.V unchanged
13375 //
13376 // In the above case, the API client does not pass in the overflow arg, which
13377 // defaults to ~0u.
13378 bool
13379 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
13380                                                   const uint32_t result,
13381                                                   const uint32_t Rd,
13382                                                   bool setflags,
13383                                                   const uint32_t carry,
13384                                                   const uint32_t overflow)
13385 {
13386     if (Rd == 15)
13387     {
13388         if (!ALUWritePC (context, result))
13389             return false;
13390     }
13391     else
13392     {
13393         lldb::RegisterKind reg_kind;
13394         uint32_t reg_num;
13395         switch (Rd)
13396         {
13397         case SP_REG:
13398             reg_kind = eRegisterKindGeneric;
13399             reg_num  = LLDB_REGNUM_GENERIC_SP;
13400             break;
13401         case LR_REG:
13402             reg_kind = eRegisterKindGeneric;
13403             reg_num  = LLDB_REGNUM_GENERIC_RA;
13404             break;
13405         default:
13406             reg_kind = eRegisterKindDWARF;
13407             reg_num  = dwarf_r0 + Rd;
13408         }
13409         if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
13410             return false;
13411         if (setflags)
13412             return WriteFlags (context, result, carry, overflow);
13413     }
13414     return true;
13415 }
13416 
13417 // This helper method tries to encapsulate the following pseudocode from the
13418 // ARM Architecture Reference Manual:
13419 //
13420 // APSR.N = result<31>;
13421 // APSR.Z = IsZeroBit(result);
13422 // APSR.C = carry;
13423 // APSR.V = overflow
13424 //
13425 // Default arguments can be specified for carry and overflow parameters, which means
13426 // not to update the respective flags.
13427 bool
13428 EmulateInstructionARM::WriteFlags (Context &context,
13429                                    const uint32_t result,
13430                                    const uint32_t carry,
13431                                    const uint32_t overflow)
13432 {
13433     m_new_inst_cpsr = m_opcode_cpsr;
13434     SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
13435     SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
13436     if (carry != ~0u)
13437         SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
13438     if (overflow != ~0u)
13439         SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
13440     if (m_new_inst_cpsr != m_opcode_cpsr)
13441     {
13442         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13443             return false;
13444     }
13445     return true;
13446 }
13447 
13448 bool
13449 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
13450 {
13451     // Advance the ITSTATE bits to their values for the next instruction.
13452     if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
13453         m_it_session.ITAdvance();
13454 
13455     ARMOpcode *opcode_data = NULL;
13456 
13457     if (m_opcode_mode == eModeThumb)
13458         opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13459     else if (m_opcode_mode == eModeARM)
13460         opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13461 
13462     if (opcode_data == NULL)
13463         return false;
13464 
13465     const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
13466     m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
13467 
13468     bool success = false;
13469     if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
13470     {
13471         m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF,
13472                                                 dwarf_cpsr,
13473                                                 0,
13474                                                 &success);
13475     }
13476 
13477     // Only return false if we are unable to read the CPSR if we care about conditions
13478     if (success == false && m_ignore_conditions == false)
13479         return false;
13480 
13481     uint32_t orig_pc_value = 0;
13482     if (auto_advance_pc)
13483     {
13484         orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13485         if (!success)
13486             return false;
13487     }
13488 
13489     // Call the Emulate... function.
13490     success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
13491     if (!success)
13492         return false;
13493 
13494     if (auto_advance_pc)
13495     {
13496         uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13497         if (!success)
13498             return false;
13499 
13500         if (auto_advance_pc && (after_pc_value == orig_pc_value))
13501         {
13502             if (opcode_data->size == eSize32)
13503                 after_pc_value += 4;
13504             else if (opcode_data->size == eSize16)
13505                 after_pc_value += 2;
13506 
13507             EmulateInstruction::Context context;
13508             context.type = eContextAdvancePC;
13509             context.SetNoArgs();
13510             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
13511                 return false;
13512 
13513         }
13514     }
13515     return true;
13516 }
13517 
13518 bool
13519 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data)
13520 {
13521     if (!test_data)
13522     {
13523         out_stream->Printf ("TestEmulation: Missing test data.\n");
13524         return false;
13525     }
13526 
13527     static ConstString opcode_key ("opcode");
13528     static ConstString before_key ("before_state");
13529     static ConstString after_key ("after_state");
13530 
13531     OptionValueSP value_sp = test_data->GetValueForKey (opcode_key);
13532 
13533     uint32_t test_opcode;
13534     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64))
13535     {
13536         out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n");
13537         return false;
13538     }
13539     test_opcode = value_sp->GetUInt64Value ();
13540 
13541     if (arch.GetTriple().getArch() == llvm::Triple::arm)
13542     {
13543         m_opcode_mode = eModeARM;
13544         m_opcode.SetOpcode32 (test_opcode, GetByteOrder());
13545     }
13546     else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
13547     {
13548         m_opcode_mode = eModeThumb;
13549         if (test_opcode < 0x10000)
13550             m_opcode.SetOpcode16 (test_opcode, GetByteOrder());
13551         else
13552             m_opcode.SetOpcode32 (test_opcode, GetByteOrder());
13553 
13554     }
13555     else
13556     {
13557         out_stream->Printf ("TestEmulation:  Invalid arch.\n");
13558         return false;
13559     }
13560 
13561     EmulationStateARM before_state;
13562     EmulationStateARM after_state;
13563 
13564     value_sp = test_data->GetValueForKey (before_key);
13565     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13566     {
13567         out_stream->Printf ("TestEmulation:  Failed to find 'before' state.\n");
13568         return false;
13569     }
13570 
13571     OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary ();
13572     if (!before_state.LoadStateFromDictionary (state_dictionary))
13573     {
13574         out_stream->Printf ("TestEmulation:  Failed loading 'before' state.\n");
13575         return false;
13576     }
13577 
13578     value_sp = test_data->GetValueForKey (after_key);
13579     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13580     {
13581         out_stream->Printf ("TestEmulation:  Failed to find 'after' state.\n");
13582         return false;
13583     }
13584 
13585     state_dictionary = value_sp->GetAsDictionary ();
13586     if (!after_state.LoadStateFromDictionary (state_dictionary))
13587     {
13588         out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n");
13589         return false;
13590     }
13591 
13592     SetBaton ((void *) &before_state);
13593     SetCallbacks (&EmulationStateARM::ReadPseudoMemory,
13594                   &EmulationStateARM::WritePseudoMemory,
13595                   &EmulationStateARM::ReadPseudoRegister,
13596                   &EmulationStateARM::WritePseudoRegister);
13597 
13598     bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC);
13599     if (!success)
13600     {
13601         out_stream->Printf ("TestEmulation:  EvaluateInstruction() failed.\n");
13602         return false;
13603     }
13604 
13605     success = before_state.CompareState (after_state);
13606     if (!success)
13607         out_stream->Printf ("TestEmulation:  'before' and 'after' states do not match.\n");
13608 
13609     return success;
13610 }
13611 //
13612 //
13613 //const char *
13614 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
13615 //{
13616 //    if (reg_kind == eRegisterKindGeneric)
13617 //    {
13618 //        switch (reg_num)
13619 //        {
13620 //        case LLDB_REGNUM_GENERIC_PC:    return "pc";
13621 //        case LLDB_REGNUM_GENERIC_SP:    return "sp";
13622 //        case LLDB_REGNUM_GENERIC_FP:    return "fp";
13623 //        case LLDB_REGNUM_GENERIC_RA:    return "lr";
13624 //        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
13625 //        default: return NULL;
13626 //        }
13627 //    }
13628 //    else if (reg_kind == eRegisterKindDWARF)
13629 //    {
13630 //        return GetARMDWARFRegisterName (reg_num);
13631 //    }
13632 //    return NULL;
13633 //}
13634 //
13635 bool
13636 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
13637 {
13638     unwind_plan.Clear();
13639     unwind_plan.SetRegisterKind (eRegisterKindDWARF);
13640 
13641     UnwindPlan::RowSP row(new UnwindPlan::Row);
13642 
13643     // Our previous Call Frame Address is the stack pointer
13644     row->SetCFARegister (dwarf_sp);
13645 
13646     // Our previous PC is in the LR
13647     row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true);
13648     unwind_plan.AppendRow (row);
13649 
13650     // All other registers are the same.
13651 
13652     unwind_plan.SetSourceName ("EmulateInstructionARM");
13653     unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
13654     unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
13655     return true;
13656 }
13657