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 #if 0 // unreachable because if true
9877         else
9878         {
9879             // R[d] = 1;
9880             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
9881                 return false;
9882         }
9883 #endif // unreachable because if true
9884     }
9885     return true;
9886 }
9887 
9888 // A8.6.197 STRB (immediate, ARM)
9889 bool
9890 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9891 {
9892 #if 0
9893     if ConditionPassed() then
9894         EncodingSpecificOperations();
9895         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9896         address = if index then offset_addr else R[n];
9897         MemU[address,1] = R[t]<7:0>;
9898         if wback then R[n] = offset_addr;
9899 #endif
9900 
9901     bool success = false;
9902 
9903     if (ConditionPassed(opcode))
9904     {
9905         uint32_t t;
9906         uint32_t n;
9907         uint32_t imm32;
9908         bool index;
9909         bool add;
9910         bool wback;
9911 
9912         switch (encoding)
9913         {
9914             case eEncodingA1:
9915                 // if P == �0� && W == �1� then SEE STRBT;
9916                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9917                 t = Bits32 (opcode, 15, 12);
9918                 n = Bits32 (opcode, 19, 16);
9919                 imm32 = Bits32 (opcode, 11, 0);
9920 
9921                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9922                 index = BitIsSet (opcode, 24);
9923                 add = BitIsSet (opcode, 23);
9924                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9925 
9926                 // if t == 15 then UNPREDICTABLE;
9927                 if (t == 15)
9928                     return false;
9929 
9930                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9931                 if (wback && ((n == 15) || (n == t)))
9932                     return false;
9933 
9934                 break;
9935 
9936             default:
9937                 return false;
9938         }
9939 
9940         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9941         uint32_t Rn = ReadCoreReg (n, &success);
9942         if (!success)
9943             return false;
9944 
9945         addr_t offset_addr;
9946         if (add)
9947             offset_addr = Rn + imm32;
9948         else
9949             offset_addr = Rn - imm32;
9950 
9951         // address = if index then offset_addr else R[n];
9952         addr_t address;
9953         if (index)
9954             address = offset_addr;
9955         else
9956             address = Rn;
9957 
9958         // MemU[address,1] = R[t]<7:0>;
9959         uint32_t Rt = ReadCoreReg (t, &success);
9960         if (!success)
9961             return false;
9962 
9963         RegisterInfo base_reg;
9964         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9965         RegisterInfo data_reg;
9966         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9967         EmulateInstruction::Context context;
9968         context.type = eContextRegisterStore;
9969         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
9970 
9971         if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1))
9972             return false;
9973 
9974         // if wback then R[n] = offset_addr;
9975         if (wback)
9976         {
9977             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
9978                 return false;
9979         }
9980     }
9981     return true;
9982 }
9983 
9984 // A8.6.194 STR (immediate, ARM)
9985 bool
9986 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding)
9987 {
9988 #if 0
9989     if ConditionPassed() then
9990         EncodingSpecificOperations();
9991         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9992         address = if index then offset_addr else R[n];
9993         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
9994         if wback then R[n] = offset_addr;
9995 #endif
9996 
9997     bool success = false;
9998 
9999     if (ConditionPassed(opcode))
10000     {
10001         uint32_t t;
10002         uint32_t n;
10003         uint32_t imm32;
10004         bool index;
10005         bool add;
10006         bool wback;
10007 
10008         const uint32_t addr_byte_size = GetAddressByteSize();
10009 
10010         switch (encoding)
10011         {
10012             case eEncodingA1:
10013                 // if P == �0� && W == �1� then SEE STRT;
10014                 // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH;
10015                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10016                 t = Bits32 (opcode, 15, 12);
10017                 n = Bits32 (opcode, 19, 16);
10018                 imm32 = Bits32 (opcode, 11, 0);
10019 
10020                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10021                 index = BitIsSet (opcode, 24);
10022                 add = BitIsSet (opcode, 23);
10023                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10024 
10025                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10026                 if (wback && ((n == 15) || (n == t)))
10027                     return false;
10028 
10029                 break;
10030 
10031             default:
10032                 return false;
10033         }
10034 
10035         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10036         uint32_t Rn = ReadCoreReg (n, &success);
10037         if (!success)
10038             return false;
10039 
10040         addr_t offset_addr;
10041         if (add)
10042             offset_addr = Rn + imm32;
10043         else
10044             offset_addr = Rn - imm32;
10045 
10046         // address = if index then offset_addr else R[n];
10047         addr_t address;
10048         if (index)
10049             address = offset_addr;
10050         else
10051             address = Rn;
10052 
10053         RegisterInfo base_reg;
10054         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10055         RegisterInfo data_reg;
10056         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10057         EmulateInstruction::Context context;
10058         context.type = eContextRegisterStore;
10059         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10060 
10061         // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10062         uint32_t Rt = ReadCoreReg (t, &success);
10063         if (!success)
10064             return false;
10065 
10066         if (t == 15)
10067         {
10068             uint32_t pc_value = ReadCoreReg (PC_REG, &success);
10069             if (!success)
10070                 return false;
10071 
10072             if (!MemUWrite (context, address, pc_value, addr_byte_size))
10073                 return false;
10074         }
10075         else
10076         {
10077             if (!MemUWrite (context, address, Rt, addr_byte_size))
10078                   return false;
10079         }
10080 
10081         // if wback then R[n] = offset_addr;
10082         if (wback)
10083         {
10084             context.type = eContextAdjustBaseRegister;
10085             context.SetImmediate (offset_addr);
10086 
10087             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10088                 return false;
10089         }
10090     }
10091     return true;
10092 }
10093 
10094 // A8.6.66 LDRD (immediate)
10095 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two
10096 // words from memory, and writes them to two registers.  It can use offset, post-indexed, or pre-indexed addressing.
10097 bool
10098 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding)
10099 {
10100 #if 0
10101     if ConditionPassed() then
10102         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10103         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10104         address = if index then offset_addr else R[n];
10105         R[t] = MemA[address,4];
10106         R[t2] = MemA[address+4,4];
10107         if wback then R[n] = offset_addr;
10108 #endif
10109 
10110     bool success = false;
10111 
10112     if (ConditionPassed(opcode))
10113     {
10114         uint32_t t;
10115         uint32_t t2;
10116         uint32_t n;
10117         uint32_t imm32;
10118         bool index;
10119         bool add;
10120         bool wback;
10121 
10122         switch (encoding)
10123         {
10124             case eEncodingT1:
10125                 //if P == �0� && W == �0� then SEE �Related encodings�;
10126                 //if Rn == �1111� then SEE LDRD (literal);
10127                 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10128                 t = Bits32 (opcode, 15, 12);
10129                 t2 = Bits32 (opcode, 11, 8);
10130                 n = Bits32 (opcode, 19, 16);
10131                 imm32 = Bits32 (opcode, 7, 0) << 2;
10132 
10133                 //index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10134                 index = BitIsSet (opcode, 24);
10135                 add = BitIsSet (opcode, 23);
10136                 wback = BitIsSet (opcode, 21);
10137 
10138                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10139                 if (wback && ((n == t) || (n == t2)))
10140                     return false;
10141 
10142                 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10143                 if (BadReg (t) || BadReg (t2) || (t == t2))
10144                     return false;
10145 
10146                 break;
10147 
10148             case eEncodingA1:
10149                 //if Rn == �1111� then SEE LDRD (literal);
10150                 //if Rt<0> == �1� then UNPREDICTABLE;
10151                 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10152                 t = Bits32 (opcode, 15, 12);
10153                 if (BitIsSet (t, 0))
10154                     return false;
10155                 t2 = t + 1;
10156                 n = Bits32 (opcode, 19, 16);
10157                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10158 
10159                 //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10160                 index = BitIsSet (opcode, 24);
10161                 add = BitIsSet (opcode, 23);
10162                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10163 
10164                 //if P == �0� && W == �1� then UNPREDICTABLE;
10165                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10166                     return false;
10167 
10168                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10169                 if (wback && ((n == t) || (n == t2)))
10170                     return false;
10171 
10172                 //if t2 == 15 then UNPREDICTABLE;
10173                 if (t2 == 15)
10174                     return false;
10175 
10176                 break;
10177 
10178             default:
10179                 return false;
10180         }
10181 
10182         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10183         uint32_t Rn = ReadCoreReg (n, &success);
10184         if (!success)
10185             return false;
10186 
10187         addr_t offset_addr;
10188         if (add)
10189                   offset_addr = Rn + imm32;
10190         else
10191             offset_addr = Rn - imm32;
10192 
10193         //address = if index then offset_addr else R[n];
10194         addr_t address;
10195         if (index)
10196             address = offset_addr;
10197         else
10198             address = Rn;
10199 
10200         //R[t] = MemA[address,4];
10201         RegisterInfo base_reg;
10202         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10203 
10204         EmulateInstruction::Context context;
10205         context.type = eContextRegisterLoad;
10206         context.SetRegisterPlusOffset (base_reg, address - Rn);
10207 
10208         const uint32_t addr_byte_size = GetAddressByteSize();
10209         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10210         if (!success)
10211             return false;
10212 
10213         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10214             return false;
10215 
10216         //R[t2] = MemA[address+4,4];
10217 
10218         context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10219         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10220         if (!success)
10221             return false;
10222 
10223         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10224             return false;
10225 
10226         //if wback then R[n] = offset_addr;
10227         if (wback)
10228         {
10229             context.type = eContextAdjustBaseRegister;
10230             context.SetAddress (offset_addr);
10231 
10232             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10233                 return false;
10234         }
10235     }
10236     return true;
10237 }
10238 
10239 // A8.6.68 LDRD (register)
10240 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two
10241 // words from memory, and writes them to two registers.  It can use offset, post-indexed or pre-indexed addressing.
10242 bool
10243 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding)
10244 {
10245 #if 0
10246     if ConditionPassed() then
10247         EncodingSpecificOperations();
10248         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10249         address = if index then offset_addr else R[n];
10250         R[t] = MemA[address,4];
10251         R[t2] = MemA[address+4,4];
10252         if wback then R[n] = offset_addr;
10253 #endif
10254 
10255     bool success = false;
10256 
10257     if (ConditionPassed(opcode))
10258     {
10259         uint32_t t;
10260         uint32_t t2;
10261         uint32_t n;
10262         uint32_t m;
10263         bool index;
10264         bool add;
10265         bool wback;
10266 
10267         switch (encoding)
10268         {
10269             case eEncodingA1:
10270                 // if Rt<0> == �1� then UNPREDICTABLE;
10271                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10272                 t = Bits32 (opcode, 15, 12);
10273                 if (BitIsSet (t, 0))
10274                     return false;
10275                 t2 = t + 1;
10276                 n = Bits32 (opcode, 19, 16);
10277                 m = Bits32 (opcode, 3, 0);
10278 
10279                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10280                 index = BitIsSet (opcode, 24);
10281                 add = BitIsSet (opcode, 23);
10282                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10283 
10284                 // if P == �0� && W == �1� then UNPREDICTABLE;
10285                   if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10286                   return false;
10287 
10288                 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10289                   if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10290                   return false;
10291 
10292                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10293                   if (wback && ((n == 15) || (n == t) || (n == t2)))
10294                   return false;
10295 
10296                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10297                 if ((ArchVersion() < 6) && wback && (m == n))
10298                   return false;
10299                 break;
10300 
10301             default:
10302                 return false;
10303         }
10304 
10305         uint32_t Rn = ReadCoreReg (n, &success);
10306         if (!success)
10307             return false;
10308         RegisterInfo base_reg;
10309         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10310 
10311         uint32_t Rm = ReadCoreReg (m, &success);
10312         if (!success)
10313             return false;
10314         RegisterInfo offset_reg;
10315         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10316 
10317         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10318         addr_t offset_addr;
10319         if (add)
10320             offset_addr = Rn + Rm;
10321         else
10322             offset_addr = Rn - Rm;
10323 
10324         // address = if index then offset_addr else R[n];
10325         addr_t address;
10326         if (index)
10327             address = offset_addr;
10328         else
10329             address = Rn;
10330 
10331         EmulateInstruction::Context context;
10332         context.type = eContextRegisterLoad;
10333         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
10334 
10335         // R[t] = MemA[address,4];
10336         const uint32_t addr_byte_size = GetAddressByteSize();
10337         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10338         if (!success)
10339             return false;
10340 
10341         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10342             return false;
10343 
10344         // R[t2] = MemA[address+4,4];
10345 
10346         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10347         if (!success)
10348             return false;
10349 
10350         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10351             return false;
10352 
10353         // if wback then R[n] = offset_addr;
10354         if (wback)
10355         {
10356             context.type = eContextAdjustBaseRegister;
10357             context.SetAddress (offset_addr);
10358 
10359             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10360                 return false;
10361         }
10362     }
10363     return true;
10364 }
10365 
10366 // A8.6.200 STRD (immediate)
10367 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and
10368 // stores two words from two registers to memory.  It can use offset, post-indexed, or pre-indexed addressing.
10369 bool
10370 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding)
10371 {
10372 #if 0
10373     if ConditionPassed() then
10374         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10375         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10376         address = if index then offset_addr else R[n];
10377         MemA[address,4] = R[t];
10378         MemA[address+4,4] = R[t2];
10379         if wback then R[n] = offset_addr;
10380 #endif
10381 
10382     bool success = false;
10383 
10384     if (ConditionPassed(opcode))
10385     {
10386         uint32_t t;
10387         uint32_t t2;
10388         uint32_t n;
10389         uint32_t imm32;
10390         bool index;
10391         bool add;
10392         bool wback;
10393 
10394         switch (encoding)
10395         {
10396             case eEncodingT1:
10397                 // if P == �0� && W == �0� then SEE �Related encodings�;
10398                 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10399                 t = Bits32 (opcode, 15, 12);
10400                 t2 = Bits32 (opcode, 11, 8);
10401                 n = Bits32 (opcode, 19, 16);
10402                 imm32 = Bits32 (opcode, 7, 0) << 2;
10403 
10404                 // index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10405                 index = BitIsSet (opcode, 24);
10406                 add = BitIsSet (opcode, 23);
10407                 wback = BitIsSet (opcode, 21);
10408 
10409                 // if wback && (n == t || n == t2) then UNPREDICTABLE;
10410                 if (wback && ((n == t) || (n == t2)))
10411                     return false;
10412 
10413                 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10414                 if ((n == 15) || BadReg (t) || BadReg (t2))
10415                     return false;
10416 
10417                 break;
10418 
10419             case eEncodingA1:
10420                 // if Rt<0> == �1� then UNPREDICTABLE;
10421                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10422                 t = Bits32 (opcode, 15, 12);
10423                 if (BitIsSet (t, 0))
10424                     return false;
10425 
10426                 t2 = t + 1;
10427                 n = Bits32 (opcode, 19, 16);
10428                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10429 
10430                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10431                 index = BitIsSet (opcode, 24);
10432                 add = BitIsSet (opcode, 23);
10433                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10434 
10435                 // if P == �0� && W == �1� then UNPREDICTABLE;
10436                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10437                     return false;
10438 
10439                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10440                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10441                     return false;
10442 
10443                 // if t2 == 15 then UNPREDICTABLE;
10444                 if (t2 == 15)
10445                     return false;
10446 
10447                 break;
10448 
10449             default:
10450                 return false;
10451         }
10452 
10453         RegisterInfo base_reg;
10454         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10455 
10456         uint32_t Rn = ReadCoreReg (n, &success);
10457         if (!success)
10458             return false;
10459 
10460         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10461         addr_t offset_addr;
10462         if (add)
10463             offset_addr = Rn + imm32;
10464         else
10465             offset_addr = Rn - imm32;
10466 
10467         //address = if index then offset_addr else R[n];
10468         addr_t address;
10469         if (index)
10470             address = offset_addr;
10471         else
10472             address = Rn;
10473 
10474         //MemA[address,4] = R[t];
10475         RegisterInfo data_reg;
10476         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10477 
10478         uint32_t data = ReadCoreReg (t, &success);
10479         if (!success)
10480             return false;
10481 
10482         EmulateInstruction::Context context;
10483         context.type = eContextRegisterStore;
10484         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10485 
10486         const uint32_t addr_byte_size = GetAddressByteSize();
10487 
10488         if (!MemAWrite (context, address, data, addr_byte_size))
10489             return false;
10490 
10491         //MemA[address+4,4] = R[t2];
10492         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10493         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10494 
10495         data = ReadCoreReg (t2, &success);
10496         if (!success)
10497             return false;
10498 
10499         if (!MemAWrite (context, address + 4, data, addr_byte_size))
10500             return false;
10501 
10502         //if wback then R[n] = offset_addr;
10503         if (wback)
10504         {
10505             context.type = eContextAdjustBaseRegister;
10506             context.SetAddress (offset_addr);
10507 
10508             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10509                 return false;
10510         }
10511     }
10512     return true;
10513 }
10514 
10515 
10516 // A8.6.201 STRD (register)
10517 bool
10518 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding)
10519 {
10520 #if 0
10521     if ConditionPassed() then
10522         EncodingSpecificOperations();
10523         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10524         address = if index then offset_addr else R[n];
10525         MemA[address,4] = R[t];
10526         MemA[address+4,4] = R[t2];
10527         if wback then R[n] = offset_addr;
10528 #endif
10529 
10530     bool success = false;
10531 
10532     if (ConditionPassed(opcode))
10533     {
10534         uint32_t t;
10535         uint32_t t2;
10536         uint32_t n;
10537         uint32_t m;
10538         bool index;
10539         bool add;
10540         bool wback;
10541 
10542         switch (encoding)
10543         {
10544             case eEncodingA1:
10545                 // if Rt<0> == �1� then UNPREDICTABLE;
10546                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10547                 t = Bits32 (opcode, 15, 12);
10548                 if (BitIsSet (t, 0))
10549                    return false;
10550 
10551                 t2 = t+1;
10552                 n = Bits32 (opcode, 19, 16);
10553                 m = Bits32 (opcode, 3, 0);
10554 
10555                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10556                 index = BitIsSet (opcode, 24);
10557                 add = BitIsSet (opcode, 23);
10558                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10559 
10560                 // if P == �0� && W == �1� then UNPREDICTABLE;
10561                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10562                    return false;
10563 
10564                 // if t2 == 15 || m == 15 then UNPREDICTABLE;
10565                 if ((t2 == 15) || (m == 15))
10566                    return false;
10567 
10568                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10569                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10570                    return false;
10571 
10572                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10573                 if ((ArchVersion() < 6) && wback && (m == n))
10574                    return false;
10575 
10576                 break;
10577 
10578             default:
10579                 return false;
10580         }
10581 
10582         RegisterInfo base_reg;
10583         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10584         RegisterInfo offset_reg;
10585         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10586         RegisterInfo data_reg;
10587 
10588         uint32_t Rn = ReadCoreReg (n, &success);
10589         if (!success)
10590             return false;
10591 
10592         uint32_t Rm = ReadCoreReg (m, &success);
10593         if (!success)
10594             return false;
10595 
10596         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10597         addr_t offset_addr;
10598         if (add)
10599             offset_addr = Rn + Rm;
10600         else
10601             offset_addr = Rn - Rm;
10602 
10603         // address = if index then offset_addr else R[n];
10604         addr_t address;
10605         if (index)
10606             address = offset_addr;
10607         else
10608             address = Rn;
10609                           // MemA[address,4] = R[t];
10610         uint32_t Rt = ReadCoreReg (t, &success);
10611         if (!success)
10612             return false;
10613 
10614         EmulateInstruction::Context context;
10615         context.type = eContextRegisterStore;
10616         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10617         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10618 
10619         const uint32_t addr_byte_size = GetAddressByteSize();
10620 
10621         if (!MemAWrite (context, address, Rt, addr_byte_size))
10622             return false;
10623 
10624         // MemA[address+4,4] = R[t2];
10625         uint32_t Rt2 = ReadCoreReg (t2, &success);
10626         if (!success)
10627             return false;
10628 
10629         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10630 
10631         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10632 
10633         if (!MemAWrite (context, address + 4, Rt2, addr_byte_size))
10634             return false;
10635 
10636         // if wback then R[n] = offset_addr;
10637         if (wback)
10638         {
10639             context.type = eContextAdjustBaseRegister;
10640             context.SetAddress (offset_addr);
10641 
10642             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10643                 return false;
10644 
10645         }
10646     }
10647     return true;
10648 }
10649 
10650 // A8.6.319 VLDM
10651 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from
10652 // an ARM core register.
10653 bool
10654 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding)
10655 {
10656 #if 0
10657     if ConditionPassed() then
10658         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10659         address = if add then R[n] else R[n]-imm32;
10660         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10661         for r = 0 to regs-1
10662             if single_regs then
10663                 S[d+r] = MemA[address,4]; address = address+4;
10664             else
10665                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10666                 // Combine the word-aligned words in the correct order for current endianness.
10667                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10668 #endif
10669 
10670     bool success = false;
10671 
10672     if (ConditionPassed(opcode))
10673     {
10674         bool single_regs;
10675         bool add;
10676         bool wback;
10677         uint32_t d;
10678         uint32_t n;
10679         uint32_t imm32;
10680         uint32_t regs;
10681 
10682         switch (encoding)
10683         {
10684             case eEncodingT1:
10685             case eEncodingA1:
10686                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10687                 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10688                 // if P == �1� && W == �0� then SEE VLDR;
10689                 // if P == U && W == �1� then UNDEFINED;
10690                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10691                     return false;
10692 
10693                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10694                 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10695                 single_regs = false;
10696                 add = BitIsSet (opcode, 23);
10697                 wback = BitIsSet (opcode, 21);
10698 
10699                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10700                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10701                 n = Bits32 (opcode, 19, 16);
10702                 imm32 = Bits32 (opcode, 7, 0) << 2;
10703 
10704                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�.
10705                 regs = Bits32 (opcode, 7, 0) / 2;
10706 
10707                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10708                 if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
10709                     return false;
10710 
10711                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10712                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10713                     return false;
10714 
10715                 break;
10716 
10717             case eEncodingT2:
10718             case eEncodingA2:
10719                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10720                 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10721                 // if P == �1� && W == �0� then SEE VLDR;
10722                 // if P == U && W == �1� then UNDEFINED;
10723                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10724                     return false;
10725 
10726                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10727                 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10728                 single_regs = true;
10729                 add = BitIsSet (opcode, 23);
10730                 wback = BitIsSet (opcode, 21);
10731                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10732                 n = Bits32 (opcode, 19, 16);
10733 
10734                 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10735                 imm32 = Bits32 (opcode, 7, 0) << 2;
10736                 regs = Bits32 (opcode, 7, 0);
10737 
10738                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10739                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10740                     return false;
10741 
10742                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10743                 if ((regs == 0) || ((d + regs) > 32))
10744                     return false;
10745                 break;
10746 
10747             default:
10748                 return false;
10749         }
10750 
10751         RegisterInfo base_reg;
10752         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10753 
10754         uint32_t Rn = ReadCoreReg (n, &success);
10755         if (!success)
10756             return false;
10757 
10758         // address = if add then R[n] else R[n]-imm32;
10759         addr_t address;
10760         if (add)
10761             address = Rn;
10762         else
10763             address = Rn - imm32;
10764 
10765         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10766         EmulateInstruction::Context context;
10767 
10768         if (wback)
10769         {
10770             uint32_t value;
10771             if (add)
10772                 value = Rn + imm32;
10773             else
10774                 value = Rn - imm32;
10775 
10776             context.type = eContextAdjustBaseRegister;
10777             context.SetImmediateSigned (value - Rn);
10778             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10779                 return false;
10780 
10781         }
10782 
10783         const uint32_t addr_byte_size = GetAddressByteSize();
10784         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10785 
10786         context.type = eContextRegisterLoad;
10787 
10788         // for r = 0 to regs-1
10789         for (uint32_t r = 0; r < regs; ++r)
10790         {
10791             if (single_regs)
10792             {
10793                 // S[d+r] = MemA[address,4]; address = address+4;
10794                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10795 
10796                 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10797                 if (!success)
10798                     return false;
10799 
10800                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10801                     return false;
10802 
10803                 address = address + 4;
10804             }
10805             else
10806             {
10807                 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10808                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10809                 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10810                 if (!success)
10811                     return false;
10812 
10813                 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10814                 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10815                 if (!success)
10816                     return false;
10817 
10818                 address = address + 8;
10819                 // // Combine the word-aligned words in the correct order for current endianness.
10820                 // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10821                 uint64_t data;
10822                 if (GetByteOrder() == eByteOrderBig)
10823                 {
10824                     data = word1;
10825                     data = (data << 32) | word2;
10826                 }
10827                 else
10828                 {
10829                     data = word2;
10830                     data = (data << 32) | word1;
10831                 }
10832 
10833                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10834                     return false;
10835             }
10836         }
10837     }
10838     return true;
10839 }
10840 
10841 // A8.6.399 VSTM
10842 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an
10843 // ARM core register.
10844 bool
10845 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding)
10846 {
10847 #if 0
10848     if ConditionPassed() then
10849         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10850         address = if add then R[n] else R[n]-imm32;
10851         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10852         for r = 0 to regs-1
10853             if single_regs then
10854                 MemA[address,4] = S[d+r]; address = address+4;
10855             else
10856                 // Store as two word-aligned words in the correct order for current endianness.
10857                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10858                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10859                 address = address+8;
10860 #endif
10861 
10862     bool success = false;
10863 
10864     if (ConditionPassed (opcode))
10865     {
10866         bool single_regs;
10867         bool add;
10868         bool wback;
10869         uint32_t d;
10870         uint32_t n;
10871         uint32_t imm32;
10872         uint32_t regs;
10873 
10874         switch (encoding)
10875         {
10876             case eEncodingT1:
10877             case eEncodingA1:
10878                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10879                 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10880                 // if P == �1� && W == �0� then SEE VSTR;
10881                 // if P == U && W == �1� then UNDEFINED;
10882                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10883                     return false;
10884 
10885                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10886                 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10887                 single_regs = false;
10888                 add = BitIsSet (opcode, 23);
10889                 wback = BitIsSet (opcode, 21);
10890 
10891                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10892                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10893                 n = Bits32 (opcode, 19, 16);
10894                 imm32 = Bits32 (opcode, 7, 0) << 2;
10895 
10896                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�.
10897                 regs = Bits32 (opcode, 7, 0) / 2;
10898 
10899                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10900                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10901                     return false;
10902 
10903                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10904                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10905                     return false;
10906 
10907                 break;
10908 
10909             case eEncodingT2:
10910             case eEncodingA2:
10911                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10912                 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10913                 // if P == �1� && W == �0� then SEE VSTR;
10914                 // if P == U && W == �1� then UNDEFINED;
10915                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10916                     return false;
10917 
10918                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10919                 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10920                 single_regs = true;
10921                 add = BitIsSet (opcode, 23);
10922                 wback = BitIsSet (opcode, 21);
10923                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10924                 n = Bits32 (opcode, 19, 16);
10925 
10926                 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10927                 imm32 = Bits32 (opcode, 7, 0) << 2;
10928                 regs = Bits32 (opcode, 7, 0);
10929 
10930                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10931                 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM)))
10932                     return false;
10933 
10934                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10935                 if ((regs == 0) || ((d + regs) > 32))
10936                     return false;
10937 
10938                 break;
10939 
10940             default:
10941                 return false;
10942         }
10943 
10944         RegisterInfo base_reg;
10945         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10946 
10947         uint32_t Rn = ReadCoreReg (n, &success);
10948         if (!success)
10949             return false;
10950 
10951         // address = if add then R[n] else R[n]-imm32;
10952         addr_t address;
10953         if (add)
10954             address = Rn;
10955         else
10956             address = Rn - imm32;
10957 
10958         EmulateInstruction::Context context;
10959         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10960         if (wback)
10961         {
10962             uint32_t value;
10963             if (add)
10964                 value = Rn + imm32;
10965             else
10966                 value = Rn - imm32;
10967 
10968             context.type = eContextAdjustBaseRegister;
10969             context.SetRegisterPlusOffset (base_reg, value - Rn);
10970 
10971             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10972                 return false;
10973         }
10974 
10975         const uint32_t addr_byte_size = GetAddressByteSize();
10976         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10977 
10978         context.type = eContextRegisterStore;
10979         // for r = 0 to regs-1
10980         for (uint32_t r = 0; r < regs; ++r)
10981         {
10982 
10983             if (single_regs)
10984             {
10985                 // MemA[address,4] = S[d+r]; address = address+4;
10986                 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10987                 if (!success)
10988                     return false;
10989 
10990                 RegisterInfo data_reg;
10991                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
10992                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10993                 if (!MemAWrite (context, address, data, addr_byte_size))
10994                     return false;
10995 
10996                 address = address + 4;
10997             }
10998             else
10999             {
11000                 // // Store as two word-aligned words in the correct order for current endianness.
11001                 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
11002                 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
11003                 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
11004                 if (!success)
11005                     return false;
11006 
11007                 RegisterInfo data_reg;
11008                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
11009 
11010                 if (GetByteOrder() == eByteOrderBig)
11011                 {
11012                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11013                     if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11014                         return false;
11015 
11016                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11017                     if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size))
11018                         return false;
11019                 }
11020                 else
11021                 {
11022                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11023                     if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11024                         return false;
11025 
11026                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11027                     if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11028                         return false;
11029                 }
11030                 // address = address+8;
11031                 address = address + 8;
11032             }
11033         }
11034     }
11035     return true;
11036 }
11037 
11038 // A8.6.320
11039 // This instruction loads a single extension register from memory, using an address from an ARM core register, with
11040 // an optional offset.
11041 bool
11042 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
11043 {
11044 #if 0
11045     if ConditionPassed() then
11046         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11047         base = if n == 15 then Align(PC,4) else R[n];
11048         address = if add then (base + imm32) else (base - imm32);
11049         if single_reg then
11050             S[d] = MemA[address,4];
11051         else
11052             word1 = MemA[address,4]; word2 = MemA[address+4,4];
11053             // Combine the word-aligned words in the correct order for current endianness.
11054             D[d] = if BigEndian() then word1:word2 else word2:word1;
11055 #endif
11056 
11057     bool success = false;
11058 
11059     if (ConditionPassed (opcode))
11060     {
11061         bool single_reg;
11062         bool add;
11063         uint32_t imm32;
11064         uint32_t d;
11065         uint32_t n;
11066 
11067         switch (encoding)
11068         {
11069             case eEncodingT1:
11070             case eEncodingA1:
11071                 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11072                 single_reg = false;
11073                 add = BitIsSet (opcode, 23);
11074                 imm32 = Bits32 (opcode, 7, 0) << 2;
11075 
11076                 // d = UInt(D:Vd); n = UInt(Rn);
11077                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11078                 n = Bits32 (opcode, 19, 16);
11079 
11080                 break;
11081 
11082             case eEncodingT2:
11083             case eEncodingA2:
11084                 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11085                 single_reg = true;
11086                 add = BitIsSet (opcode, 23);
11087                 imm32 = Bits32 (opcode, 7, 0) << 2;
11088 
11089                 // d = UInt(Vd:D); n = UInt(Rn);
11090                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11091                 n = Bits32 (opcode, 19, 16);
11092 
11093                 break;
11094 
11095             default:
11096                 return false;
11097         }
11098         RegisterInfo base_reg;
11099         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11100 
11101         uint32_t Rn = ReadCoreReg (n, &success);
11102         if (!success)
11103             return false;
11104 
11105         // base = if n == 15 then Align(PC,4) else R[n];
11106         uint32_t base;
11107         if (n == 15)
11108             base = AlignPC (Rn);
11109         else
11110             base = Rn;
11111 
11112         // address = if add then (base + imm32) else (base - imm32);
11113         addr_t address;
11114         if (add)
11115             address = base + imm32;
11116         else
11117             address = base - imm32;
11118 
11119         const uint32_t addr_byte_size = GetAddressByteSize();
11120         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11121 
11122         EmulateInstruction::Context context;
11123         context.type = eContextRegisterLoad;
11124         context.SetRegisterPlusOffset (base_reg, address - base);
11125 
11126         if (single_reg)
11127         {
11128             // S[d] = MemA[address,4];
11129             uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
11130             if (!success)
11131                 return false;
11132 
11133             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data))
11134                 return false;
11135         }
11136         else
11137         {
11138             // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11139             uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
11140             if (!success)
11141                 return false;
11142 
11143             context.SetRegisterPlusOffset (base_reg, (address + 4) - base);
11144             uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
11145             if (!success)
11146                 return false;
11147             // // Combine the word-aligned words in the correct order for current endianness.
11148             // D[d] = if BigEndian() then word1:word2 else word2:word1;
11149             uint64_t data64;
11150             if (GetByteOrder() == eByteOrderBig)
11151             {
11152                 data64 = word1;
11153                 data64 = (data64 << 32) | word2;
11154             }
11155             else
11156             {
11157                 data64 = word2;
11158                 data64 = (data64 << 32) | word1;
11159             }
11160 
11161             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64))
11162                 return false;
11163         }
11164     }
11165     return true;
11166 }
11167 
11168 // A8.6.400 VSTR
11169 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an
11170 // optional offset.
11171 bool
11172 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
11173 {
11174 #if 0
11175     if ConditionPassed() then
11176         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11177         address = if add then (R[n] + imm32) else (R[n] - imm32);
11178         if single_reg then
11179             MemA[address,4] = S[d];
11180         else
11181             // Store as two word-aligned words in the correct order for current endianness.
11182             MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11183             MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11184 #endif
11185 
11186     bool success = false;
11187 
11188     if (ConditionPassed (opcode))
11189     {
11190         bool single_reg;
11191         bool add;
11192         uint32_t imm32;
11193         uint32_t d;
11194         uint32_t n;
11195 
11196         switch (encoding)
11197         {
11198             case eEncodingT1:
11199             case eEncodingA1:
11200                 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11201                 single_reg = false;
11202                 add = BitIsSet (opcode, 23);
11203                 imm32 = Bits32 (opcode, 7, 0) << 2;
11204 
11205                 // d = UInt(D:Vd); n = UInt(Rn);
11206                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11207                 n = Bits32 (opcode, 19, 16);
11208 
11209                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11210                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11211                     return false;
11212 
11213                 break;
11214 
11215             case eEncodingT2:
11216             case eEncodingA2:
11217                 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11218                 single_reg = true;
11219                 add = BitIsSet (opcode, 23);
11220                 imm32 = Bits32 (opcode, 7, 0) << 2;
11221 
11222                 // d = UInt(Vd:D); n = UInt(Rn);
11223                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11224                 n = Bits32 (opcode, 19, 16);
11225 
11226                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11227                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11228                     return false;
11229 
11230                 break;
11231 
11232             default:
11233                 return false;
11234         }
11235 
11236         RegisterInfo base_reg;
11237         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11238 
11239         uint32_t Rn = ReadCoreReg (n, &success);
11240         if (!success)
11241             return false;
11242 
11243         // address = if add then (R[n] + imm32) else (R[n] - imm32);
11244         addr_t address;
11245         if (add)
11246             address = Rn + imm32;
11247         else
11248             address = Rn - imm32;
11249 
11250         const uint32_t addr_byte_size = GetAddressByteSize();
11251         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11252 
11253         RegisterInfo data_reg;
11254         GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg);
11255         EmulateInstruction::Context context;
11256         context.type = eContextRegisterStore;
11257         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11258 
11259         if (single_reg)
11260         {
11261             // MemA[address,4] = S[d];
11262             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11263             if (!success)
11264                 return false;
11265 
11266             if (!MemAWrite (context, address, data, addr_byte_size))
11267                 return false;
11268         }
11269         else
11270         {
11271             // // Store as two word-aligned words in the correct order for current endianness.
11272             // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11273             // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11274             uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11275             if (!success)
11276                 return false;
11277 
11278             if (GetByteOrder() == eByteOrderBig)
11279             {
11280                 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11281                     return false;
11282 
11283                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11284                 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size))
11285                     return false;
11286             }
11287             else
11288             {
11289                 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11290                     return false;
11291 
11292                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11293                 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11294                     return false;
11295             }
11296         }
11297     }
11298     return true;
11299 }
11300 
11301 // A8.6.307 VLDI1 (multiple single elements)
11302 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving.  Every
11303 // element of each register is loaded.
11304 bool
11305 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding)
11306 {
11307 #if 0
11308     if ConditionPassed() then
11309         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11310         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11311         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11312         for r = 0 to regs-1
11313             for e = 0 to elements-1
11314                 Elem[D[d+r],e,esize] = MemU[address,ebytes];
11315                 address = address + ebytes;
11316 #endif
11317 
11318     bool success = false;
11319 
11320     if (ConditionPassed (opcode))
11321     {
11322         uint32_t regs;
11323         uint32_t alignment;
11324         uint32_t ebytes;
11325         uint32_t esize;
11326         uint32_t elements;
11327         uint32_t d;
11328         uint32_t n;
11329         uint32_t m;
11330         bool wback;
11331         bool register_index;
11332 
11333         switch (encoding)
11334         {
11335             case eEncodingT1:
11336             case eEncodingA1:
11337             {
11338                 // case type of
11339                     // when �0111�
11340                         // regs = 1; if align<1> == �1� then UNDEFINED;
11341                     // when �1010�
11342                         // regs = 2; if align == �11� then UNDEFINED;
11343                     // when �0110�
11344                         // regs = 3; if align<1> == �1� then UNDEFINED;
11345                     // when �0010�
11346                         // regs = 4;
11347                     // otherwise
11348                         // SEE �Related encodings�;
11349                 uint32_t type = Bits32 (opcode, 11, 8);
11350                 uint32_t align = Bits32 (opcode, 5, 4);
11351                 if (type == 7) // '0111'
11352                 {
11353                     regs = 1;
11354                     if (BitIsSet (align, 1))
11355                         return false;
11356                 }
11357                 else if (type == 10) // '1010'
11358                 {
11359                     regs = 2;
11360                     if (align == 3)
11361                         return false;
11362 
11363                 }
11364                 else if (type == 6) // '0110'
11365                 {
11366                     regs = 3;
11367                     if (BitIsSet (align, 1))
11368                         return false;
11369                 }
11370                 else if (type == 2) // '0010'
11371                 {
11372                     regs = 4;
11373                 }
11374                 else
11375                     return false;
11376 
11377                 // alignment = if align == �00� then 1 else 4 << UInt(align);
11378                 if (align == 0)
11379                     alignment = 1;
11380                 else
11381                     alignment = 4 << align;
11382 
11383                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11384                 ebytes = 1 << Bits32 (opcode, 7, 6);
11385                 esize = 8 * ebytes;
11386                 elements = 8 / ebytes;
11387 
11388                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11389                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11390                 n = Bits32 (opcode, 19, 15);
11391                 m = Bits32 (opcode, 3, 0);
11392 
11393                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11394                 wback = (m != 15);
11395                 register_index = ((m != 15) && (m != 13));
11396 
11397                 // if d+regs > 32 then UNPREDICTABLE;
11398                 if ((d + regs) > 32)
11399                     return false;
11400             }
11401                 break;
11402 
11403             default:
11404                 return false;
11405         }
11406 
11407         RegisterInfo base_reg;
11408         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11409 
11410         uint32_t Rn = ReadCoreReg (n, &success);
11411         if (!success)
11412             return false;
11413 
11414         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11415         addr_t address = Rn;
11416         if ((address % alignment) != 0)
11417             return false;
11418 
11419         EmulateInstruction::Context context;
11420         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11421         if (wback)
11422         {
11423             uint32_t Rm = ReadCoreReg (m, &success);
11424             if (!success)
11425                 return false;
11426 
11427             uint32_t offset;
11428             if (register_index)
11429                 offset = Rm;
11430             else
11431                 offset = 8 * regs;
11432 
11433             uint32_t value = Rn + offset;
11434             context.type = eContextAdjustBaseRegister;
11435             context.SetRegisterPlusOffset (base_reg, offset);
11436 
11437             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11438                 return false;
11439 
11440         }
11441 
11442         // for r = 0 to regs-1
11443         for (uint32_t r = 0; r < regs; ++r)
11444         {
11445             // for e = 0 to elements-1
11446             uint64_t assembled_data = 0;
11447             for (uint32_t e = 0; e < elements; ++e)
11448             {
11449                 // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11450                 context.type = eContextRegisterLoad;
11451                 context.SetRegisterPlusOffset (base_reg, address - Rn);
11452                 uint64_t data = MemURead (context, address, ebytes, 0, &success);
11453                 if (!success)
11454                     return false;
11455 
11456                 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data
11457 
11458                 // address = address + ebytes;
11459                 address = address + ebytes;
11460             }
11461             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data))
11462                 return false;
11463         }
11464     }
11465     return true;
11466 }
11467 
11468 // A8.6.308 VLD1 (single element to one lane)
11469 //
11470 bool
11471 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding)
11472 {
11473 #if 0
11474     if ConditionPassed() then
11475         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11476         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11477         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11478         Elem[D[d],index,esize] = MemU[address,ebytes];
11479 #endif
11480 
11481     bool success = false;
11482 
11483     if (ConditionPassed (opcode))
11484     {
11485         uint32_t ebytes;
11486         uint32_t esize;
11487         uint32_t index;
11488         uint32_t alignment;
11489         uint32_t d;
11490         uint32_t n;
11491         uint32_t m;
11492         bool wback;
11493         bool register_index;
11494 
11495         switch (encoding)
11496         {
11497             case eEncodingT1:
11498             case eEncodingA1:
11499             {
11500                 uint32_t size = Bits32 (opcode, 11, 10);
11501                 uint32_t index_align = Bits32 (opcode, 7, 4);
11502                 // if size == �11� then SEE VLD1 (single element to all lanes);
11503                 if (size == 3)
11504                    return EmulateVLD1SingleAll (opcode, encoding);
11505                 // case size of
11506                 if (size == 0) // when '00'
11507                 {
11508                     // if index_align<0> != �0� then UNDEFINED;
11509                     if (BitIsClear (index_align, 0))
11510                         return false;
11511 
11512                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11513                     ebytes = 1;
11514                     esize = 8;
11515                     index = Bits32 (index_align, 3, 1);
11516                     alignment = 1;
11517                 }
11518                 else if (size == 1) // when �01�
11519                 {
11520                     // if index_align<1> != �0� then UNDEFINED;
11521                     if (BitIsClear (index_align, 1))
11522                         return false;
11523 
11524                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11525                     ebytes = 2;
11526                     esize = 16;
11527                     index = Bits32 (index_align, 3, 2);
11528 
11529                     // alignment = if index_align<0> == �0� then 1 else 2;
11530                     if (BitIsClear (index_align, 0))
11531                         alignment = 1;
11532                     else
11533                         alignment = 2;
11534                 }
11535                 else if (size == 2) // when �10�
11536                 {
11537                     // if index_align<2> != �0� then UNDEFINED;
11538                     if (BitIsClear (index_align, 2))
11539                         return false;
11540 
11541                     // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11542                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11543                         return false;
11544 
11545                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11546                     ebytes = 4;
11547                     esize = 32;
11548                     index = Bit32 (index_align, 3);
11549 
11550                     // alignment = if index_align<1:0> == �00� then 1 else 4;
11551                     if (Bits32 (index_align, 1, 0) == 0)
11552                         alignment = 1;
11553                     else
11554                         alignment = 4;
11555                 }
11556                 else
11557                 {
11558                     return false;
11559                 }
11560                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11561                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11562                 n = Bits32 (opcode, 19, 16);
11563                 m = Bits32 (opcode, 3, 0);
11564 
11565                 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
11566                 wback = (m != 15);
11567                 register_index = ((m != 15) && (m != 13));
11568 
11569                 if (n == 15)
11570                     return false;
11571 
11572             }
11573                 break;
11574 
11575             default:
11576                 return false;
11577         }
11578 
11579         RegisterInfo base_reg;
11580         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11581 
11582         uint32_t Rn = ReadCoreReg (n, &success);
11583         if (!success)
11584             return false;
11585 
11586         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11587         addr_t address = Rn;
11588         if ((address % alignment) != 0)
11589             return false;
11590 
11591         EmulateInstruction::Context context;
11592         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11593         if (wback)
11594         {
11595             uint32_t Rm = ReadCoreReg (m, &success);
11596             if (!success)
11597                 return false;
11598 
11599             uint32_t offset;
11600             if (register_index)
11601                 offset = Rm;
11602             else
11603                 offset = ebytes;
11604 
11605             uint32_t value = Rn + offset;
11606 
11607             context.type = eContextAdjustBaseRegister;
11608             context.SetRegisterPlusOffset (base_reg, offset);
11609 
11610             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11611                 return false;
11612         }
11613 
11614         // Elem[D[d],index,esize] = MemU[address,ebytes];
11615         uint32_t element = MemURead (context, address, esize, 0, &success);
11616         if (!success)
11617             return false;
11618 
11619         element = element << (index * esize);
11620 
11621         uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11622         if (!success)
11623             return false;
11624 
11625         uint64_t all_ones = -1;
11626         uint64_t mask = all_ones << ((index+1) * esize);  // mask is all 1's to left of where 'element' goes, & all 0's
11627                                                           // at element & to the right of element.
11628         if (index > 0)
11629             mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes.
11630                                                                      // now mask should be 0's where element goes & 1's
11631                                                                      // everywhere else.
11632 
11633         uint64_t masked_reg = reg_data & mask;  // Take original reg value & zero out 'element' bits
11634         reg_data = masked_reg & element;        // Put 'element' into those bits in reg_data.
11635 
11636         context.type = eContextRegisterLoad;
11637         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data))
11638             return false;
11639     }
11640     return true;
11641 }
11642 
11643 // A8.6.391 VST1 (multiple single elements)
11644 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four registers, without
11645 // interleaving.  Every element of each register is stored.
11646 bool
11647 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding)
11648 {
11649 #if 0
11650     if ConditionPassed() then
11651         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11652         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11653         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11654         for r = 0 to regs-1
11655             for e = 0 to elements-1
11656                 MemU[address,ebytes] = Elem[D[d+r],e,esize];
11657                 address = address + ebytes;
11658 #endif
11659 
11660     bool success = false;
11661 
11662     if (ConditionPassed (opcode))
11663     {
11664         uint32_t regs;
11665         uint32_t alignment;
11666         uint32_t ebytes;
11667         uint32_t esize;
11668         uint32_t elements;
11669         uint32_t d;
11670         uint32_t n;
11671         uint32_t m;
11672         bool wback;
11673         bool register_index;
11674 
11675         switch (encoding)
11676         {
11677             case eEncodingT1:
11678             case eEncodingA1:
11679             {
11680                 uint32_t type = Bits32 (opcode, 11, 8);
11681                 uint32_t align = Bits32 (opcode, 5, 4);
11682 
11683                 // case type of
11684                 if (type == 7)    // when �0111�
11685                 {
11686                     // regs = 1; if align<1> == �1� then UNDEFINED;
11687                     regs = 1;
11688                     if (BitIsSet (align, 1))
11689                         return false;
11690                 }
11691                 else if (type == 10) // when �1010�
11692                 {
11693                     // regs = 2; if align == �11� then UNDEFINED;
11694                     regs = 2;
11695                     if (align == 3)
11696                         return false;
11697                 }
11698                 else if (type == 6) // when �0110�
11699                 {
11700                     // regs = 3; if align<1> == �1� then UNDEFINED;
11701                     regs = 3;
11702                     if (BitIsSet (align, 1))
11703                         return false;
11704                 }
11705                 else if (type == 2) // when �0010�
11706                     // regs = 4;
11707                     regs = 4;
11708                 else // otherwise
11709                     // SEE �Related encodings�;
11710                     return false;
11711 
11712                 // alignment = if align == �00� then 1 else 4 << UInt(align);
11713                 if (align == 0)
11714                     alignment = 1;
11715                 else
11716                     alignment = 4 << align;
11717 
11718                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11719                 ebytes = 1 << Bits32 (opcode,7, 6);
11720                 esize = 8 * ebytes;
11721                 elements = 8 / ebytes;
11722 
11723                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11724                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11725                 n = Bits32 (opcode, 19, 16);
11726                 m = Bits32 (opcode, 3, 0);
11727 
11728                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11729                 wback = (m != 15);
11730                 register_index = ((m != 15) && (m != 13));
11731 
11732                 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11733                 if ((d + regs) > 32)
11734                     return false;
11735 
11736                 if (n == 15)
11737                     return false;
11738 
11739             }
11740                 break;
11741 
11742             default:
11743                 return false;
11744         }
11745 
11746         RegisterInfo base_reg;
11747         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11748 
11749         uint32_t Rn = ReadCoreReg (n, &success);
11750         if (!success)
11751             return false;
11752 
11753         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11754         addr_t address = Rn;
11755         if ((address % alignment) != 0)
11756             return false;
11757 
11758         EmulateInstruction::Context context;
11759         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11760         if (wback)
11761         {
11762             uint32_t Rm = ReadCoreReg (m, &success);
11763             if (!success)
11764                 return false;
11765 
11766             uint32_t offset;
11767             if (register_index)
11768                 offset = Rm;
11769             else
11770                 offset = 8 * regs;
11771 
11772             context.type = eContextAdjustBaseRegister;
11773             context.SetRegisterPlusOffset (base_reg, offset);
11774 
11775             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11776                 return false;
11777         }
11778 
11779         RegisterInfo data_reg;
11780         context.type = eContextRegisterStore;
11781         // for r = 0 to regs-1
11782         for (uint32_t r = 0; r < regs; ++r)
11783         {
11784             GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
11785             uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
11786             if (!success)
11787                 return false;
11788 
11789              // for e = 0 to elements-1
11790             for (uint32_t e = 0; e < elements; ++e)
11791             {
11792                 // MemU[address,ebytes] = Elem[D[d+r],e,esize];
11793                 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize);
11794 
11795                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11796                 if (!MemUWrite (context, address, word, ebytes))
11797                     return false;
11798 
11799                 // address = address + ebytes;
11800                 address = address + ebytes;
11801             }
11802         }
11803     }
11804     return true;
11805 }
11806 
11807 // A8.6.392 VST1 (single element from one lane)
11808 // This instruction stores one element to memory from one element of a register.
11809 bool
11810 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding)
11811 {
11812 #if 0
11813     if ConditionPassed() then
11814         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11815         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11816         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11817         MemU[address,ebytes] = Elem[D[d],index,esize];
11818 #endif
11819 
11820     bool success = false;
11821 
11822     if (ConditionPassed (opcode))
11823     {
11824         uint32_t ebytes;
11825         uint32_t esize;
11826         uint32_t index;
11827         uint32_t alignment;
11828         uint32_t d;
11829         uint32_t n;
11830         uint32_t m;
11831         bool wback;
11832         bool register_index;
11833 
11834         switch (encoding)
11835         {
11836             case eEncodingT1:
11837             case eEncodingA1:
11838             {
11839                 uint32_t size = Bits32 (opcode, 11, 10);
11840                 uint32_t index_align = Bits32 (opcode, 7, 4);
11841 
11842                 // if size == �11� then UNDEFINED;
11843                 if (size == 3)
11844                     return false;
11845 
11846                 // case size of
11847                 if (size == 0) // when �00�
11848                 {
11849                     // if index_align<0> != �0� then UNDEFINED;
11850                     if (BitIsClear (index_align, 0))
11851                         return false;
11852                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11853                     ebytes = 1;
11854                     esize = 8;
11855                     index = Bits32 (index_align, 3, 1);
11856                     alignment = 1;
11857                 }
11858                 else if (size == 1) // when �01�
11859                 {
11860                     // if index_align<1> != �0� then UNDEFINED;
11861                     if (BitIsClear (index_align, 1))
11862                         return false;
11863 
11864                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11865                     ebytes = 2;
11866                     esize = 16;
11867                     index = Bits32 (index_align, 3, 2);
11868 
11869                     // alignment = if index_align<0> == �0� then 1 else 2;
11870                     if (BitIsClear (index_align, 0))
11871                         alignment = 1;
11872                     else
11873                         alignment = 2;
11874                 }
11875                 else if (size == 2) // when �10�
11876                 {
11877                     // if index_align<2> != �0� then UNDEFINED;
11878                     if (BitIsClear (index_align, 2))
11879                         return false;
11880 
11881                     // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11882                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11883                         return false;
11884 
11885                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11886                     ebytes = 4;
11887                     esize = 32;
11888                     index = Bit32 (index_align, 3);
11889 
11890                     // alignment = if index_align<1:0> == �00� then 1 else 4;
11891                     if (Bits32 (index_align, 1, 0) == 0)
11892                         alignment = 1;
11893                     else
11894                         alignment = 4;
11895                 }
11896                 else
11897                 {
11898                     return false;
11899                 }
11900                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11901                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11902                 n = Bits32 (opcode, 19, 16);
11903                 m = Bits32 (opcode, 3, 0);
11904 
11905                 // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15 then UNPREDICTABLE;
11906                 wback = (m != 15);
11907                 register_index = ((m != 15) && (m != 13));
11908 
11909                 if (n == 15)
11910                     return false;
11911             }
11912                 break;
11913 
11914             default:
11915                 return false;
11916         }
11917 
11918         RegisterInfo base_reg;
11919         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11920 
11921         uint32_t Rn = ReadCoreReg (n, &success);
11922         if (!success)
11923             return false;
11924 
11925         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11926         addr_t address = Rn;
11927         if ((address % alignment) != 0)
11928             return false;
11929 
11930         EmulateInstruction::Context context;
11931         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11932         if (wback)
11933         {
11934             uint32_t Rm = ReadCoreReg (m, &success);
11935             if (!success)
11936                 return false;
11937 
11938             uint32_t offset;
11939             if (register_index)
11940                 offset = Rm;
11941             else
11942                 offset = ebytes;
11943 
11944             context.type = eContextAdjustBaseRegister;
11945             context.SetRegisterPlusOffset (base_reg, offset);
11946 
11947             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11948                 return false;
11949         }
11950 
11951         // MemU[address,ebytes] = Elem[D[d],index,esize];
11952         uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11953         if (!success)
11954             return false;
11955 
11956         uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1,  index * esize);
11957 
11958         RegisterInfo data_reg;
11959         GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg);
11960         context.type = eContextRegisterStore;
11961         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11962 
11963         if (!MemUWrite (context, address, word, ebytes))
11964             return false;
11965     }
11966     return true;
11967 }
11968 
11969 // A8.6.309 VLD1 (single element to all lanes)
11970 // This instruction loads one element from memory into every element of one or two vectors.
11971 bool
11972 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding)
11973 {
11974 #if 0
11975     if ConditionPassed() then
11976         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11977         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11978         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11979         replicated_element = Replicate(MemU[address,ebytes], elements);
11980         for r = 0 to regs-1
11981             D[d+r] = replicated_element;
11982 #endif
11983 
11984     bool success = false;
11985 
11986     if (ConditionPassed (opcode))
11987     {
11988         uint32_t ebytes;
11989         uint32_t elements;
11990         uint32_t regs;
11991         uint32_t alignment;
11992         uint32_t d;
11993         uint32_t n;
11994         uint32_t m;
11995         bool wback;
11996         bool register_index;
11997 
11998         switch (encoding)
11999         {
12000             case eEncodingT1:
12001             case eEncodingA1:
12002             {
12003                 //if size == �11� || (size == �00� && a == �1�) then UNDEFINED;
12004                 uint32_t size = Bits32 (opcode, 7, 6);
12005                 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4)))
12006                     return false;
12007 
12008                 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2;
12009                 ebytes = 1 << size;
12010                 elements = 8 / ebytes;
12011                 if (BitIsClear (opcode, 5))
12012                     regs = 1;
12013                 else
12014                     regs = 2;
12015 
12016                 //alignment = if a == �0� then 1 else ebytes;
12017                 if (BitIsClear (opcode, 4))
12018                     alignment = 1;
12019                 else
12020                     alignment = ebytes;
12021 
12022                 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12023                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
12024                 n = Bits32 (opcode, 19, 16);
12025                 m = Bits32 (opcode, 3, 0);
12026 
12027                 //wback = (m != 15); register_index = (m != 15 && m != 13);
12028                 wback = (m != 15);
12029                 register_index = ((m != 15) && (m != 13));
12030 
12031                 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12032                 if ((d + regs) > 32)
12033                     return false;
12034 
12035                 if (n == 15)
12036                     return false;
12037             }
12038             break;
12039 
12040             default:
12041                 return false;
12042         }
12043 
12044         RegisterInfo base_reg;
12045         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12046 
12047         uint32_t Rn = ReadCoreReg (n, &success);
12048         if (!success)
12049             return false;
12050 
12051         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12052         addr_t address = Rn;
12053         if ((address % alignment) != 0)
12054             return false;
12055 
12056         EmulateInstruction::Context context;
12057         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12058         if (wback)
12059         {
12060             uint32_t Rm = ReadCoreReg (m, &success);
12061             if (!success)
12062                 return false;
12063 
12064             uint32_t offset;
12065             if (register_index)
12066                 offset = Rm;
12067             else
12068                 offset = ebytes;
12069 
12070             context.type = eContextAdjustBaseRegister;
12071             context.SetRegisterPlusOffset (base_reg, offset);
12072 
12073             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
12074                 return false;
12075         }
12076 
12077         // replicated_element = Replicate(MemU[address,ebytes], elements);
12078 
12079         context.type = eContextRegisterLoad;
12080         uint64_t word = MemURead (context, address, ebytes, 0, &success);
12081         if (!success)
12082             return false;
12083 
12084         uint64_t replicated_element = 0;
12085         uint32_t esize = ebytes * 8;
12086         for (uint32_t e = 0; e < elements; ++e)
12087             replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0);
12088 
12089         // for r = 0 to regs-1
12090         for (uint32_t r = 0; r < regs; ++r)
12091         {
12092             // D[d+r] = replicated_element;
12093             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element))
12094                 return false;
12095         }
12096     }
12097     return true;
12098 }
12099 
12100 // B6.2.13 SUBS PC, LR and related instructions
12101 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack.  It subtracts the
12102 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR.
12103 bool
12104 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding)
12105 {
12106 #if 0
12107     if ConditionPassed() then
12108         EncodingSpecificOperations();
12109         if CurrentInstrSet() == InstrSet_ThumbEE then
12110             UNPREDICTABLE;
12111         operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12112         case opcode of
12113             when0000result = R[n] AND operand2; // AND
12114             when0001result = R[n] EOR operand2; // EOR
12115             when0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12116             when0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12117             when0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12118             when0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12119             when0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12120             when0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12121             when1100result = R[n] OR operand2; // ORR
12122             when1101result = operand2; // MOV
12123             when1110result = R[n] AND NOT(operand2); // BIC
12124             when1111result = NOT(operand2); // MVN
12125         CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12126         BranchWritePC(result);
12127 #endif
12128 
12129     bool success = false;
12130 
12131     if (ConditionPassed (opcode))
12132     {
12133         uint32_t n;
12134         uint32_t m;
12135         uint32_t imm32;
12136         bool register_form;
12137         ARM_ShifterType shift_t;
12138         uint32_t shift_n;
12139         uint32_t code;
12140 
12141         switch (encoding)
12142         {
12143             case eEncodingT1:
12144                 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
12145                 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB
12146                 n = 14;
12147                 imm32 = Bits32 (opcode, 7, 0);
12148                 register_form = false;
12149                 code = 2;
12150 
12151                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12152                 if (InITBlock() && !LastInITBlock())
12153                     return false;
12154 
12155                 break;
12156 
12157             case eEncodingA1:
12158                 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12159                 n = Bits32 (opcode, 19, 16);
12160                 imm32 = ARMExpandImm (opcode);
12161                 register_form = false;
12162                 code = Bits32 (opcode, 24, 21);
12163 
12164                 break;
12165 
12166             case eEncodingA2:
12167                 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12168                 n = Bits32 (opcode, 19, 16);
12169                 m = Bits32 (opcode, 3, 0);
12170                 register_form = true;
12171 
12172                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12173                 shift_n = DecodeImmShiftARM (opcode, shift_t);
12174 
12175                 break;
12176 
12177             default:
12178                 return false;
12179         }
12180 
12181         // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12182         uint32_t operand2;
12183         if (register_form)
12184         {
12185             uint32_t Rm = ReadCoreReg (m, &success);
12186             if (!success)
12187                 return false;
12188 
12189             operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success);
12190             if (!success)
12191                 return false;
12192         }
12193         else
12194         {
12195             operand2 = imm32;
12196         }
12197 
12198         uint32_t Rn = ReadCoreReg (n, &success);
12199         if (!success)
12200             return false;
12201 
12202         AddWithCarryResult result;
12203 
12204         // case opcode of
12205         switch (code)
12206         {
12207             case 0: // when �0000�
12208                 // result = R[n] AND operand2; // AND
12209                 result.result = Rn & operand2;
12210                 break;
12211 
12212             case 1: // when �0001�
12213                 // result = R[n] EOR operand2; // EOR
12214                 result.result = Rn ^ operand2;
12215                 break;
12216 
12217             case 2: // when �0010�
12218                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12219                 result = AddWithCarry (Rn, ~(operand2), 1);
12220                 break;
12221 
12222             case 3: // when �0011�
12223                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12224                 result = AddWithCarry (~(Rn), operand2, 1);
12225                 break;
12226 
12227             case 4: // when �0100�
12228                 // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12229                 result = AddWithCarry (Rn, operand2, 0);
12230                 break;
12231 
12232             case 5: // when �0101�
12233                 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12234                 result = AddWithCarry (Rn, operand2, APSR_C);
12235                 break;
12236 
12237             case 6: // when �0110�
12238                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12239                 result = AddWithCarry (Rn, ~(operand2), APSR_C);
12240                 break;
12241 
12242             case 7: // when �0111�
12243                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12244                 result = AddWithCarry (~(Rn), operand2, APSR_C);
12245                 break;
12246 
12247             case 10: // when �1100�
12248                 // result = R[n] OR operand2; // ORR
12249                 result.result = Rn | operand2;
12250                 break;
12251 
12252             case 11: // when �1101�
12253                 // result = operand2; // MOV
12254                 result.result = operand2;
12255                 break;
12256 
12257             case 12: // when �1110�
12258                 // result = R[n] AND NOT(operand2); // BIC
12259                 result.result = Rn & ~(operand2);
12260                 break;
12261 
12262             case 15: // when �1111�
12263                 // result = NOT(operand2); // MVN
12264                 result.result = ~(operand2);
12265                 break;
12266 
12267             default:
12268                 return false;
12269         }
12270         // CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12271 
12272         // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for
12273         // the best.
12274         uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12275         if (!success)
12276             return false;
12277 
12278         CPSRWriteByInstr (spsr, 15, true);
12279 
12280         // BranchWritePC(result);
12281         EmulateInstruction::Context context;
12282         context.type = eContextAdjustPC;
12283         context.SetImmediate (result.result);
12284 
12285         BranchWritePC (context, result.result);
12286     }
12287     return true;
12288 }
12289 
12290 EmulateInstructionARM::ARMOpcode*
12291 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12292 {
12293     static ARMOpcode
12294     g_arm_opcodes[] =
12295     {
12296         //----------------------------------------------------------------------
12297         // Prologue instructions
12298         //----------------------------------------------------------------------
12299 
12300         // push register(s)
12301         { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12302         { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
12303 
12304         // set r7 to point to a stack offset
12305         { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
12306         { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12307         // copy the stack pointer to ip
12308         { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
12309         { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
12310         { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12311 
12312         // adjust the stack pointer
12313         { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12314         { 0x0fef0010, 0x004d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12315 
12316         // push one register
12317         // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12318         { 0x0e5f0000, 0x040d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
12319 
12320         // vector push consecutive extension register(s)
12321         { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12322         { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12323 
12324         //----------------------------------------------------------------------
12325         // Epilogue instructions
12326         //----------------------------------------------------------------------
12327 
12328         { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12329         { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12330         { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12331         { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12332 
12333         //----------------------------------------------------------------------
12334         // Supervisor Call (previously Software Interrupt)
12335         //----------------------------------------------------------------------
12336         { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12337 
12338         //----------------------------------------------------------------------
12339         // Branch instructions
12340         //----------------------------------------------------------------------
12341         { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
12342         // To resolve ambiguity, "blx <label>" should come before "bl <label>".
12343         { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12344         { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12345         { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12346         // for example, "bx lr"
12347         { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12348         // bxj
12349         { 0x0ffffff0, 0x012fff20, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12350 
12351         //----------------------------------------------------------------------
12352         // Data-processing instructions
12353         //----------------------------------------------------------------------
12354         // adc (immediate)
12355         { 0x0fe00000, 0x02a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12356         // adc (register)
12357         { 0x0fe00010, 0x00a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12358         // add (immediate)
12359         { 0x0fe00000, 0x02800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
12360         // add (register)
12361         { 0x0fe00010, 0x00800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12362         // add (register-shifted register)
12363         { 0x0fe00090, 0x00800010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12364         // adr
12365         { 0x0fff0000, 0x028f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12366         { 0x0fff0000, 0x024f0000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12367         // and (immediate)
12368         { 0x0fe00000, 0x02000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12369         // and (register)
12370         { 0x0fe00010, 0x00000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12371         // bic (immediate)
12372         { 0x0fe00000, 0x03c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12373         // bic (register)
12374         { 0x0fe00010, 0x01c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12375         // eor (immediate)
12376         { 0x0fe00000, 0x02200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12377         // eor (register)
12378         { 0x0fe00010, 0x00200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12379         // orr (immediate)
12380         { 0x0fe00000, 0x03800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12381         // orr (register)
12382         { 0x0fe00010, 0x01800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12383         // rsb (immediate)
12384         { 0x0fe00000, 0x02600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12385         // rsb (register)
12386         { 0x0fe00010, 0x00600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12387         // rsc (immediate)
12388         { 0x0fe00000, 0x02e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12389         // rsc (register)
12390         { 0x0fe00010, 0x00e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12391         // sbc (immediate)
12392         { 0x0fe00000, 0x02c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12393         // sbc (register)
12394         { 0x0fe00010, 0x00c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12395         // sub (immediate, ARM)
12396         { 0x0fe00000, 0x02400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
12397         // sub (sp minus immediate)
12398         { 0x0fef0000, 0x024d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12399         // sub (register)
12400         { 0x0fe00010, 0x00400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12401         // teq (immediate)
12402         { 0x0ff0f000, 0x03300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12403         // teq (register)
12404         { 0x0ff0f010, 0x01300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12405         // tst (immediate)
12406         { 0x0ff0f000, 0x03100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12407         // tst (register)
12408         { 0x0ff0f010, 0x01100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12409 
12410         // mov (immediate)
12411         { 0x0fef0000, 0x03a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12412         { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
12413         // mov (register)
12414         { 0x0fef0ff0, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12415         // mvn (immediate)
12416         { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12417         // mvn (register)
12418         { 0x0fef0010, 0x01e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12419         // cmn (immediate)
12420         { 0x0ff0f000, 0x03700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12421         // cmn (register)
12422         { 0x0ff0f010, 0x01700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12423         // cmp (immediate)
12424         { 0x0ff0f000, 0x03500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
12425         // cmp (register)
12426         { 0x0ff0f010, 0x01500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
12427         // asr (immediate)
12428         { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
12429         // asr (register)
12430         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
12431         // lsl (immediate)
12432         { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
12433         // lsl (register)
12434         { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
12435         // lsr (immediate)
12436         { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
12437         // lsr (register)
12438         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
12439         // rrx is a special case encoding of ror (immediate)
12440         { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
12441         // ror (immediate)
12442         { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
12443         // ror (register)
12444         { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
12445         // mul
12446         { 0x0fe000f0, 0x00000090, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
12447 
12448         // subs pc, lr and related instructions
12449         { 0x0e10f000, 0x0210f000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" },
12450         { 0x0e10f010, 0x0010f000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" },
12451 
12452         //----------------------------------------------------------------------
12453         // Load instructions
12454         //----------------------------------------------------------------------
12455         { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12456         { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
12457         { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12458         { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
12459         { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
12460         { 0x0e500010, 0x06100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
12461         { 0x0e5f0000, 0x045f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
12462         { 0xfe500010, 0x06500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
12463         { 0x0e5f00f0, 0x005f00b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12464         { 0x0e5000f0, 0x001000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"  },
12465         { 0x0e5000f0, 0x005000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
12466         { 0x0e5f00f0, 0x005f00d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
12467         { 0x0e5000f0, 0x001000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12468         { 0x0e5000f0, 0x005000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
12469         { 0x0e5f00f0, 0x005f00f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12470         { 0x0e5000f0, 0x001000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12471         { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
12472         { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12473         { 0x0e100f00, 0x0c100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12474         { 0x0e100f00, 0x0c100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12475         { 0x0f300f00, 0x0d100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12476         { 0x0f300f00, 0x0d100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12477         { 0xffb00000, 0xf4200000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12478         { 0xffb00300, 0xf4a00000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12479         { 0xffb00f00, 0xf4a00c00, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12480 
12481         //----------------------------------------------------------------------
12482         // Store instructions
12483         //----------------------------------------------------------------------
12484         { 0x0fd00000, 0x08800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12485         { 0x0fd00000, 0x08000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
12486         { 0x0fd00000, 0x09000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12487         { 0x0fd00000, 0x09800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
12488         { 0x0e500010, 0x06000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
12489         { 0x0e5000f0, 0x000000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
12490         { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
12491         { 0x0e500000, 0x04400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12492         { 0x0e500000, 0x04000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12493         { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
12494         { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12495         { 0x0e100f00, 0x0c000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12496         { 0x0e100f00, 0x0c000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12497         { 0x0f300f00, 0x0d000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
12498         { 0x0f300f00, 0x0d000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
12499         { 0xffb00000, 0xf4000000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12500         { 0xffb00300, 0xf4800000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12501 
12502         //----------------------------------------------------------------------
12503         // Other instructions
12504         //----------------------------------------------------------------------
12505         { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
12506         { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
12507         { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
12508         { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
12509         { 0xfe500000, 0xf8100000, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
12510 
12511     };
12512     static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes);
12513 
12514     for (size_t i=0; i<k_num_arm_opcodes; ++i)
12515     {
12516         if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
12517             (g_arm_opcodes[i].variants & arm_isa) != 0)
12518             return &g_arm_opcodes[i];
12519     }
12520     return NULL;
12521 }
12522 
12523 
12524 EmulateInstructionARM::ARMOpcode*
12525 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12526 {
12527 
12528     static ARMOpcode
12529     g_thumb_opcodes[] =
12530     {
12531         //----------------------------------------------------------------------
12532         // Prologue instructions
12533         //----------------------------------------------------------------------
12534 
12535         // push register(s)
12536         { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12537         { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
12538         { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
12539 
12540         // set r7 to point to a stack offset
12541         { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
12542         // copy the stack pointer to r7
12543         { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
12544         // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
12545         { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
12546 
12547         // PC-relative load into register (see also EmulateADDSPRm)
12548         { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
12549 
12550         // adjust the stack pointer
12551         { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
12552         { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
12553         { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
12554         { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
12555         { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12556 
12557         // vector push consecutive extension register(s)
12558         { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12559         { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12560 
12561         //----------------------------------------------------------------------
12562         // Epilogue instructions
12563         //----------------------------------------------------------------------
12564 
12565         { 0xfffff800, 0x0000a800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
12566         { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
12567         { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12568         { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
12569         { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
12570         { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12571         { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12572 
12573         //----------------------------------------------------------------------
12574         // Supervisor Call (previously Software Interrupt)
12575         //----------------------------------------------------------------------
12576         { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
12577 
12578         //----------------------------------------------------------------------
12579         // If Then makes up to four following instructions conditional.
12580         //----------------------------------------------------------------------
12581         // The next 5 opcode _must_ come before the if then instruction
12582         { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"},
12583         { 0xffffffff, 0x0000bf10, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
12584         { 0xffffffff, 0x0000bf20, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
12585         { 0xffffffff, 0x0000bf30, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
12586         { 0xffffffff, 0x0000bf40, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
12587         { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
12588 
12589         //----------------------------------------------------------------------
12590         // Branch instructions
12591         //----------------------------------------------------------------------
12592         // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
12593         { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
12594         { 0xfffff800, 0x0000e000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
12595         { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
12596         { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
12597         // J1 == J2 == 1
12598         { 0xf800d000, 0xf000d000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12599         // J1 == J2 == 1
12600         { 0xf800d001, 0xf000c000, ARMV5_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12601         { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12602         // for example, "bx lr"
12603         { 0xffffff87, 0x00004700, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12604         // bxj
12605         { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12606         // compare and branch
12607         { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
12608         // table branch byte
12609         { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
12610         // table branch halfword
12611         { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
12612 
12613         //----------------------------------------------------------------------
12614         // Data-processing instructions
12615         //----------------------------------------------------------------------
12616         // adc (immediate)
12617         { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
12618         // adc (register)
12619         { 0xffffffc0, 0x00004140, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
12620         { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12621         // add (register)
12622         { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
12623         // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
12624         { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
12625         // adr
12626         { 0xfffff800, 0x0000a000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12627         { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12628         { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12629         // and (immediate)
12630         { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
12631         // and (register)
12632         { 0xffffffc0, 0x00004000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
12633         { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12634         // bic (immediate)
12635         { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
12636         // bic (register)
12637         { 0xffffffc0, 0x00004380, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
12638         { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12639         // eor (immediate)
12640         { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
12641         // eor (register)
12642         { 0xffffffc0, 0x00004040, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
12643         { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12644         // orr (immediate)
12645         { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
12646         // orr (register)
12647         { 0xffffffc0, 0x00004300, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
12648         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12649         // rsb (immediate)
12650         { 0xffffffc0, 0x00004240, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
12651         { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
12652         // rsb (register)
12653         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12654         // sbc (immediate)
12655         { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12656         // sbc (register)
12657         { 0xffffffc0, 0x00004180, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
12658         { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12659         // add (immediate, Thumb)
12660         { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
12661         { 0xfffff800, 0x00003000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
12662         { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
12663         { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
12664         // sub (immediate, Thumb)
12665         { 0xfffffe00, 0x00001e00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
12666         { 0xfffff800, 0x00003800, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
12667         { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
12668         { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
12669         // sub (sp minus immediate)
12670         { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
12671         { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
12672         // sub (register)
12673         { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
12674         { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
12675         // teq (immediate)
12676         { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
12677         // teq (register)
12678         { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12679         // tst (immediate)
12680         { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
12681         // tst (register)
12682         { 0xffffffc0, 0x00004200, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
12683         { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
12684 
12685 
12686         // move from high register to high register
12687         { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
12688         // move from low register to low register
12689         { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
12690         // mov{s}<c>.w <Rd>, <Rm>
12691         { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
12692         // move immediate
12693         { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
12694         { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
12695         { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
12696         // mvn (immediate)
12697         { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
12698         // mvn (register)
12699         { 0xffffffc0, 0x000043c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
12700         { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
12701         // cmn (immediate)
12702         { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12703         // cmn (register)
12704         { 0xffffffc0, 0x000042c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
12705         { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12706         // cmp (immediate)
12707         { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
12708         { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
12709         // cmp (register) (Rn and Rm both from r0-r7)
12710         { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12711         // cmp (register) (Rn and Rm not both from r0-r7)
12712         { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12713         // asr (immediate)
12714         { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
12715         { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
12716         // asr (register)
12717         { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
12718         { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12719         // lsl (immediate)
12720         { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
12721         { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
12722         // lsl (register)
12723         { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
12724         { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
12725         // lsr (immediate)
12726         { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
12727         { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
12728         // lsr (register)
12729         { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
12730         { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12731         // rrx is a special case encoding of ror (immediate)
12732         { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
12733         // ror (immediate)
12734         { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
12735         // ror (register)
12736         { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
12737         { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
12738         // mul
12739         { 0xffffffc0, 0x00004340, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
12740         // mul
12741         { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
12742 
12743         // subs pc, lr and related instructions
12744         { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" },
12745 
12746         //----------------------------------------------------------------------
12747         // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table;
12748         // otherwise the wrong instructions will be selected.
12749         //----------------------------------------------------------------------
12750 
12751         { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
12752         { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
12753 
12754         //----------------------------------------------------------------------
12755         // Load instructions
12756         //----------------------------------------------------------------------
12757         { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12758         { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
12759         { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12760         { 0xfffff800, 0x00006800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
12761         { 0xfffff800, 0x00009800, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
12762         { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
12763         { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
12764                   // Thumb2 PC-relative load into register
12765         { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
12766         { 0xfffffe00, 0x00005800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
12767         { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
12768         { 0xfffff800, 0x00007800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
12769         { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12770         { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" },
12771         { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
12772         { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
12773         { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
12774         { 0xfffff800, 0x00008800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"  },
12775         { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12776         { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"  },
12777         { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12778         { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
12779         { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12780         { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
12781         { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12782         { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
12783         { 0xfffffe00, 0x00005600, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
12784         { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"  },
12785         { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
12786         { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12787         { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12788         { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
12789         { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12790         { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
12791         { 0xfe100f00, 0xec100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12792         { 0xfe100f00, 0xec100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
12793         { 0xffe00f00, 0xed100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12794         { 0xff300f00, 0xed100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
12795         { 0xffb00000, 0xf9200000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12796         { 0xffb00300, 0xf9a00000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12797         { 0xffb00f00, 0xf9a00c00, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12798 
12799         //----------------------------------------------------------------------
12800         // Store instructions
12801         //----------------------------------------------------------------------
12802         { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12803         { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
12804         { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12805         { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
12806         { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
12807         { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
12808         { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
12809         { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
12810         { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
12811         { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
12812         { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
12813         { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
12814         { 0xfffffe00, 0x00005200, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
12815         { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12816         { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
12817         { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
12818         { 0xfe100f00, 0xec000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12819         { 0xfea00f00, 0xec000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12820         { 0xff300f00, 0xed000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12821         { 0xff300f00, 0xed000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12822         { 0xffb00000, 0xf9000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12823         { 0xffb00300, 0xf9800000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12824 
12825         //----------------------------------------------------------------------
12826         // Other instructions
12827         //----------------------------------------------------------------------
12828         { 0xffffffc0, 0x0000b240, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
12829         { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12830         { 0xffffffc0, 0x0000b200, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
12831         { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12832         { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
12833         { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12834         { 0xffffffc0, 0x0000b280, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
12835         { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12836     };
12837 
12838     const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes);
12839     for (size_t i=0; i<k_num_thumb_opcodes; ++i)
12840     {
12841         if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
12842             (g_thumb_opcodes[i].variants & arm_isa) != 0)
12843             return &g_thumb_opcodes[i];
12844     }
12845     return NULL;
12846 }
12847 
12848 bool
12849 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
12850 {
12851     m_arch = arch;
12852     m_arm_isa = 0;
12853     const char *arch_cstr = arch.GetArchitectureName ();
12854     if (arch_cstr)
12855     {
12856         if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
12857         else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
12858         else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
12859         else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
12860         else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
12861         else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
12862         else if (0 == ::strcasecmp(arch_cstr, "armv7s"))    m_arm_isa = ARMv7S;
12863         else if (0 == ::strcasecmp(arch_cstr, "arm"))       m_arm_isa = ARMvAll;
12864         else if (0 == ::strcasecmp(arch_cstr, "thumb"))     m_arm_isa = ARMvAll;
12865         else if (0 == ::strncasecmp(arch_cstr,"armv4", 5))  m_arm_isa = ARMv4;
12866         else if (0 == ::strncasecmp(arch_cstr,"armv6", 5))  m_arm_isa = ARMv6;
12867         else if (0 == ::strncasecmp(arch_cstr,"armv7", 5))  m_arm_isa = ARMv7;
12868         else if (0 == ::strncasecmp(arch_cstr,"armv8", 5))  m_arm_isa = ARMv8;
12869     }
12870     return m_arm_isa != 0;
12871 }
12872 
12873 bool
12874 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
12875 {
12876     if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
12877     {
12878         if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
12879             m_opcode_mode = eModeThumb;
12880         else
12881         {
12882             AddressClass addr_class = inst_addr.GetAddressClass();
12883 
12884             if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
12885                 m_opcode_mode = eModeARM;
12886             else if (addr_class == eAddressClassCodeAlternateISA)
12887                 m_opcode_mode = eModeThumb;
12888             else
12889                 return false;
12890         }
12891         if (m_opcode_mode == eModeThumb)
12892             m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
12893         else
12894             m_opcode_cpsr = CPSR_MODE_USR;
12895         return true;
12896     }
12897     return false;
12898 }
12899 
12900 bool
12901 EmulateInstructionARM::ReadInstruction ()
12902 {
12903     bool success = false;
12904     m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
12905     if (success)
12906     {
12907         addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
12908         if (success)
12909         {
12910             Context read_inst_context;
12911             read_inst_context.type = eContextReadOpcode;
12912             read_inst_context.SetNoArgs ();
12913 
12914             if (m_opcode_cpsr & MASK_CPSR_T)
12915             {
12916                 m_opcode_mode = eModeThumb;
12917                 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
12918 
12919                 if (success)
12920                 {
12921                     if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
12922                     {
12923                         m_opcode.SetOpcode16 (thumb_opcode, GetByteOrder());
12924                     }
12925                     else
12926                     {
12927                         m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success), GetByteOrder());
12928                     }
12929                 }
12930             }
12931             else
12932             {
12933                 m_opcode_mode = eModeARM;
12934                 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success), GetByteOrder());
12935             }
12936         }
12937     }
12938     if (!success)
12939     {
12940         m_opcode_mode = eModeInvalid;
12941         m_addr = LLDB_INVALID_ADDRESS;
12942     }
12943     return success;
12944 }
12945 
12946 uint32_t
12947 EmulateInstructionARM::ArchVersion ()
12948 {
12949     return m_arm_isa;
12950 }
12951 
12952 bool
12953 EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional)
12954 {
12955    // If we are ignoring conditions, then always return true.
12956    // this allows us to iterate over disassembly code and still
12957    // emulate an instruction even if we don't have all the right
12958    // bits set in the CPSR register...
12959     if (m_ignore_conditions)
12960         return true;
12961 
12962     if (is_conditional)
12963         *is_conditional = true;
12964 
12965     const uint32_t cond = CurrentCond (opcode);
12966 
12967     if (cond == UINT32_MAX)
12968         return false;
12969 
12970     bool result = false;
12971     switch (UnsignedBits(cond, 3, 1))
12972     {
12973     case 0:
12974 		if (m_opcode_cpsr == 0)
12975 			result = true;
12976         else
12977             result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
12978 		break;
12979     case 1:
12980         if (m_opcode_cpsr == 0)
12981             result = true;
12982         else
12983             result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
12984 		break;
12985     case 2:
12986         if (m_opcode_cpsr == 0)
12987             result = true;
12988         else
12989             result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
12990 		break;
12991     case 3:
12992         if (m_opcode_cpsr == 0)
12993             result = true;
12994         else
12995             result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
12996 		break;
12997     case 4:
12998         if (m_opcode_cpsr == 0)
12999             result = true;
13000         else
13001             result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13002 		break;
13003     case 5:
13004         if (m_opcode_cpsr == 0)
13005             result = true;
13006         else
13007 		{
13008             bool n = (m_opcode_cpsr & MASK_CPSR_N);
13009             bool v = (m_opcode_cpsr & MASK_CPSR_V);
13010             result = n == v;
13011         }
13012         break;
13013     case 6:
13014         if (m_opcode_cpsr == 0)
13015             result = true;
13016         else
13017 		{
13018             bool n = (m_opcode_cpsr & MASK_CPSR_N);
13019             bool v = (m_opcode_cpsr & MASK_CPSR_V);
13020             result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13021         }
13022         break;
13023     case 7:
13024         // Always execute (cond == 0b1110, or the special 0b1111 which gives
13025         // opcodes different meanings, but always means execution happens.
13026         if (is_conditional)
13027             *is_conditional = false;
13028         result = true;
13029         break;
13030     }
13031 
13032     if (cond & 1)
13033         result = !result;
13034     return result;
13035 }
13036 
13037 uint32_t
13038 EmulateInstructionARM::CurrentCond (const uint32_t opcode)
13039 {
13040     switch (m_opcode_mode)
13041     {
13042     case eModeInvalid:
13043         break;
13044 
13045     case eModeARM:
13046         return UnsignedBits(opcode, 31, 28);
13047 
13048     case eModeThumb:
13049         // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
13050         // 'cond' field of the encoding.
13051         {
13052             const uint32_t byte_size = m_opcode.GetByteSize();
13053             if (byte_size == 2)
13054             {
13055                 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f)
13056                     return Bits32(opcode, 11, 7);
13057             }
13058             else if (byte_size == 4)
13059             {
13060                 if (Bits32(opcode, 31, 27) == 0x1e &&
13061                     Bits32(opcode, 15, 14) == 0x02 &&
13062                     Bits32(opcode, 12, 12) == 0x00 &&
13063                     Bits32(opcode, 25, 22) <= 0x0d)
13064                 {
13065                     return Bits32(opcode, 25, 22);
13066                 }
13067             }
13068             else
13069                 // We have an invalid thumb instruction, let's bail out.
13070                 break;
13071 
13072             return m_it_session.GetCond();
13073         }
13074     }
13075     return UINT32_MAX;  // Return invalid value
13076 }
13077 
13078 bool
13079 EmulateInstructionARM::InITBlock()
13080 {
13081     return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13082 }
13083 
13084 bool
13085 EmulateInstructionARM::LastInITBlock()
13086 {
13087     return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13088 }
13089 
13090 bool
13091 EmulateInstructionARM::BadMode (uint32_t mode)
13092 {
13093 
13094     switch (mode)
13095     {
13096         case 16: return false; // '10000'
13097         case 17: return false; // '10001'
13098         case 18: return false; // '10010'
13099         case 19: return false; // '10011'
13100         case 22: return false; // '10110'
13101         case 23: return false; // '10111'
13102         case 27: return false; // '11011'
13103         case 31: return false; // '11111'
13104         default: return true;
13105     }
13106     return true;
13107 }
13108 
13109 bool
13110 EmulateInstructionARM::CurrentModeIsPrivileged ()
13111 {
13112     uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
13113 
13114     if (BadMode (mode))
13115         return false;
13116 
13117     if (mode == 16)
13118         return false;
13119 
13120     return true;
13121 }
13122 
13123 void
13124 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
13125 {
13126     bool privileged = CurrentModeIsPrivileged();
13127 
13128     uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20;
13129 
13130     if (BitIsSet (bytemask, 3))
13131     {
13132         tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
13133         if (affect_execstate)
13134             tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
13135     }
13136 
13137     if (BitIsSet (bytemask, 2))
13138     {
13139         tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
13140     }
13141 
13142     if (BitIsSet (bytemask, 1))
13143     {
13144         if (affect_execstate)
13145             tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
13146         tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
13147         if (privileged)
13148             tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
13149     }
13150 
13151     if (BitIsSet (bytemask, 0))
13152     {
13153         if (privileged)
13154             tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
13155         if (affect_execstate)
13156             tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
13157         if (privileged)
13158             tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
13159     }
13160 
13161     m_opcode_cpsr = tmp_cpsr;
13162 }
13163 
13164 
13165 bool
13166 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
13167 {
13168     addr_t target;
13169 
13170     // Check the current instruction set.
13171     if (CurrentInstrSet() == eModeARM)
13172         target = addr & 0xfffffffc;
13173     else
13174         target = addr & 0xfffffffe;
13175 
13176     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13177         return false;
13178 
13179     return true;
13180 }
13181 
13182 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
13183 bool
13184 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
13185 {
13186     addr_t target;
13187     // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
13188     // we want to record it and issue a WriteRegister callback so the clients
13189     // can track the mode changes accordingly.
13190     bool cpsr_changed = false;
13191 
13192     if (BitIsSet(addr, 0))
13193     {
13194         if (CurrentInstrSet() != eModeThumb)
13195         {
13196             SelectInstrSet(eModeThumb);
13197             cpsr_changed = true;
13198         }
13199         target = addr & 0xfffffffe;
13200         context.SetISA (eModeThumb);
13201     }
13202     else if (BitIsClear(addr, 1))
13203     {
13204         if (CurrentInstrSet() != eModeARM)
13205         {
13206             SelectInstrSet(eModeARM);
13207             cpsr_changed = true;
13208         }
13209         target = addr & 0xfffffffc;
13210         context.SetISA (eModeARM);
13211     }
13212     else
13213         return false; // address<1:0> == '10' => UNPREDICTABLE
13214 
13215     if (cpsr_changed)
13216     {
13217         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13218             return false;
13219     }
13220     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13221         return false;
13222 
13223     return true;
13224 }
13225 
13226 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
13227 bool
13228 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
13229 {
13230     if (ArchVersion() >= ARMv5T)
13231         return BXWritePC(context, addr);
13232     else
13233         return BranchWritePC((const Context)context, addr);
13234 }
13235 
13236 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
13237 bool
13238 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
13239 {
13240     if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
13241         return BXWritePC(context, addr);
13242     else
13243         return BranchWritePC((const Context)context, addr);
13244 }
13245 
13246 EmulateInstructionARM::Mode
13247 EmulateInstructionARM::CurrentInstrSet ()
13248 {
13249     return m_opcode_mode;
13250 }
13251 
13252 // Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
13253 // ReadInstruction() is performed.  This function has a side effect of updating
13254 // the m_new_inst_cpsr member variable if necessary.
13255 bool
13256 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
13257 {
13258     m_new_inst_cpsr = m_opcode_cpsr;
13259     switch (arm_or_thumb)
13260     {
13261     default:
13262         return false;
13263     case eModeARM:
13264         // Clear the T bit.
13265         m_new_inst_cpsr &= ~MASK_CPSR_T;
13266         break;
13267     case eModeThumb:
13268         // Set the T bit.
13269         m_new_inst_cpsr |= MASK_CPSR_T;
13270         break;
13271     }
13272     return true;
13273 }
13274 
13275 // This function returns TRUE if the processor currently provides support for
13276 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
13277 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
13278 bool
13279 EmulateInstructionARM::UnalignedSupport()
13280 {
13281     return (ArchVersion() >= ARMv7);
13282 }
13283 
13284 // The main addition and subtraction instructions can produce status information
13285 // about both unsigned carry and signed overflow conditions.  This status
13286 // information can be used to synthesize multi-word additions and subtractions.
13287 EmulateInstructionARM::AddWithCarryResult
13288 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
13289 {
13290     uint32_t result;
13291     uint8_t carry_out;
13292     uint8_t overflow;
13293 
13294     uint64_t unsigned_sum = x + y + carry_in;
13295     int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
13296 
13297     result = UnsignedBits(unsigned_sum, 31, 0);
13298 //    carry_out = (result == unsigned_sum ? 0 : 1);
13299     overflow = ((int32_t)result == signed_sum ? 0 : 1);
13300 
13301     if (carry_in)
13302         carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0;
13303     else
13304         carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0;
13305 
13306     AddWithCarryResult res = { result, carry_out, overflow };
13307     return res;
13308 }
13309 
13310 uint32_t
13311 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
13312 {
13313     lldb::RegisterKind reg_kind;
13314     uint32_t reg_num;
13315     switch (num)
13316     {
13317     case SP_REG:
13318         reg_kind = eRegisterKindGeneric;
13319         reg_num  = LLDB_REGNUM_GENERIC_SP;
13320         break;
13321     case LR_REG:
13322         reg_kind = eRegisterKindGeneric;
13323         reg_num  = LLDB_REGNUM_GENERIC_RA;
13324         break;
13325     case PC_REG:
13326         reg_kind = eRegisterKindGeneric;
13327         reg_num  = LLDB_REGNUM_GENERIC_PC;
13328         break;
13329     default:
13330         if (num < SP_REG)
13331         {
13332             reg_kind = eRegisterKindDWARF;
13333             reg_num  = dwarf_r0 + num;
13334         }
13335         else
13336         {
13337             //assert(0 && "Invalid register number");
13338             *success = false;
13339             return UINT32_MAX;
13340         }
13341         break;
13342     }
13343 
13344     // Read our register.
13345     uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
13346 
13347     // When executing an ARM instruction , PC reads as the address of the current
13348     // instruction plus 8.
13349     // When executing a Thumb instruction , PC reads as the address of the current
13350     // instruction plus 4.
13351     if (num == 15)
13352     {
13353         if (CurrentInstrSet() == eModeARM)
13354             val += 8;
13355         else
13356             val += 4;
13357     }
13358 
13359     return val;
13360 }
13361 
13362 // Write the result to the ARM core register Rd, and optionally update the
13363 // condition flags based on the result.
13364 //
13365 // This helper method tries to encapsulate the following pseudocode from the
13366 // ARM Architecture Reference Manual:
13367 //
13368 // if d == 15 then         // Can only occur for encoding A1
13369 //     ALUWritePC(result); // setflags is always FALSE here
13370 // else
13371 //     R[d] = result;
13372 //     if setflags then
13373 //         APSR.N = result<31>;
13374 //         APSR.Z = IsZeroBit(result);
13375 //         APSR.C = carry;
13376 //         // APSR.V unchanged
13377 //
13378 // In the above case, the API client does not pass in the overflow arg, which
13379 // defaults to ~0u.
13380 bool
13381 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
13382                                                   const uint32_t result,
13383                                                   const uint32_t Rd,
13384                                                   bool setflags,
13385                                                   const uint32_t carry,
13386                                                   const uint32_t overflow)
13387 {
13388     if (Rd == 15)
13389     {
13390         if (!ALUWritePC (context, result))
13391             return false;
13392     }
13393     else
13394     {
13395         lldb::RegisterKind reg_kind;
13396         uint32_t reg_num;
13397         switch (Rd)
13398         {
13399         case SP_REG:
13400             reg_kind = eRegisterKindGeneric;
13401             reg_num  = LLDB_REGNUM_GENERIC_SP;
13402             break;
13403         case LR_REG:
13404             reg_kind = eRegisterKindGeneric;
13405             reg_num  = LLDB_REGNUM_GENERIC_RA;
13406             break;
13407         default:
13408             reg_kind = eRegisterKindDWARF;
13409             reg_num  = dwarf_r0 + Rd;
13410         }
13411         if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
13412             return false;
13413         if (setflags)
13414             return WriteFlags (context, result, carry, overflow);
13415     }
13416     return true;
13417 }
13418 
13419 // This helper method tries to encapsulate the following pseudocode from the
13420 // ARM Architecture Reference Manual:
13421 //
13422 // APSR.N = result<31>;
13423 // APSR.Z = IsZeroBit(result);
13424 // APSR.C = carry;
13425 // APSR.V = overflow
13426 //
13427 // Default arguments can be specified for carry and overflow parameters, which means
13428 // not to update the respective flags.
13429 bool
13430 EmulateInstructionARM::WriteFlags (Context &context,
13431                                    const uint32_t result,
13432                                    const uint32_t carry,
13433                                    const uint32_t overflow)
13434 {
13435     m_new_inst_cpsr = m_opcode_cpsr;
13436     SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
13437     SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
13438     if (carry != ~0u)
13439         SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
13440     if (overflow != ~0u)
13441         SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
13442     if (m_new_inst_cpsr != m_opcode_cpsr)
13443     {
13444         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13445             return false;
13446     }
13447     return true;
13448 }
13449 
13450 bool
13451 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
13452 {
13453     // Advance the ITSTATE bits to their values for the next instruction.
13454     if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
13455         m_it_session.ITAdvance();
13456 
13457     ARMOpcode *opcode_data = NULL;
13458 
13459     if (m_opcode_mode == eModeThumb)
13460         opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13461     else if (m_opcode_mode == eModeARM)
13462         opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13463 
13464     if (opcode_data == NULL)
13465         return false;
13466 
13467     const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
13468     m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
13469 
13470     bool success = false;
13471     if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
13472     {
13473         m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF,
13474                                                 dwarf_cpsr,
13475                                                 0,
13476                                                 &success);
13477     }
13478 
13479     // Only return false if we are unable to read the CPSR if we care about conditions
13480     if (success == false && m_ignore_conditions == false)
13481         return false;
13482 
13483     uint32_t orig_pc_value = 0;
13484     if (auto_advance_pc)
13485     {
13486         orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13487         if (!success)
13488             return false;
13489     }
13490 
13491     // Call the Emulate... function.
13492     success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
13493     if (!success)
13494         return false;
13495 
13496     if (auto_advance_pc)
13497     {
13498         uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13499         if (!success)
13500             return false;
13501 
13502         if (auto_advance_pc && (after_pc_value == orig_pc_value))
13503         {
13504             if (opcode_data->size == eSize32)
13505                 after_pc_value += 4;
13506             else if (opcode_data->size == eSize16)
13507                 after_pc_value += 2;
13508 
13509             EmulateInstruction::Context context;
13510             context.type = eContextAdvancePC;
13511             context.SetNoArgs();
13512             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
13513                 return false;
13514 
13515         }
13516     }
13517     return true;
13518 }
13519 
13520 bool
13521 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data)
13522 {
13523     if (!test_data)
13524     {
13525         out_stream->Printf ("TestEmulation: Missing test data.\n");
13526         return false;
13527     }
13528 
13529     static ConstString opcode_key ("opcode");
13530     static ConstString before_key ("before_state");
13531     static ConstString after_key ("after_state");
13532 
13533     OptionValueSP value_sp = test_data->GetValueForKey (opcode_key);
13534 
13535     uint32_t test_opcode;
13536     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64))
13537     {
13538         out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n");
13539         return false;
13540     }
13541     test_opcode = value_sp->GetUInt64Value ();
13542 
13543     if (arch.GetTriple().getArch() == llvm::Triple::arm)
13544     {
13545         m_opcode_mode = eModeARM;
13546         m_opcode.SetOpcode32 (test_opcode, GetByteOrder());
13547     }
13548     else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
13549     {
13550         m_opcode_mode = eModeThumb;
13551         if (test_opcode < 0x10000)
13552             m_opcode.SetOpcode16 (test_opcode, GetByteOrder());
13553         else
13554             m_opcode.SetOpcode32 (test_opcode, GetByteOrder());
13555 
13556     }
13557     else
13558     {
13559         out_stream->Printf ("TestEmulation:  Invalid arch.\n");
13560         return false;
13561     }
13562 
13563     EmulationStateARM before_state;
13564     EmulationStateARM after_state;
13565 
13566     value_sp = test_data->GetValueForKey (before_key);
13567     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13568     {
13569         out_stream->Printf ("TestEmulation:  Failed to find 'before' state.\n");
13570         return false;
13571     }
13572 
13573     OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary ();
13574     if (!before_state.LoadStateFromDictionary (state_dictionary))
13575     {
13576         out_stream->Printf ("TestEmulation:  Failed loading 'before' state.\n");
13577         return false;
13578     }
13579 
13580     value_sp = test_data->GetValueForKey (after_key);
13581     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13582     {
13583         out_stream->Printf ("TestEmulation:  Failed to find 'after' state.\n");
13584         return false;
13585     }
13586 
13587     state_dictionary = value_sp->GetAsDictionary ();
13588     if (!after_state.LoadStateFromDictionary (state_dictionary))
13589     {
13590         out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n");
13591         return false;
13592     }
13593 
13594     SetBaton ((void *) &before_state);
13595     SetCallbacks (&EmulationStateARM::ReadPseudoMemory,
13596                   &EmulationStateARM::WritePseudoMemory,
13597                   &EmulationStateARM::ReadPseudoRegister,
13598                   &EmulationStateARM::WritePseudoRegister);
13599 
13600     bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC);
13601     if (!success)
13602     {
13603         out_stream->Printf ("TestEmulation:  EvaluateInstruction() failed.\n");
13604         return false;
13605     }
13606 
13607     success = before_state.CompareState (after_state);
13608     if (!success)
13609         out_stream->Printf ("TestEmulation:  'before' and 'after' states do not match.\n");
13610 
13611     return success;
13612 }
13613 //
13614 //
13615 //const char *
13616 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
13617 //{
13618 //    if (reg_kind == eRegisterKindGeneric)
13619 //    {
13620 //        switch (reg_num)
13621 //        {
13622 //        case LLDB_REGNUM_GENERIC_PC:    return "pc";
13623 //        case LLDB_REGNUM_GENERIC_SP:    return "sp";
13624 //        case LLDB_REGNUM_GENERIC_FP:    return "fp";
13625 //        case LLDB_REGNUM_GENERIC_RA:    return "lr";
13626 //        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
13627 //        default: return NULL;
13628 //        }
13629 //    }
13630 //    else if (reg_kind == eRegisterKindDWARF)
13631 //    {
13632 //        return GetARMDWARFRegisterName (reg_num);
13633 //    }
13634 //    return NULL;
13635 //}
13636 //
13637 bool
13638 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
13639 {
13640     unwind_plan.Clear();
13641     unwind_plan.SetRegisterKind (eRegisterKindDWARF);
13642 
13643     UnwindPlan::RowSP row(new UnwindPlan::Row);
13644 
13645     // Our previous Call Frame Address is the stack pointer
13646     row->GetCFAValue().SetIsRegisterPlusOffset (dwarf_sp, 0);
13647 
13648     // Our previous PC is in the LR
13649     row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true);
13650     unwind_plan.AppendRow (row);
13651 
13652     // All other registers are the same.
13653 
13654     unwind_plan.SetSourceName ("EmulateInstructionARM");
13655     unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
13656     unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
13657     return true;
13658 }
13659