1 //===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include <stdlib.h>
11 
12 #include "EmulateInstructionARM.h"
13 #include "EmulationStateARM.h"
14 #include "lldb/Core/ArchSpec.h"
15 #include "lldb/Core/Address.h"
16 #include "lldb/Core/ConstString.h"
17 #include "lldb/Core/PluginManager.h"
18 #include "lldb/Core/Stream.h"
19 #include "lldb/Interpreter/OptionValueArray.h"
20 #include "lldb/Interpreter/OptionValueDictionary.h"
21 #include "lldb/Symbol/UnwindPlan.h"
22 
23 #include "Plugins/Process/Utility/ARMDefines.h"
24 #include "Plugins/Process/Utility/ARMUtils.h"
25 #include "Utility/ARM_DWARF_Registers.h"
26 
27 #include "llvm/ADT/STLExtras.h"
28 #include "llvm/Support/MathExtras.h" // for SignExtend32 template function
29                                      // and countTrailingZeros function
30 
31 using namespace lldb;
32 using namespace lldb_private;
33 
34 // Convenient macro definitions.
35 #define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS)
36 #define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS)
37 
38 #define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
39 
40 //----------------------------------------------------------------------
41 //
42 // ITSession implementation
43 //
44 //----------------------------------------------------------------------
45 
46 // A8.6.50
47 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
48 static uint32_t
49 CountITSize (uint32_t ITMask) {
50     // First count the trailing zeros of the IT mask.
51     uint32_t TZ = llvm::countTrailingZeros(ITMask);
52     if (TZ > 3)
53     {
54 #ifdef LLDB_CONFIGURATION_DEBUG
55         printf("Encoding error: IT Mask '0000'\n");
56 #endif
57         return 0;
58     }
59     return (4 - TZ);
60 }
61 
62 // Init ITState.  Note that at least one bit is always 1 in mask.
63 bool ITSession::InitIT(uint32_t bits7_0)
64 {
65     ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
66     if (ITCounter == 0)
67         return false;
68 
69     // A8.6.50 IT
70     unsigned short FirstCond = Bits32(bits7_0, 7, 4);
71     if (FirstCond == 0xF)
72     {
73 #ifdef LLDB_CONFIGURATION_DEBUG
74         printf("Encoding error: IT FirstCond '1111'\n");
75 #endif
76         return false;
77     }
78     if (FirstCond == 0xE && ITCounter != 1)
79     {
80 #ifdef LLDB_CONFIGURATION_DEBUG
81         printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
82 #endif
83         return false;
84     }
85 
86     ITState = bits7_0;
87     return true;
88 }
89 
90 // Update ITState if necessary.
91 void ITSession::ITAdvance()
92 {
93     //assert(ITCounter);
94     --ITCounter;
95     if (ITCounter == 0)
96         ITState = 0;
97     else
98     {
99         unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
100         SetBits32(ITState, 4, 0, NewITState4_0);
101     }
102 }
103 
104 // Return true if we're inside an IT Block.
105 bool ITSession::InITBlock()
106 {
107     return ITCounter != 0;
108 }
109 
110 // Return true if we're the last instruction inside an IT Block.
111 bool ITSession::LastInITBlock()
112 {
113     return ITCounter == 1;
114 }
115 
116 // Get condition bits for the current thumb instruction.
117 uint32_t ITSession::GetCond()
118 {
119     if (InITBlock())
120         return Bits32(ITState, 7, 4);
121     else
122         return COND_AL;
123 }
124 
125 // ARM constants used during decoding
126 #define REG_RD          0
127 #define LDM_REGLIST     1
128 #define SP_REG          13
129 #define LR_REG          14
130 #define PC_REG          15
131 #define PC_REGLIST_BIT  0x8000
132 
133 #define ARMv4     (1u << 0)
134 #define ARMv4T    (1u << 1)
135 #define ARMv5T    (1u << 2)
136 #define ARMv5TE   (1u << 3)
137 #define ARMv5TEJ  (1u << 4)
138 #define ARMv6     (1u << 5)
139 #define ARMv6K    (1u << 6)
140 #define ARMv6T2   (1u << 7)
141 #define ARMv7     (1u << 8)
142 #define ARMv7S    (1u << 9)
143 #define ARMv8     (1u << 10)
144 #define ARMvAll   (0xffffffffu)
145 
146 #define ARMV4T_ABOVE  (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
147 #define ARMV5_ABOVE   (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
148 #define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
149 #define ARMV5J_ABOVE  (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
150 #define ARMV6_ABOVE   (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
151 #define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv7S|ARMv8)
152 #define ARMV7_ABOVE   (ARMv7|ARMv7S|ARMv8)
153 
154 #define No_VFP  0
155 #define VFPv1   (1u << 1)
156 #define VFPv2   (1u << 2)
157 #define VFPv3   (1u << 3)
158 #define AdvancedSIMD (1u << 4)
159 
160 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
161 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
162 #define VFPv2v3     (VFPv2 | VFPv3)
163 
164 //----------------------------------------------------------------------
165 //
166 // EmulateInstructionARM implementation
167 //
168 //----------------------------------------------------------------------
169 
170 void
171 EmulateInstructionARM::Initialize ()
172 {
173     PluginManager::RegisterPlugin (GetPluginNameStatic (),
174                                    GetPluginDescriptionStatic (),
175                                    CreateInstance);
176 }
177 
178 void
179 EmulateInstructionARM::Terminate ()
180 {
181     PluginManager::UnregisterPlugin (CreateInstance);
182 }
183 
184 ConstString
185 EmulateInstructionARM::GetPluginNameStatic ()
186 {
187     static ConstString g_name("arm");
188     return g_name;
189 }
190 
191 const char *
192 EmulateInstructionARM::GetPluginDescriptionStatic ()
193 {
194     return "Emulate instructions for the ARM architecture.";
195 }
196 
197 EmulateInstruction *
198 EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type)
199 {
200     if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic(inst_type))
201     {
202         if (arch.GetTriple().getArch() == llvm::Triple::arm)
203         {
204             std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
205 
206             if (emulate_insn_ap.get())
207                 return emulate_insn_ap.release();
208         }
209         else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
210         {
211             std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
212 
213             if (emulate_insn_ap.get())
214                 return emulate_insn_ap.release();
215         }
216     }
217 
218     return NULL;
219 }
220 
221 bool
222 EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch)
223 {
224     if (arch.GetTriple().getArch () == llvm::Triple::arm)
225         return true;
226     else if (arch.GetTriple().getArch () == llvm::Triple::thumb)
227         return true;
228 
229     return false;
230 }
231 
232 // Write "bits (32) UNKNOWN" to memory address "address".  Helper function for many ARM instructions.
233 bool
234 EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address)
235 {
236     EmulateInstruction::Context context;
237     context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
238     context.SetNoArgs ();
239 
240     uint32_t random_data = rand ();
241     const uint32_t addr_byte_size = GetAddressByteSize();
242 
243     if (!MemAWrite (context, address, random_data, addr_byte_size))
244         return false;
245 
246     return true;
247 }
248 
249 // Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM instructions.
250 bool
251 EmulateInstructionARM::WriteBits32Unknown (int n)
252 {
253     EmulateInstruction::Context context;
254     context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
255     context.SetNoArgs ();
256 
257     bool success;
258     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
259 
260     if (!success)
261         return false;
262 
263     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
264         return false;
265 
266     return true;
267 }
268 
269 bool
270 EmulateInstructionARM::GetRegisterInfo (lldb::RegisterKind reg_kind, uint32_t reg_num, RegisterInfo &reg_info)
271 {
272     if (reg_kind == eRegisterKindGeneric)
273     {
274         switch (reg_num)
275         {
276             case LLDB_REGNUM_GENERIC_PC:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break;
277             case LLDB_REGNUM_GENERIC_SP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break;
278             case LLDB_REGNUM_GENERIC_FP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break;
279             case LLDB_REGNUM_GENERIC_RA:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break;
280             case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break;
281             default: return false;
282         }
283     }
284 
285     if (reg_kind == eRegisterKindDWARF)
286         return GetARMDWARFRegisterInfo(reg_num, reg_info);
287     return false;
288 }
289 
290 uint32_t
291 EmulateInstructionARM::GetFramePointerRegisterNumber () const
292 {
293     if (m_arch.GetTriple().isAndroid())
294         return LLDB_INVALID_REGNUM; // Don't use frame pointer on android
295     bool is_apple = false;
296     if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
297         is_apple = true;
298     switch (m_arch.GetTriple().getOS())
299     {
300             case llvm::Triple::Darwin:
301             case llvm::Triple::MacOSX:
302             case llvm::Triple::IOS:
303             case llvm::Triple::TvOS:
304             case llvm::Triple::WatchOS:
305                 is_apple = true;
306                 break;
307             default:
308                 break;
309     }
310 
311     /* On Apple iOS et al, the frame pointer register is always r7.
312      * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
313      */
314 
315     uint32_t fp_regnum = 11;
316 
317     if (is_apple)
318         fp_regnum = 7;
319 
320     if (m_opcode_mode == eModeThumb)
321         fp_regnum = 7;
322 
323     return fp_regnum;
324 }
325 
326 uint32_t
327 EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const
328 {
329     bool is_apple = false;
330     if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
331         is_apple = true;
332     switch (m_arch.GetTriple().getOS())
333     {
334             case llvm::Triple::Darwin:
335             case llvm::Triple::MacOSX:
336             case llvm::Triple::IOS:
337                 is_apple = true;
338                 break;
339             default:
340                 break;
341     }
342 
343     /* On Apple iOS et al, the frame pointer register is always r7.
344      * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
345      */
346 
347     uint32_t fp_regnum = dwarf_r11;
348 
349     if (is_apple)
350         fp_regnum = dwarf_r7;
351 
352     if (m_opcode_mode == eModeThumb)
353         fp_regnum = dwarf_r7;
354 
355     return fp_regnum;
356 }
357 
358 // Push Multiple Registers stores multiple registers to the stack, storing to
359 // consecutive memory locations ending just below the address in SP, and updates
360 // SP to point to the start of the stored data.
361 bool
362 EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding)
363 {
364 #if 0
365     // ARM pseudo code...
366     if (ConditionPassed())
367     {
368         EncodingSpecificOperations();
369         NullCheckIfThumbEE(13);
370         address = SP - 4*BitCount(registers);
371 
372         for (i = 0 to 14)
373         {
374             if (registers<i> == '1')
375             {
376                 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
377                     MemA[address,4] = bits(32) UNKNOWN;
378                 else
379                     MemA[address,4] = R[i];
380                 address = address + 4;
381             }
382         }
383 
384         if (registers<15> == '1') // Only possible for encoding A1 or A2
385             MemA[address,4] = PCStoreValue();
386 
387         SP = SP - 4*BitCount(registers);
388     }
389 #endif
390 
391     bool success = false;
392     if (ConditionPassed(opcode))
393     {
394         const uint32_t addr_byte_size = GetAddressByteSize();
395         const addr_t sp = ReadCoreReg (SP_REG, &success);
396         if (!success)
397             return false;
398         uint32_t registers = 0;
399         uint32_t Rt; // the source register
400         switch (encoding) {
401         case eEncodingT1:
402             registers = Bits32(opcode, 7, 0);
403             // The M bit represents LR.
404             if (Bit32(opcode, 8))
405                 registers |= (1u << 14);
406             // if BitCount(registers) < 1 then UNPREDICTABLE;
407             if (BitCount(registers) < 1)
408                 return false;
409             break;
410         case eEncodingT2:
411             // Ignore bits 15 & 13.
412             registers = Bits32(opcode, 15, 0) & ~0xa000;
413             // if BitCount(registers) < 2 then UNPREDICTABLE;
414             if (BitCount(registers) < 2)
415                 return false;
416             break;
417         case eEncodingT3:
418             Rt = Bits32(opcode, 15, 12);
419             // if BadReg(t) then UNPREDICTABLE;
420             if (BadReg(Rt))
421                 return false;
422             registers = (1u << Rt);
423             break;
424         case eEncodingA1:
425             registers = Bits32(opcode, 15, 0);
426             // Instead of return false, let's handle the following case as well,
427             // which amounts to pushing one reg onto the full descending stacks.
428             // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
429             break;
430         case eEncodingA2:
431             Rt = Bits32(opcode, 15, 12);
432             // if t == 13 then UNPREDICTABLE;
433             if (Rt == dwarf_sp)
434                 return false;
435             registers = (1u << Rt);
436             break;
437         default:
438             return false;
439         }
440         addr_t sp_offset = addr_byte_size * BitCount (registers);
441         addr_t addr = sp - sp_offset;
442         uint32_t i;
443 
444         EmulateInstruction::Context context;
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     if (ConditionPassed(opcode))
512     {
513         const uint32_t addr_byte_size = GetAddressByteSize();
514         const addr_t sp = ReadCoreReg (SP_REG, &success);
515         if (!success)
516             return false;
517         uint32_t registers = 0;
518         uint32_t Rt; // the destination register
519         switch (encoding) {
520         case eEncodingT1:
521             registers = Bits32(opcode, 7, 0);
522             // The P bit represents PC.
523             if (Bit32(opcode, 8))
524                 registers |= (1u << 15);
525             // if BitCount(registers) < 1 then UNPREDICTABLE;
526             if (BitCount(registers) < 1)
527                 return false;
528             break;
529         case eEncodingT2:
530             // Ignore bit 13.
531             registers = Bits32(opcode, 15, 0) & ~0x2000;
532             // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
533             if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
534                 return false;
535             // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
536             if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
537                 return false;
538             break;
539         case eEncodingT3:
540             Rt = Bits32(opcode, 15, 12);
541             // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
542             if (Rt == 13)
543                 return false;
544             if (Rt == 15 && InITBlock() && !LastInITBlock())
545                 return false;
546             registers = (1u << Rt);
547             break;
548         case eEncodingA1:
549             registers = Bits32(opcode, 15, 0);
550             // Instead of return false, let's handle the following case as well,
551             // which amounts to popping one reg from the full descending stacks.
552             // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
553 
554             // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
555             if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
556                 return false;
557             break;
558         case eEncodingA2:
559             Rt = Bits32(opcode, 15, 12);
560             // if t == 13 then UNPREDICTABLE;
561             if (Rt == dwarf_sp)
562                 return false;
563             registers = (1u << Rt);
564             break;
565         default:
566             return false;
567         }
568         addr_t sp_offset = addr_byte_size * BitCount (registers);
569         addr_t addr = sp;
570         uint32_t i, data;
571 
572         EmulateInstruction::Context context;
573         context.type = EmulateInstruction::eContextPopRegisterOffStack;
574 
575         RegisterInfo sp_reg;
576         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
577 
578         for (i=0; i<15; ++i)
579         {
580             if (BitIsSet (registers, i))
581             {
582                 context.SetAddress(addr);
583                 data = MemARead(context, addr, 4, 0, &success);
584                 if (!success)
585                     return false;
586                 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data))
587                     return false;
588                 addr += addr_byte_size;
589             }
590         }
591 
592         if (BitIsSet (registers, 15))
593         {
594             context.SetRegisterPlusOffset (sp_reg, addr - sp);
595             data = MemARead(context, addr, 4, 0, &success);
596             if (!success)
597                 return false;
598             // In ARMv5T and above, this is an interworking branch.
599             if (!LoadWritePC(context, data))
600                 return false;
601             //addr += addr_byte_size;
602         }
603 
604         context.type = EmulateInstruction::eContextAdjustStackPointer;
605         context.SetImmediateSigned (sp_offset);
606 
607         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
608             return false;
609     }
610     return true;
611 }
612 
613 // Set r7 or ip to point to saved value residing within the stack.
614 // ADD (SP plus immediate)
615 bool
616 EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding)
617 {
618 #if 0
619     // ARM pseudo code...
620     if (ConditionPassed())
621     {
622         EncodingSpecificOperations();
623         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
624         if d == 15 then
625            ALUWritePC(result); // setflags is always FALSE here
626         else
627             R[d] = result;
628             if setflags then
629                 APSR.N = result<31>;
630                 APSR.Z = IsZeroBit(result);
631                 APSR.C = carry;
632                 APSR.V = overflow;
633     }
634 #endif
635 
636     bool success = false;
637 
638     if (ConditionPassed(opcode))
639     {
640         const addr_t sp = ReadCoreReg (SP_REG, &success);
641         if (!success)
642             return false;
643         uint32_t Rd; // the destination register
644         uint32_t imm32;
645         switch (encoding) {
646         case eEncodingT1:
647             Rd = 7;
648             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
649             break;
650         case eEncodingA1:
651             Rd = Bits32(opcode, 15, 12);
652             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
653             break;
654         default:
655             return false;
656         }
657         addr_t sp_offset = imm32;
658         addr_t addr = sp + sp_offset; // a pointer to the stack area
659 
660         EmulateInstruction::Context context;
661         if (Rd == GetFramePointerRegisterNumber())
662             context.type = eContextSetFramePointer;
663         else
664             context.type = EmulateInstruction::eContextRegisterPlusOffset;
665         RegisterInfo sp_reg;
666         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
667         context.SetRegisterPlusOffset (sp_reg, sp_offset);
668 
669         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
670             return false;
671     }
672     return true;
673 }
674 
675 // Set r7 or ip to the current stack pointer.
676 // MOV (register)
677 bool
678 EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding)
679 {
680 #if 0
681     // ARM pseudo code...
682     if (ConditionPassed())
683     {
684         EncodingSpecificOperations();
685         result = R[m];
686         if d == 15 then
687             ALUWritePC(result); // setflags is always FALSE here
688         else
689             R[d] = result;
690             if setflags then
691                 APSR.N = result<31>;
692                 APSR.Z = IsZeroBit(result);
693                 // APSR.C unchanged
694                 // APSR.V unchanged
695     }
696 #endif
697 
698     bool success = false;
699 
700     if (ConditionPassed(opcode))
701     {
702         const addr_t sp = ReadCoreReg (SP_REG, &success);
703         if (!success)
704             return false;
705         uint32_t Rd; // the destination register
706         switch (encoding) {
707         case eEncodingT1:
708             Rd = 7;
709             break;
710         case eEncodingA1:
711             Rd = 12;
712             break;
713         default:
714             return false;
715         }
716 
717         EmulateInstruction::Context context;
718         if (Rd == GetFramePointerRegisterNumber())
719             context.type = EmulateInstruction::eContextSetFramePointer;
720         else
721             context.type = EmulateInstruction::eContextRegisterPlusOffset;
722         RegisterInfo sp_reg;
723         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
724         context.SetRegisterPlusOffset (sp_reg, 0);
725 
726         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
727             return false;
728     }
729     return true;
730 }
731 
732 // Move from high register (r8-r15) to low register (r0-r7).
733 // MOV (register)
734 bool
735 EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding)
736 {
737     return EmulateMOVRdRm (opcode, encoding);
738 }
739 
740 // Move from register to register.
741 // MOV (register)
742 bool
743 EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding)
744 {
745 #if 0
746     // ARM pseudo code...
747     if (ConditionPassed())
748     {
749         EncodingSpecificOperations();
750         result = R[m];
751         if d == 15 then
752             ALUWritePC(result); // setflags is always FALSE here
753         else
754             R[d] = result;
755             if setflags then
756                 APSR.N = result<31>;
757                 APSR.Z = IsZeroBit(result);
758                 // APSR.C unchanged
759                 // APSR.V unchanged
760     }
761 #endif
762 
763     bool success = false;
764 
765     if (ConditionPassed(opcode))
766     {
767         uint32_t Rm; // the source register
768         uint32_t Rd; // the destination register
769         bool setflags;
770         switch (encoding) {
771         case eEncodingT1:
772             Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
773             Rm = Bits32(opcode, 6, 3);
774             setflags = false;
775             if (Rd == 15 && InITBlock() && !LastInITBlock())
776                 return false;
777             break;
778         case eEncodingT2:
779             Rd = Bits32(opcode, 2, 0);
780             Rm = Bits32(opcode, 5, 3);
781             setflags = true;
782             if (InITBlock())
783                 return false;
784             break;
785         case eEncodingT3:
786             Rd = Bits32(opcode, 11, 8);
787             Rm = Bits32(opcode, 3, 0);
788             setflags = BitIsSet(opcode, 20);
789             // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
790             if (setflags && (BadReg(Rd) || BadReg(Rm)))
791                 return false;
792             // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE;
793             if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
794                 return false;
795             break;
796         case eEncodingA1:
797             Rd = Bits32(opcode, 15, 12);
798             Rm = Bits32(opcode, 3, 0);
799             setflags = BitIsSet(opcode, 20);
800 
801             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
802             if (Rd == 15 && setflags)
803                 return EmulateSUBSPcLrEtc (opcode, encoding);
804             break;
805         default:
806             return false;
807         }
808         uint32_t result = ReadCoreReg(Rm, &success);
809         if (!success)
810             return false;
811 
812         // The context specifies that Rm is to be moved into Rd.
813         EmulateInstruction::Context context;
814         if (Rd == 13)
815             context.type = EmulateInstruction::eContextAdjustStackPointer;
816         else
817             context.type = EmulateInstruction::eContextRegisterPlusOffset;
818         RegisterInfo dwarf_reg;
819         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
820         context.SetRegisterPlusOffset (dwarf_reg, 0);
821 
822         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
823             return false;
824     }
825     return true;
826 }
827 
828 // Move (immediate) writes an immediate value to the destination register.  It
829 // can optionally update the condition flags based on the value.
830 // MOV (immediate)
831 bool
832 EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding)
833 {
834 #if 0
835     // ARM pseudo code...
836     if (ConditionPassed())
837     {
838         EncodingSpecificOperations();
839         result = imm32;
840         if d == 15 then         // Can only occur for ARM encoding
841             ALUWritePC(result); // setflags is always FALSE here
842         else
843             R[d] = result;
844             if setflags then
845                 APSR.N = result<31>;
846                 APSR.Z = IsZeroBit(result);
847                 APSR.C = carry;
848                 // APSR.V unchanged
849     }
850 #endif
851 
852     if (ConditionPassed(opcode))
853     {
854         uint32_t Rd; // the destination register
855         uint32_t imm32; // the immediate value to be written to Rd
856         uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
857                             // for setflags == false, this value is a don't care
858                             // initialized to 0 to silence the static analyzer
859         bool setflags;
860         switch (encoding) {
861             case eEncodingT1:
862                 Rd = Bits32(opcode, 10, 8);
863                 setflags = !InITBlock();
864                 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
865                 carry = APSR_C;
866 
867                 break;
868 
869             case eEncodingT2:
870                 Rd = Bits32(opcode, 11, 8);
871                 setflags = BitIsSet(opcode, 20);
872                 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
873                 if (BadReg(Rd))
874                   return false;
875 
876                 break;
877 
878             case eEncodingT3:
879             {
880                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32);
881                 Rd = Bits32 (opcode, 11, 8);
882                 setflags = false;
883                 uint32_t imm4 = Bits32 (opcode, 19, 16);
884                 uint32_t imm3 = Bits32 (opcode, 14, 12);
885                 uint32_t i = Bit32 (opcode, 26);
886                 uint32_t imm8 = Bits32 (opcode, 7, 0);
887                 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
888 
889                 // if BadReg(d) then UNPREDICTABLE;
890                 if (BadReg (Rd))
891                     return false;
892             }
893                 break;
894 
895             case eEncodingA1:
896                 // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C);
897                 Rd = Bits32 (opcode, 15, 12);
898                 setflags = BitIsSet (opcode, 20);
899                 imm32 = ARMExpandImm_C (opcode, APSR_C, carry);
900 
901                 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
902                 if ((Rd == 15) && setflags)
903                     return EmulateSUBSPcLrEtc (opcode, encoding);
904 
905                 break;
906 
907             case eEncodingA2:
908             {
909                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
910                 Rd = Bits32 (opcode, 15, 12);
911                 setflags = false;
912                 uint32_t imm4 = Bits32 (opcode, 19, 16);
913                 uint32_t imm12 = Bits32 (opcode, 11, 0);
914                 imm32 = (imm4 << 12) | imm12;
915 
916                 // if d == 15 then UNPREDICTABLE;
917                 if (Rd == 15)
918                     return false;
919             }
920                 break;
921 
922             default:
923                 return false;
924         }
925         uint32_t result = imm32;
926 
927         // The context specifies that an immediate is to be moved into Rd.
928         EmulateInstruction::Context context;
929         context.type = EmulateInstruction::eContextImmediate;
930         context.SetNoArgs ();
931 
932         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
933             return false;
934     }
935     return true;
936 }
937 
938 // MUL multiplies two register values.  The least significant 32 bits of the result are written to the destination
939 // register.  These 32 bits do not depend on whether the source register values are considered to be signed values or
940 // unsigned values.
941 //
942 // Optionally, it can update the condition flags based on the result.  In the Thumb instruction set, this option is
943 // limited to only a few forms of the instruction.
944 bool
945 EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding)
946 {
947 #if 0
948     if ConditionPassed() then
949         EncodingSpecificOperations();
950         operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
951         operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
952         result = operand1 * operand2;
953         R[d] = result<31:0>;
954         if setflags then
955             APSR.N = result<31>;
956             APSR.Z = IsZeroBit(result);
957             if ArchVersion() == 4 then
958                 APSR.C = bit UNKNOWN;
959             // else APSR.C unchanged
960             // APSR.V always unchanged
961 #endif
962 
963     if (ConditionPassed(opcode))
964     {
965         uint32_t d;
966         uint32_t n;
967         uint32_t m;
968         bool setflags;
969 
970         // EncodingSpecificOperations();
971         switch (encoding)
972         {
973             case eEncodingT1:
974                 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
975                 d = Bits32 (opcode, 2, 0);
976                 n = Bits32 (opcode, 5, 3);
977                 m = Bits32 (opcode, 2, 0);
978                 setflags = !InITBlock();
979 
980                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
981                 if ((ArchVersion() < ARMv6) && (d == n))
982                     return false;
983 
984                 break;
985 
986             case eEncodingT2:
987                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
988                 d = Bits32 (opcode, 11, 8);
989                 n = Bits32 (opcode, 19, 16);
990                 m = Bits32 (opcode, 3, 0);
991                 setflags = false;
992 
993                 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
994                 if (BadReg (d) || BadReg (n) || BadReg (m))
995                     return false;
996 
997                 break;
998 
999             case eEncodingA1:
1000                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
1001                 d = Bits32 (opcode, 19, 16);
1002                 n = Bits32 (opcode, 3, 0);
1003                 m = Bits32 (opcode, 11, 8);
1004                 setflags = BitIsSet (opcode, 20);
1005 
1006                 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
1007                 if ((d == 15) ||  (n == 15) || (m == 15))
1008                     return false;
1009 
1010                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1011                 if ((ArchVersion() < ARMv6) && (d == n))
1012                     return false;
1013 
1014                 break;
1015 
1016             default:
1017                 return false;
1018         }
1019 
1020         bool success = false;
1021 
1022         // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
1023         uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
1024         if (!success)
1025             return false;
1026 
1027         // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
1028         uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
1029         if (!success)
1030             return false;
1031 
1032         // result = operand1 * operand2;
1033         uint64_t result = operand1 * operand2;
1034 
1035         // R[d] = result<31:0>;
1036         RegisterInfo op1_reg;
1037         RegisterInfo op2_reg;
1038         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
1039         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
1040 
1041         EmulateInstruction::Context context;
1042         context.type = eContextArithmetic;
1043         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
1044 
1045         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result)))
1046             return false;
1047 
1048         // if setflags then
1049         if (setflags)
1050         {
1051             // APSR.N = result<31>;
1052             // APSR.Z = IsZeroBit(result);
1053             m_new_inst_cpsr = m_opcode_cpsr;
1054             SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31));
1055             SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1056             if (m_new_inst_cpsr != m_opcode_cpsr)
1057             {
1058                 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1059                     return false;
1060             }
1061 
1062             // if ArchVersion() == 4 then
1063                 // APSR.C = bit UNKNOWN;
1064         }
1065     }
1066     return true;
1067 }
1068 
1069 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register.
1070 // It can optionally update the condition flags based on the value.
1071 bool
1072 EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding)
1073 {
1074 #if 0
1075     // ARM pseudo code...
1076     if (ConditionPassed())
1077     {
1078         EncodingSpecificOperations();
1079         result = NOT(imm32);
1080         if d == 15 then         // Can only occur for ARM encoding
1081             ALUWritePC(result); // setflags is always FALSE here
1082         else
1083             R[d] = result;
1084             if setflags then
1085                 APSR.N = result<31>;
1086                 APSR.Z = IsZeroBit(result);
1087                 APSR.C = carry;
1088                 // APSR.V unchanged
1089     }
1090 #endif
1091 
1092     if (ConditionPassed(opcode))
1093     {
1094         uint32_t Rd; // the destination register
1095         uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1096         uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1097         bool setflags;
1098         switch (encoding) {
1099         case eEncodingT1:
1100             Rd = Bits32(opcode, 11, 8);
1101             setflags = BitIsSet(opcode, 20);
1102             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1103             break;
1104         case eEncodingA1:
1105             Rd = Bits32(opcode, 15, 12);
1106             setflags = BitIsSet(opcode, 20);
1107             imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1108 
1109             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1110             if (Rd == 15 && setflags)
1111                 return EmulateSUBSPcLrEtc (opcode, encoding);
1112             break;
1113         default:
1114             return false;
1115         }
1116         uint32_t result = ~imm32;
1117 
1118         // The context specifies that an immediate is to be moved into Rd.
1119         EmulateInstruction::Context context;
1120         context.type = EmulateInstruction::eContextImmediate;
1121         context.SetNoArgs ();
1122 
1123         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1124             return false;
1125     }
1126     return true;
1127 }
1128 
1129 // Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register.
1130 // It can optionally update the condition flags based on the result.
1131 bool
1132 EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding)
1133 {
1134 #if 0
1135     // ARM pseudo code...
1136     if (ConditionPassed())
1137     {
1138         EncodingSpecificOperations();
1139         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1140         result = NOT(shifted);
1141         if d == 15 then         // Can only occur for ARM encoding
1142             ALUWritePC(result); // setflags is always FALSE here
1143         else
1144             R[d] = result;
1145             if setflags then
1146                 APSR.N = result<31>;
1147                 APSR.Z = IsZeroBit(result);
1148                 APSR.C = carry;
1149                 // APSR.V unchanged
1150     }
1151 #endif
1152 
1153     if (ConditionPassed(opcode))
1154     {
1155         uint32_t Rm; // the source register
1156         uint32_t Rd; // the destination register
1157         ARM_ShifterType shift_t;
1158         uint32_t shift_n; // the shift applied to the value read from Rm
1159         bool setflags;
1160         uint32_t carry; // the carry bit after the shift operation
1161         switch (encoding) {
1162         case eEncodingT1:
1163             Rd = Bits32(opcode, 2, 0);
1164             Rm = Bits32(opcode, 5, 3);
1165             setflags = !InITBlock();
1166             shift_t = SRType_LSL;
1167             shift_n = 0;
1168             if (InITBlock())
1169                 return false;
1170             break;
1171         case eEncodingT2:
1172             Rd = Bits32(opcode, 11, 8);
1173             Rm = Bits32(opcode, 3, 0);
1174             setflags = BitIsSet(opcode, 20);
1175             shift_n = DecodeImmShiftThumb(opcode, shift_t);
1176             // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1177             if (BadReg(Rd) || BadReg(Rm))
1178                 return false;
1179             break;
1180         case eEncodingA1:
1181             Rd = Bits32(opcode, 15, 12);
1182             Rm = Bits32(opcode, 3, 0);
1183             setflags = BitIsSet(opcode, 20);
1184             shift_n = DecodeImmShiftARM(opcode, shift_t);
1185             break;
1186         default:
1187             return false;
1188         }
1189         bool success = false;
1190         uint32_t value = ReadCoreReg(Rm, &success);
1191         if (!success)
1192             return false;
1193 
1194         uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1195         if (!success)
1196             return false;
1197         uint32_t result = ~shifted;
1198 
1199         // The context specifies that an immediate is to be moved into Rd.
1200         EmulateInstruction::Context context;
1201         context.type = EmulateInstruction::eContextImmediate;
1202         context.SetNoArgs ();
1203 
1204         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1205             return false;
1206     }
1207     return true;
1208 }
1209 
1210 // PC relative immediate load into register, possibly followed by ADD (SP plus register).
1211 // LDR (literal)
1212 bool
1213 EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding)
1214 {
1215 #if 0
1216     // ARM pseudo code...
1217     if (ConditionPassed())
1218     {
1219         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1220         base = Align(PC,4);
1221         address = if add then (base + imm32) else (base - imm32);
1222         data = MemU[address,4];
1223         if t == 15 then
1224             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1225         elsif UnalignedSupport() || address<1:0> = '00' then
1226             R[t] = data;
1227         else // Can only apply before ARMv7
1228             if CurrentInstrSet() == InstrSet_ARM then
1229                 R[t] = ROR(data, 8*UInt(address<1:0>));
1230             else
1231                 R[t] = bits(32) UNKNOWN;
1232     }
1233 #endif
1234 
1235     if (ConditionPassed(opcode))
1236     {
1237         bool success = false;
1238         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1239         if (!success)
1240             return false;
1241 
1242         // PC relative immediate load context
1243         EmulateInstruction::Context context;
1244         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1245         RegisterInfo pc_reg;
1246         GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
1247         context.SetRegisterPlusOffset (pc_reg, 0);
1248 
1249         uint32_t Rt;    // the destination register
1250         uint32_t imm32; // immediate offset from the PC
1251         bool add;       // +imm32 or -imm32?
1252         addr_t base;    // the base address
1253         addr_t address; // the PC relative address
1254         uint32_t data;  // the literal data value from the PC relative load
1255         switch (encoding) {
1256         case eEncodingT1:
1257             Rt = Bits32(opcode, 10, 8);
1258             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1259             add = true;
1260             break;
1261         case eEncodingT2:
1262             Rt = Bits32(opcode, 15, 12);
1263             imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1264             add = BitIsSet(opcode, 23);
1265             if (Rt == 15 && InITBlock() && !LastInITBlock())
1266                 return false;
1267             break;
1268         default:
1269             return false;
1270         }
1271 
1272         base = Align(pc, 4);
1273         if (add)
1274             address = base + imm32;
1275         else
1276             address = base - imm32;
1277 
1278         context.SetRegisterPlusOffset(pc_reg, address - base);
1279         data = MemURead(context, address, 4, 0, &success);
1280         if (!success)
1281             return false;
1282 
1283         if (Rt == 15)
1284         {
1285             if (Bits32(address, 1, 0) == 0)
1286             {
1287                 // In ARMv5T and above, this is an interworking branch.
1288                 if (!LoadWritePC(context, data))
1289                     return false;
1290             }
1291             else
1292                 return false;
1293         }
1294         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
1295         {
1296             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
1297                 return false;
1298         }
1299         else // We don't handle ARM for now.
1300             return false;
1301 
1302     }
1303     return true;
1304 }
1305 
1306 // An add operation to adjust the SP.
1307 // ADD (SP plus immediate)
1308 bool
1309 EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding)
1310 {
1311 #if 0
1312     // ARM pseudo code...
1313     if (ConditionPassed())
1314     {
1315         EncodingSpecificOperations();
1316         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1317         if d == 15 then // Can only occur for ARM encoding
1318             ALUWritePC(result); // setflags is always FALSE here
1319         else
1320             R[d] = result;
1321             if setflags then
1322                 APSR.N = result<31>;
1323                 APSR.Z = IsZeroBit(result);
1324                 APSR.C = carry;
1325                 APSR.V = overflow;
1326     }
1327 #endif
1328 
1329     bool success = false;
1330 
1331     if (ConditionPassed(opcode))
1332     {
1333         const addr_t sp = ReadCoreReg (SP_REG, &success);
1334         if (!success)
1335             return false;
1336         uint32_t imm32; // the immediate operand
1337         uint32_t d;
1338         bool setflags;
1339         switch (encoding)
1340         {
1341             case eEncodingT1:
1342                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1343                 d = Bits32 (opcode, 10, 8);
1344                 imm32 = (Bits32 (opcode, 7, 0) << 2);
1345                 setflags = false;
1346                 break;
1347 
1348             case eEncodingT2:
1349                 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1350                 d = 13;
1351                 imm32 = ThumbImm7Scaled (opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1352                 setflags = false;
1353                 break;
1354 
1355             case eEncodingT3:
1356                 // d = UInt(Rd); setflags = (S == "1"); imm32 = ThumbExpandImm(i:imm3:imm8);
1357                 d = Bits32 (opcode, 11, 8);
1358                 imm32 = ThumbExpandImm (opcode);
1359                 setflags = Bit32 (opcode, 20);
1360 
1361                 // if Rd == "1111" && S == "1" then SEE CMN (immediate);
1362                 if (d == 15 && setflags == 1)
1363                     return false; // CMN (immediate) not yet supported
1364 
1365                 // if d == 15 && S == "0" then UNPREDICTABLE;
1366                 if (d == 15 && setflags == 0)
1367                     return false;
1368                 break;
1369 
1370             case eEncodingT4:
1371                 {
1372                     // if Rn == '1111' then SEE ADR;
1373                     // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
1374                     d = Bits32 (opcode, 11, 8);
1375                     setflags = false;
1376                     uint32_t i = Bit32 (opcode, 26);
1377                     uint32_t imm3 = Bits32 (opcode, 14, 12);
1378                     uint32_t imm8 = Bits32 (opcode, 7, 0);
1379                     imm32 = (i << 11) | (imm3 << 8) | imm8;
1380 
1381                     // if d == 15 then UNPREDICTABLE;
1382                     if (d == 15)
1383                         return false;
1384                 }
1385                 break;
1386 
1387             default:
1388                 return false;
1389         }
1390         // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
1391         AddWithCarryResult res = AddWithCarry (sp, imm32, 0);
1392 
1393         EmulateInstruction::Context context;
1394         if (d == 13)
1395             context.type = EmulateInstruction::eContextAdjustStackPointer;
1396         else
1397             context.type = EmulateInstruction::eContextRegisterPlusOffset;
1398 
1399         RegisterInfo sp_reg;
1400         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1401         context.SetRegisterPlusOffset (sp_reg, res.result - sp);
1402 
1403         if (d == 15)
1404         {
1405             if (!ALUWritePC (context, res.result))
1406                 return false;
1407         }
1408         else
1409         {
1410             // R[d] = result;
1411             // if setflags then
1412             //     APSR.N = result<31>;
1413             //     APSR.Z = IsZeroBit(result);
1414             //     APSR.C = carry;
1415             //     APSR.V = overflow;
1416             if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
1417                 return false;
1418         }
1419     }
1420     return true;
1421 }
1422 
1423 // An add operation to adjust the SP.
1424 // ADD (SP plus register)
1425 bool
1426 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding)
1427 {
1428 #if 0
1429     // ARM pseudo code...
1430     if (ConditionPassed())
1431     {
1432         EncodingSpecificOperations();
1433         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1434         (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1435         if d == 15 then
1436             ALUWritePC(result); // setflags is always FALSE here
1437         else
1438             R[d] = result;
1439             if setflags then
1440                 APSR.N = result<31>;
1441                 APSR.Z = IsZeroBit(result);
1442                 APSR.C = carry;
1443                 APSR.V = overflow;
1444     }
1445 #endif
1446 
1447     bool success = false;
1448 
1449     if (ConditionPassed(opcode))
1450     {
1451         const addr_t sp = ReadCoreReg (SP_REG, &success);
1452         if (!success)
1453             return false;
1454         uint32_t Rm; // the second operand
1455         switch (encoding) {
1456         case eEncodingT2:
1457             Rm = Bits32(opcode, 6, 3);
1458             break;
1459         default:
1460             return false;
1461         }
1462         int32_t reg_value = ReadCoreReg(Rm, &success);
1463         if (!success)
1464             return false;
1465 
1466         addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1467 
1468         EmulateInstruction::Context context;
1469         context.type = eContextArithmetic;
1470         RegisterInfo sp_reg;
1471         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1472 
1473         RegisterInfo other_reg;
1474         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1475         context.SetRegisterRegisterOperands (sp_reg, other_reg);
1476 
1477         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
1478             return false;
1479     }
1480     return true;
1481 }
1482 
1483 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
1484 // at a PC-relative address, and changes instruction set from ARM to Thumb, or
1485 // from Thumb to ARM.
1486 // BLX (immediate)
1487 bool
1488 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding)
1489 {
1490 #if 0
1491     // ARM pseudo code...
1492     if (ConditionPassed())
1493     {
1494         EncodingSpecificOperations();
1495         if CurrentInstrSet() == InstrSet_ARM then
1496             LR = PC - 4;
1497         else
1498             LR = PC<31:1> : '1';
1499         if targetInstrSet == InstrSet_ARM then
1500             targetAddress = Align(PC,4) + imm32;
1501         else
1502             targetAddress = PC + imm32;
1503         SelectInstrSet(targetInstrSet);
1504         BranchWritePC(targetAddress);
1505     }
1506 #endif
1507 
1508     bool success = true;
1509 
1510     if (ConditionPassed(opcode))
1511     {
1512         EmulateInstruction::Context context;
1513         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1514         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1515         if (!success)
1516             return false;
1517         addr_t lr; // next instruction address
1518         addr_t target; // target address
1519         int32_t imm32; // PC-relative offset
1520         switch (encoding) {
1521         case eEncodingT1:
1522             {
1523             lr = pc | 1u; // return address
1524             uint32_t S = Bit32(opcode, 26);
1525             uint32_t imm10 = Bits32(opcode, 25, 16);
1526             uint32_t J1 = Bit32(opcode, 13);
1527             uint32_t J2 = Bit32(opcode, 11);
1528             uint32_t imm11 = Bits32(opcode, 10, 0);
1529             uint32_t I1 = !(J1 ^ S);
1530             uint32_t I2 = !(J2 ^ S);
1531             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1532             imm32 = llvm::SignExtend32<25>(imm25);
1533             target = pc + imm32;
1534             SelectInstrSet (eModeThumb);
1535             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
1536             if (InITBlock() && !LastInITBlock())
1537                 return false;
1538             break;
1539             }
1540         case eEncodingT2:
1541             {
1542             lr = pc | 1u; // return address
1543             uint32_t S = Bit32(opcode, 26);
1544             uint32_t imm10H = Bits32(opcode, 25, 16);
1545             uint32_t J1 = Bit32(opcode, 13);
1546             uint32_t J2 = Bit32(opcode, 11);
1547             uint32_t imm10L = Bits32(opcode, 10, 1);
1548             uint32_t I1 = !(J1 ^ S);
1549             uint32_t I2 = !(J2 ^ S);
1550             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
1551             imm32 = llvm::SignExtend32<25>(imm25);
1552             target = Align(pc, 4) + imm32;
1553             SelectInstrSet (eModeARM);
1554             context.SetISAAndImmediateSigned (eModeARM, 4 + imm32);
1555             if (InITBlock() && !LastInITBlock())
1556                 return false;
1557             break;
1558             }
1559         case eEncodingA1:
1560             lr = pc - 4; // return address
1561             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1562             target = Align(pc, 4) + imm32;
1563             SelectInstrSet (eModeARM);
1564             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
1565             break;
1566         case eEncodingA2:
1567             lr = pc - 4; // return address
1568             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
1569             target = pc + imm32;
1570             SelectInstrSet (eModeThumb);
1571             context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32);
1572             break;
1573         default:
1574             return false;
1575         }
1576         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1577             return false;
1578         if (!BranchWritePC(context, target))
1579             return false;
1580         if (m_opcode_cpsr != m_new_inst_cpsr)
1581             if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1582                 return false;
1583     }
1584     return true;
1585 }
1586 
1587 // Branch with Link and Exchange (register) calls a subroutine at an address and
1588 // instruction set specified by a register.
1589 // BLX (register)
1590 bool
1591 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding)
1592 {
1593 #if 0
1594     // ARM pseudo code...
1595     if (ConditionPassed())
1596     {
1597         EncodingSpecificOperations();
1598         target = R[m];
1599         if CurrentInstrSet() == InstrSet_ARM then
1600             next_instr_addr = PC - 4;
1601             LR = next_instr_addr;
1602         else
1603             next_instr_addr = PC - 2;
1604             LR = next_instr_addr<31:1> : '1';
1605         BXWritePC(target);
1606     }
1607 #endif
1608 
1609     bool success = false;
1610 
1611     if (ConditionPassed(opcode))
1612     {
1613         EmulateInstruction::Context context;
1614         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1615         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1616         addr_t lr; // next instruction address
1617         if (!success)
1618             return false;
1619         uint32_t Rm; // the register with the target address
1620         switch (encoding) {
1621         case eEncodingT1:
1622             lr = (pc - 2) | 1u; // return address
1623             Rm = Bits32(opcode, 6, 3);
1624             // if m == 15 then UNPREDICTABLE;
1625             if (Rm == 15)
1626                 return false;
1627             if (InITBlock() && !LastInITBlock())
1628                 return false;
1629             break;
1630         case eEncodingA1:
1631             lr = pc - 4; // return address
1632             Rm = Bits32(opcode, 3, 0);
1633             // if m == 15 then UNPREDICTABLE;
1634             if (Rm == 15)
1635                 return false;
1636             break;
1637         default:
1638             return false;
1639         }
1640         addr_t target = ReadCoreReg (Rm, &success);
1641         if (!success)
1642             return false;
1643         RegisterInfo dwarf_reg;
1644         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1645         context.SetRegister (dwarf_reg);
1646         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1647             return false;
1648         if (!BXWritePC(context, target))
1649             return false;
1650     }
1651     return true;
1652 }
1653 
1654 // Branch and Exchange causes a branch to an address and instruction set specified by a register.
1655 bool
1656 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding)
1657 {
1658 #if 0
1659     // ARM pseudo code...
1660     if (ConditionPassed())
1661     {
1662         EncodingSpecificOperations();
1663         BXWritePC(R[m]);
1664     }
1665 #endif
1666 
1667     if (ConditionPassed(opcode))
1668     {
1669         EmulateInstruction::Context context;
1670         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1671         uint32_t Rm; // the register with the target address
1672         switch (encoding) {
1673         case eEncodingT1:
1674             Rm = Bits32(opcode, 6, 3);
1675             if (InITBlock() && !LastInITBlock())
1676                 return false;
1677             break;
1678         case eEncodingA1:
1679             Rm = Bits32(opcode, 3, 0);
1680             break;
1681         default:
1682             return false;
1683         }
1684         bool success = false;
1685         addr_t target = ReadCoreReg (Rm, &success);
1686         if (!success)
1687             return false;
1688 
1689         RegisterInfo dwarf_reg;
1690         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1691         context.SetRegister (dwarf_reg);
1692         if (!BXWritePC(context, target))
1693             return false;
1694     }
1695     return true;
1696 }
1697 
1698 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an
1699 // address and instruction set specified by a register as though it were a BX instruction.
1700 //
1701 // TODO: Emulate Jazelle architecture?
1702 //       We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation.
1703 bool
1704 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding)
1705 {
1706 #if 0
1707     // ARM pseudo code...
1708     if (ConditionPassed())
1709     {
1710         EncodingSpecificOperations();
1711         if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
1712             BXWritePC(R[m]);
1713         else
1714             if JazelleAcceptsExecution() then
1715                 SwitchToJazelleExecution();
1716             else
1717                 SUBARCHITECTURE_DEFINED handler call;
1718     }
1719 #endif
1720 
1721     if (ConditionPassed(opcode))
1722     {
1723         EmulateInstruction::Context context;
1724         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1725         uint32_t Rm; // the register with the target address
1726         switch (encoding) {
1727         case eEncodingT1:
1728             Rm = Bits32(opcode, 19, 16);
1729             if (BadReg(Rm))
1730                 return false;
1731             if (InITBlock() && !LastInITBlock())
1732                 return false;
1733             break;
1734         case eEncodingA1:
1735             Rm = Bits32(opcode, 3, 0);
1736             if (Rm == 15)
1737                 return false;
1738             break;
1739         default:
1740             return false;
1741         }
1742         bool success = false;
1743         addr_t target = ReadCoreReg (Rm, &success);
1744         if (!success)
1745             return false;
1746 
1747         RegisterInfo dwarf_reg;
1748         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1749         context.SetRegister (dwarf_reg);
1750         if (!BXWritePC(context, target))
1751             return false;
1752     }
1753     return true;
1754 }
1755 
1756 // Set r7 to point to some ip offset.
1757 // SUB (immediate)
1758 bool
1759 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding)
1760 {
1761 #if 0
1762     // ARM pseudo code...
1763     if (ConditionPassed())
1764     {
1765         EncodingSpecificOperations();
1766         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1767         if d == 15 then // Can only occur for ARM encoding
1768            ALUWritePC(result); // setflags is always FALSE here
1769         else
1770             R[d] = result;
1771             if setflags then
1772                 APSR.N = result<31>;
1773                 APSR.Z = IsZeroBit(result);
1774                 APSR.C = carry;
1775                 APSR.V = overflow;
1776     }
1777 #endif
1778 
1779     if (ConditionPassed(opcode))
1780     {
1781         bool success = false;
1782         const addr_t ip = ReadCoreReg (12, &success);
1783         if (!success)
1784             return false;
1785         uint32_t imm32;
1786         switch (encoding) {
1787         case eEncodingA1:
1788             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1789             break;
1790         default:
1791             return false;
1792         }
1793         addr_t ip_offset = imm32;
1794         addr_t addr = ip - ip_offset; // the adjusted ip value
1795 
1796         EmulateInstruction::Context context;
1797         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1798         RegisterInfo dwarf_reg;
1799         GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg);
1800         context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
1801 
1802         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
1803             return false;
1804     }
1805     return true;
1806 }
1807 
1808 // Set ip to point to some stack offset.
1809 // SUB (SP minus immediate)
1810 bool
1811 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding)
1812 {
1813 #if 0
1814     // ARM pseudo code...
1815     if (ConditionPassed())
1816     {
1817         EncodingSpecificOperations();
1818         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1819         if d == 15 then // Can only occur for ARM encoding
1820            ALUWritePC(result); // setflags is always FALSE here
1821         else
1822             R[d] = result;
1823             if setflags then
1824                 APSR.N = result<31>;
1825                 APSR.Z = IsZeroBit(result);
1826                 APSR.C = carry;
1827                 APSR.V = overflow;
1828     }
1829 #endif
1830 
1831     if (ConditionPassed(opcode))
1832     {
1833         bool success = false;
1834         const addr_t sp = ReadCoreReg (SP_REG, &success);
1835         if (!success)
1836             return false;
1837         uint32_t imm32;
1838         switch (encoding) {
1839         case eEncodingA1:
1840             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1841             break;
1842         default:
1843             return false;
1844         }
1845         addr_t sp_offset = imm32;
1846         addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1847 
1848         EmulateInstruction::Context context;
1849         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1850         RegisterInfo dwarf_reg;
1851         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
1852         context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
1853 
1854         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
1855             return false;
1856     }
1857     return true;
1858 }
1859 
1860 // This instruction subtracts an immediate value from the SP value, and writes
1861 // the result to the destination register.
1862 //
1863 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage.
1864 bool
1865 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding)
1866 {
1867 #if 0
1868     // ARM pseudo code...
1869     if (ConditionPassed())
1870     {
1871         EncodingSpecificOperations();
1872         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1873         if d == 15 then        // Can only occur for ARM encoding
1874            ALUWritePC(result); // setflags is always FALSE here
1875         else
1876             R[d] = result;
1877             if setflags then
1878                 APSR.N = result<31>;
1879                 APSR.Z = IsZeroBit(result);
1880                 APSR.C = carry;
1881                 APSR.V = overflow;
1882     }
1883 #endif
1884 
1885     bool success = false;
1886     if (ConditionPassed(opcode))
1887     {
1888         const addr_t sp = ReadCoreReg (SP_REG, &success);
1889         if (!success)
1890             return false;
1891 
1892         uint32_t Rd;
1893         bool setflags;
1894         uint32_t imm32;
1895         switch (encoding) {
1896         case eEncodingT1:
1897             Rd = 13;
1898             setflags = false;
1899             imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1900             break;
1901         case eEncodingT2:
1902             Rd = Bits32(opcode, 11, 8);
1903             setflags = BitIsSet(opcode, 20);
1904             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1905             if (Rd == 15 && setflags)
1906                 return EmulateCMPImm(opcode, eEncodingT2);
1907             if (Rd == 15 && !setflags)
1908                 return false;
1909             break;
1910         case eEncodingT3:
1911             Rd = Bits32(opcode, 11, 8);
1912             setflags = false;
1913             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
1914             if (Rd == 15)
1915                 return false;
1916             break;
1917         case eEncodingA1:
1918             Rd = Bits32(opcode, 15, 12);
1919             setflags = BitIsSet(opcode, 20);
1920             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1921 
1922             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1923             if (Rd == 15 && setflags)
1924                 return EmulateSUBSPcLrEtc (opcode, encoding);
1925             break;
1926         default:
1927             return false;
1928         }
1929         AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
1930 
1931         EmulateInstruction::Context context;
1932         if (Rd == 13)
1933         {
1934             uint64_t imm64 = imm32;  // Need to expand it to 64 bits before attempting to negate it, or the wrong
1935                                      // value gets passed down to context.SetImmediateSigned.
1936             context.type = EmulateInstruction::eContextAdjustStackPointer;
1937             context.SetImmediateSigned (-imm64); // the stack pointer offset
1938         }
1939         else
1940         {
1941             context.type = EmulateInstruction::eContextImmediate;
1942             context.SetNoArgs ();
1943         }
1944 
1945         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
1946             return false;
1947     }
1948     return true;
1949 }
1950 
1951 // A store operation to the stack that also updates the SP.
1952 bool
1953 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding)
1954 {
1955 #if 0
1956     // ARM pseudo code...
1957     if (ConditionPassed())
1958     {
1959         EncodingSpecificOperations();
1960         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1961         address = if index then offset_addr else R[n];
1962         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1963         if wback then R[n] = offset_addr;
1964     }
1965 #endif
1966 
1967     bool success = false;
1968     if (ConditionPassed(opcode))
1969     {
1970         const uint32_t addr_byte_size = GetAddressByteSize();
1971         const addr_t sp = ReadCoreReg (SP_REG, &success);
1972         if (!success)
1973             return false;
1974         uint32_t Rt; // the source register
1975         uint32_t imm12;
1976         uint32_t Rn;  // This function assumes Rn is the SP, but we should verify that.
1977 
1978         bool index;
1979         bool add;
1980         bool wback;
1981         switch (encoding) {
1982         case eEncodingA1:
1983             Rt = Bits32(opcode, 15, 12);
1984             imm12 = Bits32(opcode, 11, 0);
1985             Rn = Bits32 (opcode, 19, 16);
1986 
1987             if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
1988                 return false;
1989 
1990             index = BitIsSet (opcode, 24);
1991             add = BitIsSet (opcode, 23);
1992             wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
1993 
1994             if (wback && ((Rn == 15) || (Rn == Rt)))
1995                 return false;
1996             break;
1997         default:
1998             return false;
1999         }
2000         addr_t offset_addr;
2001         if (add)
2002             offset_addr = sp + imm12;
2003         else
2004             offset_addr = sp - imm12;
2005 
2006         addr_t addr;
2007         if (index)
2008             addr = offset_addr;
2009         else
2010             addr = sp;
2011 
2012         EmulateInstruction::Context context;
2013         context.type = EmulateInstruction::eContextPushRegisterOnStack;
2014         RegisterInfo sp_reg;
2015         RegisterInfo dwarf_reg;
2016 
2017         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2018         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
2019         context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
2020         if (Rt != 15)
2021         {
2022             uint32_t reg_value = ReadCoreReg(Rt, &success);
2023             if (!success)
2024                 return false;
2025             if (!MemUWrite (context, addr, reg_value, addr_byte_size))
2026                 return false;
2027         }
2028         else
2029         {
2030             const uint32_t pc = ReadCoreReg(PC_REG, &success);
2031             if (!success)
2032                 return false;
2033             if (!MemUWrite (context, addr, pc, addr_byte_size))
2034                 return false;
2035         }
2036 
2037 
2038         if (wback)
2039         {
2040             context.type = EmulateInstruction::eContextAdjustStackPointer;
2041             context.SetImmediateSigned (addr - sp);
2042             if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr))
2043                 return false;
2044         }
2045     }
2046     return true;
2047 }
2048 
2049 // Vector Push stores multiple extension registers to the stack.
2050 // It also updates SP to point to the start of the stored data.
2051 bool
2052 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding)
2053 {
2054 #if 0
2055     // ARM pseudo code...
2056     if (ConditionPassed())
2057     {
2058         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2059         address = SP - imm32;
2060         SP = SP - imm32;
2061         if single_regs then
2062             for r = 0 to regs-1
2063                 MemA[address,4] = S[d+r]; address = address+4;
2064         else
2065             for r = 0 to regs-1
2066                 // Store as two word-aligned words in the correct order for current endianness.
2067                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
2068                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
2069                 address = address+8;
2070     }
2071 #endif
2072 
2073     bool success = false;
2074     if (ConditionPassed(opcode))
2075     {
2076         const uint32_t addr_byte_size = GetAddressByteSize();
2077         const addr_t sp = ReadCoreReg (SP_REG, &success);
2078         if (!success)
2079             return false;
2080         bool single_regs;
2081         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2082         uint32_t imm32; // stack offset
2083         uint32_t regs;  // number of registers
2084         switch (encoding) {
2085         case eEncodingT1:
2086         case eEncodingA1:
2087             single_regs = false;
2088             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2089             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2090             // If UInt(imm8) is odd, see "FSTMX".
2091             regs = Bits32(opcode, 7, 0) / 2;
2092             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2093             if (regs == 0 || regs > 16 || (d + regs) > 32)
2094                 return false;
2095             break;
2096         case eEncodingT2:
2097         case eEncodingA2:
2098             single_regs = true;
2099             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2100             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2101             regs = Bits32(opcode, 7, 0);
2102             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2103             if (regs == 0 || regs > 16 || (d + regs) > 32)
2104                 return false;
2105             break;
2106         default:
2107             return false;
2108         }
2109         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2110         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2111         addr_t sp_offset = imm32;
2112         addr_t addr = sp - sp_offset;
2113         uint32_t i;
2114 
2115         EmulateInstruction::Context context;
2116         context.type = EmulateInstruction::eContextPushRegisterOnStack;
2117 
2118         RegisterInfo dwarf_reg;
2119         RegisterInfo sp_reg;
2120         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2121         for (i=0; i<regs; ++i)
2122         {
2123             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2124             context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
2125             // uint64_t to accommodate 64-bit registers.
2126             uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success);
2127             if (!success)
2128                 return false;
2129             if (!MemAWrite (context, addr, reg_value, reg_byte_size))
2130                 return false;
2131             addr += reg_byte_size;
2132         }
2133 
2134         context.type = EmulateInstruction::eContextAdjustStackPointer;
2135         context.SetImmediateSigned (-sp_offset);
2136 
2137         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2138             return false;
2139     }
2140     return true;
2141 }
2142 
2143 // Vector Pop loads multiple extension registers from the stack.
2144 // It also updates SP to point just above the loaded data.
2145 bool
2146 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding)
2147 {
2148 #if 0
2149     // ARM pseudo code...
2150     if (ConditionPassed())
2151     {
2152         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2153         address = SP;
2154         SP = SP + imm32;
2155         if single_regs then
2156             for r = 0 to regs-1
2157                 S[d+r] = MemA[address,4]; address = address+4;
2158         else
2159             for r = 0 to regs-1
2160                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2161                 // Combine the word-aligned words in the correct order for current endianness.
2162                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2163     }
2164 #endif
2165 
2166     bool success = false;
2167     if (ConditionPassed(opcode))
2168     {
2169         const uint32_t addr_byte_size = GetAddressByteSize();
2170         const addr_t sp = ReadCoreReg (SP_REG, &success);
2171         if (!success)
2172             return false;
2173         bool single_regs;
2174         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2175         uint32_t imm32; // stack offset
2176         uint32_t regs;  // number of registers
2177         switch (encoding) {
2178         case eEncodingT1:
2179         case eEncodingA1:
2180             single_regs = false;
2181             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2182             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2183             // If UInt(imm8) is odd, see "FLDMX".
2184             regs = Bits32(opcode, 7, 0) / 2;
2185             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2186             if (regs == 0 || regs > 16 || (d + regs) > 32)
2187                 return false;
2188             break;
2189         case eEncodingT2:
2190         case eEncodingA2:
2191             single_regs = true;
2192             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2193             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2194             regs = Bits32(opcode, 7, 0);
2195             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2196             if (regs == 0 || regs > 16 || (d + regs) > 32)
2197                 return false;
2198             break;
2199         default:
2200             return false;
2201         }
2202         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2203         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2204         addr_t sp_offset = imm32;
2205         addr_t addr = sp;
2206         uint32_t i;
2207         uint64_t data; // uint64_t to accommodate 64-bit registers.
2208 
2209         EmulateInstruction::Context context;
2210         context.type = EmulateInstruction::eContextPopRegisterOffStack;
2211 
2212         RegisterInfo dwarf_reg;
2213         RegisterInfo sp_reg;
2214         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2215         for (i=0; i<regs; ++i)
2216         {
2217             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2218             context.SetAddress(addr);
2219             data = MemARead(context, addr, reg_byte_size, 0, &success);
2220             if (!success)
2221                 return false;
2222             if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2223                 return false;
2224             addr += reg_byte_size;
2225         }
2226 
2227         context.type = EmulateInstruction::eContextAdjustStackPointer;
2228         context.SetImmediateSigned (sp_offset);
2229 
2230         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2231             return false;
2232     }
2233     return true;
2234 }
2235 
2236 // SVC (previously SWI)
2237 bool
2238 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding)
2239 {
2240 #if 0
2241     // ARM pseudo code...
2242     if (ConditionPassed())
2243     {
2244         EncodingSpecificOperations();
2245         CallSupervisor();
2246     }
2247 #endif
2248 
2249     bool success = false;
2250 
2251     if (ConditionPassed(opcode))
2252     {
2253         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2254         addr_t lr; // next instruction address
2255         if (!success)
2256             return false;
2257         uint32_t imm32; // the immediate constant
2258         uint32_t mode;  // ARM or Thumb mode
2259         switch (encoding) {
2260         case eEncodingT1:
2261             lr = (pc + 2) | 1u; // return address
2262             imm32 = Bits32(opcode, 7, 0);
2263             mode = eModeThumb;
2264             break;
2265         case eEncodingA1:
2266             lr = pc + 4; // return address
2267             imm32 = Bits32(opcode, 23, 0);
2268             mode = eModeARM;
2269             break;
2270         default:
2271             return false;
2272         }
2273 
2274         EmulateInstruction::Context context;
2275         context.type = EmulateInstruction::eContextSupervisorCall;
2276         context.SetISAAndImmediate (mode, imm32);
2277         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
2278             return false;
2279     }
2280     return true;
2281 }
2282 
2283 // If Then makes up to four following instructions (the IT block) conditional.
2284 bool
2285 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding)
2286 {
2287 #if 0
2288     // ARM pseudo code...
2289     EncodingSpecificOperations();
2290     ITSTATE.IT<7:0> = firstcond:mask;
2291 #endif
2292 
2293     m_it_session.InitIT(Bits32(opcode, 7, 0));
2294     return true;
2295 }
2296 
2297 bool
2298 EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding)
2299 {
2300     // NOP, nothing to do...
2301     return true;
2302 }
2303 
2304 // Branch causes a branch to a target address.
2305 bool
2306 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding)
2307 {
2308 #if 0
2309     // ARM pseudo code...
2310     if (ConditionPassed())
2311     {
2312         EncodingSpecificOperations();
2313         BranchWritePC(PC + imm32);
2314     }
2315 #endif
2316 
2317     bool success = false;
2318 
2319     if (ConditionPassed(opcode))
2320     {
2321         EmulateInstruction::Context context;
2322         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2323         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2324         if (!success)
2325             return false;
2326         addr_t target; // target address
2327         int32_t imm32; // PC-relative offset
2328         switch (encoding) {
2329         case eEncodingT1:
2330             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2331             imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2332             target = pc + imm32;
2333             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2334             break;
2335         case eEncodingT2:
2336             imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1);
2337             target = pc + imm32;
2338             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2339             break;
2340         case eEncodingT3:
2341             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2342             {
2343             if (Bits32(opcode, 25, 23) == 7)
2344                 return false; // See Branches and miscellaneous control on page A6-235.
2345 
2346             uint32_t S = Bit32(opcode, 26);
2347             uint32_t imm6 = Bits32(opcode, 21, 16);
2348             uint32_t J1 = Bit32(opcode, 13);
2349             uint32_t J2 = Bit32(opcode, 11);
2350             uint32_t imm11 = Bits32(opcode, 10, 0);
2351             uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2352             imm32 = llvm::SignExtend32<21>(imm21);
2353             target = pc + imm32;
2354             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2355             break;
2356             }
2357         case eEncodingT4:
2358             {
2359             uint32_t S = Bit32(opcode, 26);
2360             uint32_t imm10 = Bits32(opcode, 25, 16);
2361             uint32_t J1 = Bit32(opcode, 13);
2362             uint32_t J2 = Bit32(opcode, 11);
2363             uint32_t imm11 = Bits32(opcode, 10, 0);
2364             uint32_t I1 = !(J1 ^ S);
2365             uint32_t I2 = !(J2 ^ S);
2366             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2367             imm32 = llvm::SignExtend32<25>(imm25);
2368             target = pc + imm32;
2369             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2370             break;
2371             }
2372         case eEncodingA1:
2373             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2374             target = pc + imm32;
2375             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
2376             break;
2377         default:
2378             return false;
2379         }
2380         if (!BranchWritePC(context, target))
2381             return false;
2382     }
2383     return true;
2384 }
2385 
2386 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
2387 // zero and conditionally branch forward a constant value.  They do not affect the condition flags.
2388 // CBNZ, CBZ
2389 bool
2390 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding)
2391 {
2392 #if 0
2393     // ARM pseudo code...
2394     EncodingSpecificOperations();
2395     if nonzero ^ IsZero(R[n]) then
2396         BranchWritePC(PC + imm32);
2397 #endif
2398 
2399     bool success = false;
2400 
2401     // Read the register value from the operand register Rn.
2402     uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2403     if (!success)
2404         return false;
2405 
2406     EmulateInstruction::Context context;
2407     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2408     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2409     if (!success)
2410         return false;
2411 
2412     addr_t target;  // target address
2413     uint32_t imm32; // PC-relative offset to branch forward
2414     bool nonzero;
2415     switch (encoding) {
2416     case eEncodingT1:
2417         imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2418         nonzero = BitIsSet(opcode, 11);
2419         target = pc + imm32;
2420         context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2421         break;
2422     default:
2423         return false;
2424     }
2425     if (m_ignore_conditions || (nonzero ^ (reg_val == 0)))
2426         if (!BranchWritePC(context, target))
2427             return false;
2428 
2429     return true;
2430 }
2431 
2432 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
2433 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2434 // The branch length is twice the value of the byte returned from the table.
2435 //
2436 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
2437 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2438 // The branch length is twice the value of the halfword returned from the table.
2439 // TBB, TBH
2440 bool
2441 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding)
2442 {
2443 #if 0
2444     // ARM pseudo code...
2445     EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2446     if is_tbh then
2447         halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2448     else
2449         halfwords = UInt(MemU[R[n]+R[m], 1]);
2450     BranchWritePC(PC + 2*halfwords);
2451 #endif
2452 
2453     bool success = false;
2454 
2455     if (ConditionPassed(opcode))
2456     {
2457         uint32_t Rn;     // the base register which contains the address of the table of branch lengths
2458         uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
2459         bool is_tbh;     // true if table branch halfword
2460         switch (encoding) {
2461         case eEncodingT1:
2462             Rn = Bits32(opcode, 19, 16);
2463             Rm = Bits32(opcode, 3, 0);
2464             is_tbh = BitIsSet(opcode, 4);
2465             if (Rn == 13 || BadReg(Rm))
2466                 return false;
2467             if (InITBlock() && !LastInITBlock())
2468                 return false;
2469             break;
2470         default:
2471             return false;
2472         }
2473 
2474         // Read the address of the table from the operand register Rn.
2475         // The PC can be used, in which case the table immediately follows this instruction.
2476         uint32_t base = ReadCoreReg(Rn, &success);
2477         if (!success)
2478             return false;
2479 
2480         // the table index
2481         uint32_t index = ReadCoreReg(Rm, &success);
2482         if (!success)
2483             return false;
2484 
2485         // the offsetted table address
2486         addr_t addr = base + (is_tbh ? index*2 : index);
2487 
2488         // PC-relative offset to branch forward
2489         EmulateInstruction::Context context;
2490         context.type = EmulateInstruction::eContextTableBranchReadMemory;
2491         uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2492         if (!success)
2493             return false;
2494 
2495         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2496         if (!success)
2497             return false;
2498 
2499         // target address
2500         addr_t target = pc + offset;
2501         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2502         context.SetISAAndImmediateSigned (eModeThumb, 4 + offset);
2503 
2504         if (!BranchWritePC(context, target))
2505             return false;
2506     }
2507 
2508     return true;
2509 }
2510 
2511 // This instruction adds an immediate value to a register value, and writes the result to the destination register.
2512 // It can optionally update the condition flags based on the result.
2513 bool
2514 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding)
2515 {
2516 #if 0
2517     if ConditionPassed() then
2518         EncodingSpecificOperations();
2519         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2520         R[d] = result;
2521         if setflags then
2522             APSR.N = result<31>;
2523             APSR.Z = IsZeroBit(result);
2524             APSR.C = carry;
2525             APSR.V = overflow;
2526 #endif
2527 
2528     bool success = false;
2529 
2530     if (ConditionPassed(opcode))
2531     {
2532         uint32_t d;
2533         uint32_t n;
2534         bool setflags;
2535         uint32_t imm32;
2536         uint32_t carry_out;
2537 
2538         //EncodingSpecificOperations();
2539         switch (encoding)
2540         {
2541             case eEncodingT1:
2542                 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32);
2543                 d = Bits32 (opcode, 2, 0);
2544                 n = Bits32 (opcode, 5, 3);
2545                 setflags = !InITBlock();
2546                 imm32 = Bits32 (opcode, 8,6);
2547 
2548                 break;
2549 
2550             case eEncodingT2:
2551                 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32);
2552                 d = Bits32 (opcode, 10, 8);
2553                 n = Bits32 (opcode, 10, 8);
2554                 setflags = !InITBlock();
2555                 imm32 = Bits32 (opcode, 7, 0);
2556 
2557                 break;
2558 
2559             case eEncodingT3:
2560                 // if Rd == '1111' && S == '1' then SEE CMN (immediate);
2561                 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8);
2562                 d = Bits32 (opcode, 11, 8);
2563                 n = Bits32 (opcode, 19, 16);
2564                 setflags = BitIsSet (opcode, 20);
2565                 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out);
2566 
2567                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2568                 if (n == 13)
2569                     return EmulateADDSPImm(opcode, eEncodingT3);
2570 
2571                 // if BadReg(d) || n == 15 then UNPREDICTABLE;
2572                 if (BadReg (d) || (n == 15))
2573                     return false;
2574 
2575                 break;
2576 
2577             case eEncodingT4:
2578             {
2579                 // if Rn == '1111' then SEE ADR;
2580                 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
2581                 d = Bits32 (opcode, 11, 8);
2582                 n = Bits32 (opcode, 19, 16);
2583                 setflags = false;
2584                 uint32_t i = Bit32 (opcode, 26);
2585                 uint32_t imm3 = Bits32 (opcode, 14, 12);
2586                 uint32_t imm8 = Bits32 (opcode, 7, 0);
2587                 imm32 = (i << 11) | (imm3 << 8) | imm8;
2588 
2589                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2590                 if (n == 13)
2591                     return EmulateADDSPImm(opcode, eEncodingT4);
2592 
2593                 // if BadReg(d) then UNPREDICTABLE;
2594                 if (BadReg (d))
2595                     return false;
2596 
2597                 break;
2598             }
2599 
2600             default:
2601                 return false;
2602         }
2603 
2604         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2605         if (!success)
2606             return false;
2607 
2608         //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2609         AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
2610 
2611         RegisterInfo reg_n;
2612         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
2613 
2614         EmulateInstruction::Context context;
2615         context.type = eContextArithmetic;
2616         context.SetRegisterPlusOffset (reg_n, imm32);
2617 
2618         //R[d] = result;
2619         //if setflags then
2620             //APSR.N = result<31>;
2621             //APSR.Z = IsZeroBit(result);
2622             //APSR.C = carry;
2623             //APSR.V = overflow;
2624         if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
2625             return false;
2626 
2627     }
2628     return true;
2629 }
2630 
2631 // This instruction adds an immediate value to a register value, and writes the result to the destination
2632 // register.  It can optionally update the condition flags based on the result.
2633 bool
2634 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding)
2635 {
2636 #if 0
2637     // ARM pseudo code...
2638     if ConditionPassed() then
2639         EncodingSpecificOperations();
2640         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2641         if d == 15 then
2642             ALUWritePC(result); // setflags is always FALSE here
2643         else
2644             R[d] = result;
2645             if setflags then
2646                 APSR.N = result<31>;
2647                 APSR.Z = IsZeroBit(result);
2648                 APSR.C = carry;
2649                 APSR.V = overflow;
2650 #endif
2651 
2652     bool success = false;
2653 
2654     if (ConditionPassed(opcode))
2655     {
2656         uint32_t Rd, Rn;
2657         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
2658         bool setflags;
2659         switch (encoding)
2660         {
2661         case eEncodingA1:
2662             Rd = Bits32(opcode, 15, 12);
2663             Rn = Bits32(opcode, 19, 16);
2664             setflags = BitIsSet(opcode, 20);
2665             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2666             break;
2667         default:
2668             return false;
2669         }
2670 
2671         // Read the first operand.
2672         uint32_t val1 = ReadCoreReg(Rn, &success);
2673         if (!success)
2674             return false;
2675 
2676         AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
2677 
2678         EmulateInstruction::Context context;
2679         if (Rd == 13)
2680             context.type = EmulateInstruction::eContextAdjustStackPointer;
2681         else if (Rd == GetFramePointerRegisterNumber())
2682             context.type = EmulateInstruction::eContextSetFramePointer;
2683         else
2684             context.type = EmulateInstruction::eContextRegisterPlusOffset;
2685 
2686         RegisterInfo dwarf_reg;
2687         GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
2688         context.SetRegisterPlusOffset (dwarf_reg, imm32);
2689 
2690         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2691             return false;
2692     }
2693     return true;
2694 }
2695 
2696 // This instruction adds a register value and an optionally-shifted register value, and writes the result
2697 // to the destination register. It can optionally update the condition flags based on the result.
2698 bool
2699 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding)
2700 {
2701 #if 0
2702     // ARM pseudo code...
2703     if ConditionPassed() then
2704         EncodingSpecificOperations();
2705         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2706         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2707         if d == 15 then
2708             ALUWritePC(result); // setflags is always FALSE here
2709         else
2710             R[d] = result;
2711             if setflags then
2712                 APSR.N = result<31>;
2713                 APSR.Z = IsZeroBit(result);
2714                 APSR.C = carry;
2715                 APSR.V = overflow;
2716 #endif
2717 
2718     bool success = false;
2719 
2720     if (ConditionPassed(opcode))
2721     {
2722         uint32_t Rd, Rn, Rm;
2723         ARM_ShifterType shift_t;
2724         uint32_t shift_n; // the shift applied to the value read from Rm
2725         bool setflags;
2726         switch (encoding)
2727         {
2728         case eEncodingT1:
2729             Rd = Bits32(opcode, 2, 0);
2730             Rn = Bits32(opcode, 5, 3);
2731             Rm = Bits32(opcode, 8, 6);
2732             setflags = !InITBlock();
2733             shift_t = SRType_LSL;
2734             shift_n = 0;
2735             break;
2736         case eEncodingT2:
2737             Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2738             Rm = Bits32(opcode, 6, 3);
2739             setflags = false;
2740             shift_t = SRType_LSL;
2741             shift_n = 0;
2742             if (Rn == 15 && Rm == 15)
2743                 return false;
2744             if (Rd == 15 && InITBlock() && !LastInITBlock())
2745                 return false;
2746             break;
2747         case eEncodingA1:
2748             Rd = Bits32(opcode, 15, 12);
2749             Rn = Bits32(opcode, 19, 16);
2750             Rm = Bits32(opcode, 3, 0);
2751             setflags = BitIsSet(opcode, 20);
2752             shift_n = DecodeImmShiftARM(opcode, shift_t);
2753             break;
2754         default:
2755             return false;
2756         }
2757 
2758         // Read the first operand.
2759         uint32_t val1 = ReadCoreReg(Rn, &success);
2760         if (!success)
2761             return false;
2762 
2763         // Read the second operand.
2764         uint32_t val2 = ReadCoreReg(Rm, &success);
2765         if (!success)
2766             return false;
2767 
2768         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2769         if (!success)
2770             return false;
2771         AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2772 
2773         EmulateInstruction::Context context;
2774         context.type = eContextArithmetic;
2775         RegisterInfo op1_reg;
2776         RegisterInfo op2_reg;
2777         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
2778         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
2779         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
2780 
2781         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2782             return false;
2783     }
2784     return true;
2785 }
2786 
2787 // Compare Negative (immediate) adds a register value and an immediate value.
2788 // It updates the condition flags based on the result, and discards the result.
2789 bool
2790 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding)
2791 {
2792 #if 0
2793     // ARM pseudo code...
2794     if ConditionPassed() then
2795         EncodingSpecificOperations();
2796         (result, carry, overflow) = AddWithCarry(R[n], imm32, '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 imm32; // the immediate value to be compared with
2807     switch (encoding) {
2808     case eEncodingT1:
2809         Rn = Bits32(opcode, 19, 16);
2810         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2811         if (Rn == 15)
2812             return false;
2813         break;
2814     case eEncodingA1:
2815         Rn = Bits32(opcode, 19, 16);
2816         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2817         break;
2818     default:
2819         return false;
2820     }
2821     // Read the register value from the operand register Rn.
2822     uint32_t reg_val = ReadCoreReg(Rn, &success);
2823     if (!success)
2824         return false;
2825 
2826     AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
2827 
2828     EmulateInstruction::Context context;
2829     context.type = EmulateInstruction::eContextImmediate;
2830     context.SetNoArgs ();
2831     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2832         return false;
2833 
2834     return true;
2835 }
2836 
2837 // Compare Negative (register) adds a register value and an optionally-shifted register value.
2838 // It updates the condition flags based on the result, and discards the result.
2839 bool
2840 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding)
2841 {
2842 #if 0
2843     // ARM pseudo code...
2844     if ConditionPassed() then
2845         EncodingSpecificOperations();
2846         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2847         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2848         APSR.N = result<31>;
2849         APSR.Z = IsZeroBit(result);
2850         APSR.C = carry;
2851         APSR.V = overflow;
2852 #endif
2853 
2854     bool success = false;
2855 
2856     uint32_t Rn; // the first operand
2857     uint32_t Rm; // the second operand
2858     ARM_ShifterType shift_t;
2859     uint32_t shift_n; // the shift applied to the value read from Rm
2860     switch (encoding) {
2861     case eEncodingT1:
2862         Rn = Bits32(opcode, 2, 0);
2863         Rm = Bits32(opcode, 5, 3);
2864         shift_t = SRType_LSL;
2865         shift_n = 0;
2866         break;
2867     case eEncodingT2:
2868         Rn = Bits32(opcode, 19, 16);
2869         Rm = Bits32(opcode, 3, 0);
2870         shift_n = DecodeImmShiftThumb(opcode, shift_t);
2871         // if n == 15 || BadReg(m) then UNPREDICTABLE;
2872         if (Rn == 15 || BadReg(Rm))
2873             return false;
2874         break;
2875     case eEncodingA1:
2876         Rn = Bits32(opcode, 19, 16);
2877         Rm = Bits32(opcode, 3, 0);
2878         shift_n = DecodeImmShiftARM(opcode, shift_t);
2879         break;
2880     default:
2881         return false;
2882     }
2883     // Read the register value from register Rn.
2884     uint32_t val1 = ReadCoreReg(Rn, &success);
2885     if (!success)
2886         return false;
2887 
2888     // Read the register value from register Rm.
2889     uint32_t val2 = ReadCoreReg(Rm, &success);
2890     if (!success)
2891         return false;
2892 
2893     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2894     if (!success)
2895         return false;
2896     AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2897 
2898     EmulateInstruction::Context context;
2899     context.type = EmulateInstruction::eContextImmediate;
2900     context.SetNoArgs();
2901     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2902         return false;
2903 
2904     return true;
2905 }
2906 
2907 // Compare (immediate) subtracts an immediate value from a register value.
2908 // It updates the condition flags based on the result, and discards the result.
2909 bool
2910 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding)
2911 {
2912 #if 0
2913     // ARM pseudo code...
2914     if ConditionPassed() then
2915         EncodingSpecificOperations();
2916         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2917         APSR.N = result<31>;
2918         APSR.Z = IsZeroBit(result);
2919         APSR.C = carry;
2920         APSR.V = overflow;
2921 #endif
2922 
2923     bool success = false;
2924 
2925     uint32_t Rn; // the first operand
2926     uint32_t imm32; // the immediate value to be compared with
2927     switch (encoding) {
2928     case eEncodingT1:
2929         Rn = Bits32(opcode, 10, 8);
2930         imm32 = Bits32(opcode, 7, 0);
2931         break;
2932     case eEncodingT2:
2933         Rn = Bits32(opcode, 19, 16);
2934         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2935         if (Rn == 15)
2936             return false;
2937         break;
2938     case eEncodingA1:
2939         Rn = Bits32(opcode, 19, 16);
2940         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2941         break;
2942     default:
2943         return false;
2944     }
2945     // Read the register value from the operand register Rn.
2946     uint32_t reg_val = ReadCoreReg(Rn, &success);
2947     if (!success)
2948         return false;
2949 
2950     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
2951 
2952     EmulateInstruction::Context context;
2953     context.type = EmulateInstruction::eContextImmediate;
2954     context.SetNoArgs ();
2955     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2956         return false;
2957 
2958     return true;
2959 }
2960 
2961 // Compare (register) subtracts an optionally-shifted register value from a register value.
2962 // It updates the condition flags based on the result, and discards the result.
2963 bool
2964 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding)
2965 {
2966 #if 0
2967     // ARM pseudo code...
2968     if ConditionPassed() then
2969         EncodingSpecificOperations();
2970         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2971         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2972         APSR.N = result<31>;
2973         APSR.Z = IsZeroBit(result);
2974         APSR.C = carry;
2975         APSR.V = overflow;
2976 #endif
2977 
2978     bool success = false;
2979 
2980     uint32_t Rn; // the first operand
2981     uint32_t Rm; // the second operand
2982     ARM_ShifterType shift_t;
2983     uint32_t shift_n; // the shift applied to the value read from Rm
2984     switch (encoding) {
2985     case eEncodingT1:
2986         Rn = Bits32(opcode, 2, 0);
2987         Rm = Bits32(opcode, 5, 3);
2988         shift_t = SRType_LSL;
2989         shift_n = 0;
2990         break;
2991     case eEncodingT2:
2992         Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2993         Rm = Bits32(opcode, 6, 3);
2994         shift_t = SRType_LSL;
2995         shift_n = 0;
2996         if (Rn < 8 && Rm < 8)
2997             return false;
2998         if (Rn == 15 || Rm == 15)
2999             return false;
3000         break;
3001     case eEncodingT3:
3002         Rn = Bits32(opcode, 19, 16);
3003         Rm = Bits32(opcode, 3, 0);
3004         shift_n = DecodeImmShiftThumb(opcode, shift_t);
3005         if (Rn == 15 || BadReg(Rm))
3006             return false;
3007         break;
3008     case eEncodingA1:
3009         Rn = Bits32(opcode, 19, 16);
3010         Rm = Bits32(opcode, 3, 0);
3011         shift_n = DecodeImmShiftARM(opcode, shift_t);
3012         break;
3013     default:
3014         return false;
3015     }
3016     // Read the register value from register Rn.
3017     uint32_t val1 = ReadCoreReg(Rn, &success);
3018     if (!success)
3019         return false;
3020 
3021     // Read the register value from register Rm.
3022     uint32_t val2 = ReadCoreReg(Rm, &success);
3023     if (!success)
3024         return false;
3025 
3026     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3027     if (!success)
3028         return false;
3029     AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
3030 
3031     EmulateInstruction::Context context;
3032     context.type = EmulateInstruction::eContextImmediate;
3033     context.SetNoArgs();
3034     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
3035         return false;
3036 
3037     return true;
3038 }
3039 
3040 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
3041 // shifting in copies of its sign bit, and writes the result to the destination register.  It can
3042 // optionally update the condition flags based on the result.
3043 bool
3044 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding)
3045 {
3046 #if 0
3047     // ARM pseudo code...
3048     if ConditionPassed() then
3049         EncodingSpecificOperations();
3050         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3051         if d == 15 then         // Can only occur for ARM encoding
3052             ALUWritePC(result); // setflags is always FALSE here
3053         else
3054             R[d] = result;
3055             if setflags then
3056                 APSR.N = result<31>;
3057                 APSR.Z = IsZeroBit(result);
3058                 APSR.C = carry;
3059                 // APSR.V unchanged
3060 #endif
3061 
3062     return EmulateShiftImm (opcode, encoding, SRType_ASR);
3063 }
3064 
3065 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
3066 // shifting in copies of its sign bit, and writes the result to the destination register.
3067 // The variable number of bits is read from the bottom byte of a register. It can optionally update
3068 // the condition flags based on the result.
3069 bool
3070 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding)
3071 {
3072 #if 0
3073     // ARM pseudo code...
3074     if ConditionPassed() then
3075         EncodingSpecificOperations();
3076         shift_n = UInt(R[m]<7:0>);
3077         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3078         R[d] = result;
3079         if setflags then
3080             APSR.N = result<31>;
3081             APSR.Z = IsZeroBit(result);
3082             APSR.C = carry;
3083             // APSR.V unchanged
3084 #endif
3085 
3086     return EmulateShiftReg (opcode, encoding, SRType_ASR);
3087 }
3088 
3089 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
3090 // shifting in zeros, and writes the result to the destination register.  It can optionally
3091 // update the condition flags based on the result.
3092 bool
3093 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding)
3094 {
3095 #if 0
3096     // ARM pseudo code...
3097     if ConditionPassed() then
3098         EncodingSpecificOperations();
3099         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3100         if d == 15 then         // Can only occur for ARM encoding
3101             ALUWritePC(result); // setflags is always FALSE here
3102         else
3103             R[d] = result;
3104             if setflags then
3105                 APSR.N = result<31>;
3106                 APSR.Z = IsZeroBit(result);
3107                 APSR.C = carry;
3108                 // APSR.V unchanged
3109 #endif
3110 
3111     return EmulateShiftImm (opcode, encoding, SRType_LSL);
3112 }
3113 
3114 // Logical Shift Left (register) shifts a register value left by a variable number of bits,
3115 // shifting in zeros, and writes the result to the destination register.  The variable number
3116 // of bits is read from the bottom byte of a register. It can optionally update the condition
3117 // flags based on the result.
3118 bool
3119 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding)
3120 {
3121 #if 0
3122     // ARM pseudo code...
3123     if ConditionPassed() then
3124         EncodingSpecificOperations();
3125         shift_n = UInt(R[m]<7:0>);
3126         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3127         R[d] = result;
3128         if setflags then
3129             APSR.N = result<31>;
3130             APSR.Z = IsZeroBit(result);
3131             APSR.C = carry;
3132             // APSR.V unchanged
3133 #endif
3134 
3135     return EmulateShiftReg (opcode, encoding, SRType_LSL);
3136 }
3137 
3138 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
3139 // shifting in zeros, and writes the result to the destination register.  It can optionally
3140 // update the condition flags based on the result.
3141 bool
3142 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding)
3143 {
3144 #if 0
3145     // ARM pseudo code...
3146     if ConditionPassed() then
3147         EncodingSpecificOperations();
3148         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3149         if d == 15 then         // Can only occur for ARM encoding
3150             ALUWritePC(result); // setflags is always FALSE here
3151         else
3152             R[d] = result;
3153             if setflags then
3154                 APSR.N = result<31>;
3155                 APSR.Z = IsZeroBit(result);
3156                 APSR.C = carry;
3157                 // APSR.V unchanged
3158 #endif
3159 
3160     return EmulateShiftImm (opcode, encoding, SRType_LSR);
3161 }
3162 
3163 // Logical Shift Right (register) shifts a register value right by a variable number of bits,
3164 // shifting in zeros, and writes the result to the destination register.  The variable number
3165 // of bits is read from the bottom byte of a register. It can optionally update the condition
3166 // flags based on the result.
3167 bool
3168 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding)
3169 {
3170 #if 0
3171     // ARM pseudo code...
3172     if ConditionPassed() then
3173         EncodingSpecificOperations();
3174         shift_n = UInt(R[m]<7:0>);
3175         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3176         R[d] = result;
3177         if setflags then
3178             APSR.N = result<31>;
3179             APSR.Z = IsZeroBit(result);
3180             APSR.C = carry;
3181             // APSR.V unchanged
3182 #endif
3183 
3184     return EmulateShiftReg (opcode, encoding, SRType_LSR);
3185 }
3186 
3187 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
3188 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3189 // It can optionally update the condition flags based on the result.
3190 bool
3191 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding)
3192 {
3193 #if 0
3194     // ARM pseudo code...
3195     if ConditionPassed() then
3196         EncodingSpecificOperations();
3197         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3198         if d == 15 then         // Can only occur for ARM encoding
3199             ALUWritePC(result); // setflags is always FALSE here
3200         else
3201             R[d] = result;
3202             if setflags then
3203                 APSR.N = result<31>;
3204                 APSR.Z = IsZeroBit(result);
3205                 APSR.C = carry;
3206                 // APSR.V unchanged
3207 #endif
3208 
3209     return EmulateShiftImm (opcode, encoding, SRType_ROR);
3210 }
3211 
3212 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
3213 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3214 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
3215 // flags based on the result.
3216 bool
3217 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding)
3218 {
3219 #if 0
3220     // ARM pseudo code...
3221     if ConditionPassed() then
3222         EncodingSpecificOperations();
3223         shift_n = UInt(R[m]<7:0>);
3224         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3225         R[d] = result;
3226         if setflags then
3227             APSR.N = result<31>;
3228             APSR.Z = IsZeroBit(result);
3229             APSR.C = carry;
3230             // APSR.V unchanged
3231 #endif
3232 
3233     return EmulateShiftReg (opcode, encoding, SRType_ROR);
3234 }
3235 
3236 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
3237 // with the carry flag shifted into bit [31].
3238 //
3239 // RRX can optionally update the condition flags based on the result.
3240 // In that case, bit [0] is shifted into the carry flag.
3241 bool
3242 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding)
3243 {
3244 #if 0
3245     // ARM pseudo code...
3246     if ConditionPassed() then
3247         EncodingSpecificOperations();
3248         (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3249         if d == 15 then         // Can only occur for ARM encoding
3250             ALUWritePC(result); // setflags is always FALSE here
3251         else
3252             R[d] = result;
3253             if setflags then
3254                 APSR.N = result<31>;
3255                 APSR.Z = IsZeroBit(result);
3256                 APSR.C = carry;
3257                 // APSR.V unchanged
3258 #endif
3259 
3260     return EmulateShiftImm (opcode, encoding, SRType_RRX);
3261 }
3262 
3263 bool
3264 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3265 {
3266 //    assert(shift_type == SRType_ASR
3267 //           || shift_type == SRType_LSL
3268 //           || shift_type == SRType_LSR
3269 //           || shift_type == SRType_ROR
3270 //           || shift_type == SRType_RRX);
3271 
3272     bool success = false;
3273 
3274     if (ConditionPassed(opcode))
3275     {
3276         uint32_t Rd;    // the destination register
3277         uint32_t Rm;    // the first operand register
3278         uint32_t imm5;  // encoding for the shift amount
3279         uint32_t carry; // the carry bit after the shift operation
3280         bool setflags;
3281 
3282         // Special case handling!
3283         // A8.6.139 ROR (immediate) -- Encoding T1
3284         ARMEncoding use_encoding = encoding;
3285         if (shift_type == SRType_ROR && use_encoding == eEncodingT1)
3286         {
3287             // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
3288             // have the same decoding of bit fields as the other Thumb2 shift operations.
3289             use_encoding = eEncodingT2;
3290         }
3291 
3292         switch (use_encoding) {
3293         case eEncodingT1:
3294             // Due to the above special case handling!
3295             if (shift_type == SRType_ROR)
3296                 return false;
3297 
3298             Rd = Bits32(opcode, 2, 0);
3299             Rm = Bits32(opcode, 5, 3);
3300             setflags = !InITBlock();
3301             imm5 = Bits32(opcode, 10, 6);
3302             break;
3303         case eEncodingT2:
3304             // A8.6.141 RRX
3305             // There's no imm form of RRX instructions.
3306             if (shift_type == SRType_RRX)
3307                 return false;
3308 
3309             Rd = Bits32(opcode, 11, 8);
3310             Rm = Bits32(opcode, 3, 0);
3311             setflags = BitIsSet(opcode, 20);
3312             imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3313             if (BadReg(Rd) || BadReg(Rm))
3314                 return false;
3315             break;
3316         case eEncodingA1:
3317             Rd = Bits32(opcode, 15, 12);
3318             Rm = Bits32(opcode, 3, 0);
3319             setflags = BitIsSet(opcode, 20);
3320             imm5 = Bits32(opcode, 11, 7);
3321             break;
3322         default:
3323             return false;
3324         }
3325 
3326         // A8.6.139 ROR (immediate)
3327         if (shift_type == SRType_ROR && imm5 == 0)
3328             shift_type = SRType_RRX;
3329 
3330         // Get the first operand.
3331         uint32_t value = ReadCoreReg (Rm, &success);
3332         if (!success)
3333             return false;
3334 
3335         // Decode the shift amount if not RRX.
3336         uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3337 
3338         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3339         if (!success)
3340             return false;
3341 
3342         // The context specifies that an immediate is to be moved into Rd.
3343         EmulateInstruction::Context context;
3344         context.type = EmulateInstruction::eContextImmediate;
3345         context.SetNoArgs ();
3346 
3347         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3348             return false;
3349     }
3350     return true;
3351 }
3352 
3353 bool
3354 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3355 {
3356     // assert(shift_type == SRType_ASR
3357     //        || shift_type == SRType_LSL
3358     //        || shift_type == SRType_LSR
3359     //        || shift_type == SRType_ROR);
3360 
3361     bool success = false;
3362 
3363     if (ConditionPassed(opcode))
3364     {
3365         uint32_t Rd;    // the destination register
3366         uint32_t Rn;    // the first operand register
3367         uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
3368         uint32_t carry; // the carry bit after the shift operation
3369         bool setflags;
3370         switch (encoding) {
3371         case eEncodingT1:
3372             Rd = Bits32(opcode, 2, 0);
3373             Rn = Rd;
3374             Rm = Bits32(opcode, 5, 3);
3375             setflags = !InITBlock();
3376             break;
3377         case eEncodingT2:
3378             Rd = Bits32(opcode, 11, 8);
3379             Rn = Bits32(opcode, 19, 16);
3380             Rm = Bits32(opcode, 3, 0);
3381             setflags = BitIsSet(opcode, 20);
3382             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3383                 return false;
3384             break;
3385         case eEncodingA1:
3386             Rd = Bits32(opcode, 15, 12);
3387             Rn = Bits32(opcode, 3, 0);
3388             Rm = Bits32(opcode, 11, 8);
3389             setflags = BitIsSet(opcode, 20);
3390             if (Rd == 15 || Rn == 15 || Rm == 15)
3391                 return false;
3392             break;
3393         default:
3394             return false;
3395         }
3396 
3397         // Get the first operand.
3398         uint32_t value = ReadCoreReg (Rn, &success);
3399         if (!success)
3400             return false;
3401         // Get the Rm register content.
3402         uint32_t val = ReadCoreReg (Rm, &success);
3403         if (!success)
3404             return false;
3405 
3406         // Get the shift amount.
3407         uint32_t amt = Bits32(val, 7, 0);
3408 
3409         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3410         if (!success)
3411             return false;
3412 
3413         // The context specifies that an immediate is to be moved into Rd.
3414         EmulateInstruction::Context context;
3415         context.type = EmulateInstruction::eContextImmediate;
3416         context.SetNoArgs ();
3417 
3418         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3419             return false;
3420     }
3421     return true;
3422 }
3423 
3424 // LDM loads multiple registers from consecutive memory locations, using an
3425 // address from a base register.  Optionally the address just above the highest of those locations
3426 // can be written back to the base register.
3427 bool
3428 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding)
3429 {
3430 #if 0
3431     // ARM pseudo code...
3432     if ConditionPassed()
3433         EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3434         address = R[n];
3435 
3436         for i = 0 to 14
3437             if registers<i> == '1' then
3438                 R[i] = MemA[address, 4]; address = address + 4;
3439         if registers<15> == '1' then
3440             LoadWritePC (MemA[address, 4]);
3441 
3442         if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3443         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3444 
3445 #endif
3446 
3447     bool success = false;
3448     if (ConditionPassed(opcode))
3449     {
3450         uint32_t n;
3451         uint32_t registers = 0;
3452         bool wback;
3453         const uint32_t addr_byte_size = GetAddressByteSize();
3454         switch (encoding)
3455         {
3456             case eEncodingT1:
3457                 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0');
3458                 n = Bits32 (opcode, 10, 8);
3459                 registers = Bits32 (opcode, 7, 0);
3460                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3461                 wback = BitIsClear (registers, n);
3462                 // if BitCount(registers) < 1 then UNPREDICTABLE;
3463                 if (BitCount(registers) < 1)
3464                     return false;
3465                 break;
3466             case eEncodingT2:
3467                 // if W == '1' && Rn == '1101' then SEE POP;
3468                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3469                 n = Bits32 (opcode, 19, 16);
3470                 registers = Bits32 (opcode, 15, 0);
3471                 registers = registers & 0xdfff; // Make sure bit 13 is zero.
3472                 wback = BitIsSet (opcode, 21);
3473 
3474                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3475                 if ((n == 15)
3476                     || (BitCount (registers) < 2)
3477                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3478                     return false;
3479 
3480                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3481                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3482                     return false;
3483 
3484                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3485                 if (wback
3486                     && BitIsSet (registers, n))
3487                     return false;
3488                 break;
3489 
3490             case eEncodingA1:
3491                 n = Bits32 (opcode, 19, 16);
3492                 registers = Bits32 (opcode, 15, 0);
3493                 wback = BitIsSet (opcode, 21);
3494                 if ((n == 15)
3495                     || (BitCount (registers) < 1))
3496                     return false;
3497                 break;
3498             default:
3499                 return false;
3500         }
3501 
3502         int32_t offset = 0;
3503         const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3504         if (!success)
3505             return false;
3506 
3507         EmulateInstruction::Context context;
3508         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3509         RegisterInfo dwarf_reg;
3510         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3511         context.SetRegisterPlusOffset (dwarf_reg, offset);
3512 
3513         for (int i = 0; i < 14; ++i)
3514         {
3515             if (BitIsSet (registers, i))
3516             {
3517                 context.type = EmulateInstruction::eContextRegisterPlusOffset;
3518                 context.SetRegisterPlusOffset (dwarf_reg, offset);
3519                 if (wback && (n == 13)) // Pop Instruction
3520                 {
3521                     context.type = EmulateInstruction::eContextPopRegisterOffStack;
3522                     context.SetAddress(base_address + offset);
3523                 }
3524 
3525                 // R[i] = MemA [address, 4]; address = address + 4;
3526                 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3527                 if (!success)
3528                     return false;
3529 
3530                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3531                     return false;
3532 
3533                 offset += addr_byte_size;
3534             }
3535         }
3536 
3537         if (BitIsSet (registers, 15))
3538         {
3539             //LoadWritePC (MemA [address, 4]);
3540             context.type = EmulateInstruction::eContextRegisterPlusOffset;
3541             context.SetRegisterPlusOffset (dwarf_reg, offset);
3542             uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3543             if (!success)
3544                 return false;
3545             // In ARMv5T and above, this is an interworking branch.
3546             if (!LoadWritePC(context, data))
3547                 return false;
3548         }
3549 
3550         if (wback && BitIsClear (registers, n))
3551         {
3552             // R[n] = R[n] + 4 * BitCount (registers)
3553             int32_t offset = addr_byte_size * BitCount (registers);
3554             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3555             context.SetRegisterPlusOffset (dwarf_reg, offset);
3556 
3557             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
3558                 return false;
3559         }
3560         if (wback && BitIsSet (registers, n))
3561             // R[n] bits(32) UNKNOWN;
3562             return WriteBits32Unknown (n);
3563     }
3564     return true;
3565 }
3566 
3567 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register.
3568 // The consecutive memory locations end at this address and the address just below the lowest of those locations
3569 // can optionally be written back to the base register.
3570 bool
3571 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding)
3572 {
3573 #if 0
3574     // ARM pseudo code...
3575     if ConditionPassed() then
3576         EncodingSpecificOperations();
3577         address = R[n] - 4*BitCount(registers) + 4;
3578 
3579         for i = 0 to 14
3580             if registers<i> == '1' then
3581                   R[i] = MemA[address,4]; address = address + 4;
3582 
3583         if registers<15> == '1' then
3584             LoadWritePC(MemA[address,4]);
3585 
3586         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3587         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3588 #endif
3589 
3590     bool success = false;
3591 
3592     if (ConditionPassed(opcode))
3593     {
3594         uint32_t n;
3595         uint32_t registers = 0;
3596         bool wback;
3597         const uint32_t addr_byte_size = GetAddressByteSize();
3598 
3599         // EncodingSpecificOperations();
3600         switch (encoding)
3601         {
3602             case eEncodingA1:
3603                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3604                 n = Bits32 (opcode, 19, 16);
3605                 registers = Bits32 (opcode, 15, 0);
3606                 wback = BitIsSet (opcode, 21);
3607 
3608                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3609                 if ((n == 15) || (BitCount (registers) < 1))
3610                     return false;
3611 
3612                 break;
3613 
3614             default:
3615                 return false;
3616         }
3617         // address = R[n] - 4*BitCount(registers) + 4;
3618 
3619         int32_t offset = 0;
3620         addr_t Rn = ReadCoreReg (n, &success);
3621 
3622         if (!success)
3623             return false;
3624 
3625         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size;
3626 
3627         EmulateInstruction::Context context;
3628         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3629         RegisterInfo dwarf_reg;
3630         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3631         context.SetRegisterPlusOffset (dwarf_reg, offset);
3632 
3633         // for i = 0 to 14
3634         for (int i = 0; i < 14; ++i)
3635         {
3636             // if registers<i> == '1' then
3637             if (BitIsSet (registers, i))
3638             {
3639                   // R[i] = MemA[address,4]; address = address + 4;
3640                   context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3641                   uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3642                   if (!success)
3643                       return false;
3644                   if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3645                       return false;
3646                   offset += addr_byte_size;
3647             }
3648         }
3649 
3650         // if registers<15> == '1' then
3651         //     LoadWritePC(MemA[address,4]);
3652         if (BitIsSet (registers, 15))
3653         {
3654             context.SetRegisterPlusOffset (dwarf_reg, offset);
3655             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3656             if (!success)
3657                 return false;
3658             // In ARMv5T and above, this is an interworking branch.
3659             if (!LoadWritePC(context, data))
3660                 return false;
3661         }
3662 
3663         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3664         if (wback && BitIsClear (registers, n))
3665         {
3666             if (!success)
3667                 return false;
3668 
3669             offset = (addr_byte_size * BitCount (registers)) * -1;
3670             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3671             context.SetImmediateSigned (offset);
3672             addr_t addr = Rn + offset;
3673             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3674                 return false;
3675         }
3676 
3677         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3678         if (wback && BitIsSet (registers, n))
3679             return WriteBits32Unknown (n);
3680     }
3681     return true;
3682 }
3683 
3684 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
3685 // consecutive memory locations end just below this address, and the address of the lowest of those locations can
3686 // be optionally written back to the base register.
3687 bool
3688 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding)
3689 {
3690 #if 0
3691     // ARM pseudo code...
3692     if ConditionPassed() then
3693         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3694         address = R[n] - 4*BitCount(registers);
3695 
3696         for i = 0 to 14
3697             if registers<i> == '1' then
3698                   R[i] = MemA[address,4]; address = address + 4;
3699         if registers<15> == '1' then
3700                   LoadWritePC(MemA[address,4]);
3701 
3702         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3703         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3704 #endif
3705 
3706     bool success = false;
3707 
3708     if (ConditionPassed(opcode))
3709     {
3710         uint32_t n;
3711         uint32_t registers = 0;
3712         bool wback;
3713         const uint32_t addr_byte_size = GetAddressByteSize();
3714         switch (encoding)
3715         {
3716             case eEncodingT1:
3717                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3718                 n = Bits32 (opcode, 19, 16);
3719                 registers = Bits32 (opcode, 15, 0);
3720                 registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
3721                 wback = BitIsSet (opcode, 21);
3722 
3723                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3724                 if ((n == 15)
3725                     || (BitCount (registers) < 2)
3726                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3727                     return false;
3728 
3729                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3730                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3731                     return false;
3732 
3733                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3734                 if (wback && BitIsSet (registers, n))
3735                     return false;
3736 
3737                 break;
3738 
3739             case eEncodingA1:
3740                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3741                 n = Bits32 (opcode, 19, 16);
3742                 registers = Bits32 (opcode, 15, 0);
3743                 wback = BitIsSet (opcode, 21);
3744 
3745                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3746                 if ((n == 15) || (BitCount (registers) < 1))
3747                     return false;
3748 
3749                 break;
3750 
3751             default:
3752                 return false;
3753         }
3754 
3755         // address = R[n] - 4*BitCount(registers);
3756 
3757         int32_t offset = 0;
3758         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3759 
3760         if (!success)
3761             return false;
3762 
3763         addr_t address = Rn - (addr_byte_size * BitCount (registers));
3764         EmulateInstruction::Context context;
3765         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3766         RegisterInfo dwarf_reg;
3767         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3768         context.SetRegisterPlusOffset (dwarf_reg, Rn - address);
3769 
3770         for (int i = 0; i < 14; ++i)
3771         {
3772             if (BitIsSet (registers, i))
3773             {
3774                 // R[i] = MemA[address,4]; address = address + 4;
3775                 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3776                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3777                 if (!success)
3778                     return false;
3779 
3780                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3781                     return false;
3782 
3783                 offset += addr_byte_size;
3784             }
3785         }
3786 
3787         // if registers<15> == '1' then
3788         //     LoadWritePC(MemA[address,4]);
3789         if (BitIsSet (registers, 15))
3790         {
3791             context.SetRegisterPlusOffset (dwarf_reg, offset);
3792             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3793             if (!success)
3794                 return false;
3795             // In ARMv5T and above, this is an interworking branch.
3796             if (!LoadWritePC(context, data))
3797                 return false;
3798         }
3799 
3800         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3801         if (wback && BitIsClear (registers, n))
3802         {
3803             if (!success)
3804                 return false;
3805 
3806             offset = (addr_byte_size * BitCount (registers)) * -1;
3807             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3808             context.SetImmediateSigned (offset);
3809             addr_t addr = Rn + offset;
3810             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3811                 return false;
3812         }
3813 
3814         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3815         if (wback && BitIsSet (registers, n))
3816             return WriteBits32Unknown (n);
3817     }
3818     return true;
3819 }
3820 
3821 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
3822 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can
3823 // optinoally be written back to the base register.
3824 bool
3825 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding)
3826 {
3827 #if 0
3828     if ConditionPassed() then
3829         EncodingSpecificOperations();
3830         address = R[n] + 4;
3831 
3832         for i = 0 to 14
3833             if registers<i> == '1' then
3834                   R[i] = MemA[address,4]; address = address + 4;
3835         if registers<15> == '1' then
3836             LoadWritePC(MemA[address,4]);
3837 
3838         if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3839         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3840 #endif
3841 
3842     bool success = false;
3843 
3844     if (ConditionPassed(opcode))
3845     {
3846         uint32_t n;
3847         uint32_t registers = 0;
3848         bool wback;
3849         const uint32_t addr_byte_size = GetAddressByteSize();
3850         switch (encoding)
3851         {
3852             case eEncodingA1:
3853                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3854                 n = Bits32 (opcode, 19, 16);
3855                 registers = Bits32 (opcode, 15, 0);
3856                 wback = BitIsSet (opcode, 21);
3857 
3858                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3859                 if ((n == 15) || (BitCount (registers) < 1))
3860                     return false;
3861 
3862                 break;
3863             default:
3864                 return false;
3865         }
3866         // address = R[n] + 4;
3867 
3868         int32_t offset = 0;
3869         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3870 
3871         if (!success)
3872             return false;
3873 
3874         addr_t address = Rn + addr_byte_size;
3875 
3876         EmulateInstruction::Context context;
3877         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3878         RegisterInfo dwarf_reg;
3879         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3880         context.SetRegisterPlusOffset (dwarf_reg, offset);
3881 
3882         for (int i = 0; i < 14; ++i)
3883         {
3884             if (BitIsSet (registers, i))
3885             {
3886                 // R[i] = MemA[address,4]; address = address + 4;
3887 
3888                 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size);
3889                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3890                 if (!success)
3891                     return false;
3892 
3893                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3894                     return false;
3895 
3896                 offset += addr_byte_size;
3897             }
3898         }
3899 
3900         // if registers<15> == '1' then
3901         //     LoadWritePC(MemA[address,4]);
3902         if (BitIsSet (registers, 15))
3903         {
3904             context.SetRegisterPlusOffset (dwarf_reg, offset);
3905             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3906             if (!success)
3907                 return false;
3908             // In ARMv5T and above, this is an interworking branch.
3909             if (!LoadWritePC(context, data))
3910                 return false;
3911         }
3912 
3913         // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3914         if (wback && BitIsClear (registers, n))
3915         {
3916             if (!success)
3917                 return false;
3918 
3919             offset = addr_byte_size * BitCount (registers);
3920             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3921             context.SetImmediateSigned (offset);
3922             addr_t addr = Rn + offset;
3923             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3924                 return false;
3925         }
3926 
3927         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3928         if (wback && BitIsSet (registers, n))
3929             return WriteBits32Unknown (n);
3930     }
3931     return true;
3932 }
3933 
3934 // Load Register (immediate) calculates an address from a base register value and
3935 // an immediate offset, loads a word from memory, and writes to a register.
3936 // LDR (immediate, Thumb)
3937 bool
3938 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding)
3939 {
3940 #if 0
3941     // ARM pseudo code...
3942     if (ConditionPassed())
3943     {
3944         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3945         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3946         address = if index then offset_addr else R[n];
3947         data = MemU[address,4];
3948         if wback then R[n] = offset_addr;
3949         if t == 15 then
3950             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3951         elsif UnalignedSupport() || address<1:0> = '00' then
3952             R[t] = data;
3953         else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3954     }
3955 #endif
3956 
3957     bool success = false;
3958 
3959     if (ConditionPassed(opcode))
3960     {
3961         uint32_t Rt; // the destination register
3962         uint32_t Rn; // the base register
3963         uint32_t imm32; // the immediate offset used to form the address
3964         addr_t offset_addr; // the offset address
3965         addr_t address; // the calculated address
3966         uint32_t data; // the literal data value from memory load
3967         bool add, index, wback;
3968         switch (encoding) {
3969             case eEncodingT1:
3970                 Rt = Bits32(opcode, 2, 0);
3971                 Rn = Bits32(opcode, 5, 3);
3972                 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3973                 // index = TRUE; add = TRUE; wback = FALSE
3974                 add = true;
3975                 index = true;
3976                 wback = false;
3977 
3978                 break;
3979 
3980             case eEncodingT2:
3981                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
3982                 Rt = Bits32 (opcode, 10, 8);
3983                 Rn = 13;
3984                 imm32 = Bits32 (opcode, 7, 0) << 2;
3985 
3986                 // index = TRUE; add = TRUE; wback = FALSE;
3987                 index = true;
3988                 add = true;
3989                 wback = false;
3990 
3991                 break;
3992 
3993             case eEncodingT3:
3994                 // if Rn == '1111' then SEE LDR (literal);
3995                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
3996                 Rt = Bits32 (opcode, 15, 12);
3997                 Rn = Bits32 (opcode, 19, 16);
3998                 imm32 = Bits32 (opcode, 11, 0);
3999 
4000                 // index = TRUE; add = TRUE; wback = FALSE;
4001                 index = true;
4002                 add = true;
4003                 wback = false;
4004 
4005                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
4006                 if ((Rt == 15) && InITBlock() && !LastInITBlock())
4007                     return false;
4008 
4009                 break;
4010 
4011             case eEncodingT4:
4012                 // if Rn == '1111' then SEE LDR (literal);
4013                 // if P == '1' && U == '1' && W == '0' then SEE LDRT;
4014                 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
4015                 // if P == '0' && W == '0' then UNDEFINED;
4016                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
4017                     return false;
4018 
4019                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4020                 Rt = Bits32 (opcode, 15, 12);
4021                 Rn = Bits32 (opcode, 19, 16);
4022                 imm32 = Bits32 (opcode, 7, 0);
4023 
4024                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4025                 index = BitIsSet (opcode, 10);
4026                 add = BitIsSet (opcode, 9);
4027                 wback = BitIsSet (opcode, 8);
4028 
4029                 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
4030                 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock()))
4031                     return false;
4032 
4033                 break;
4034 
4035             default:
4036                 return false;
4037         }
4038         uint32_t base = ReadCoreReg (Rn, &success);
4039         if (!success)
4040             return false;
4041         if (add)
4042             offset_addr = base + imm32;
4043         else
4044             offset_addr = base - imm32;
4045 
4046         address = (index ? offset_addr : base);
4047 
4048         RegisterInfo base_reg;
4049         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
4050         if (wback)
4051         {
4052             EmulateInstruction::Context ctx;
4053             if (Rn == 13)
4054             {
4055                 ctx.type = eContextAdjustStackPointer;
4056                 ctx.SetImmediateSigned((int32_t) (offset_addr - base));
4057             }
4058             else if (Rn == GetFramePointerRegisterNumber())
4059             {
4060                 ctx.type = eContextSetFramePointer;
4061                 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
4062             }
4063             else
4064             {
4065                 ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
4066                 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
4067             }
4068 
4069 
4070             if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
4071                 return false;
4072         }
4073 
4074         // Prepare to write to the Rt register.
4075         EmulateInstruction::Context context;
4076         context.type = EmulateInstruction::eContextRegisterLoad;
4077         context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
4078 
4079         // Read memory from the address.
4080         data = MemURead(context, address, 4, 0, &success);
4081         if (!success)
4082             return false;
4083 
4084         if (Rt == 15)
4085         {
4086             if (Bits32(address, 1, 0) == 0)
4087             {
4088                 if (!LoadWritePC(context, data))
4089                     return false;
4090             }
4091             else
4092                 return false;
4093         }
4094         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
4095         {
4096             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
4097                 return false;
4098         }
4099         else
4100             WriteBits32Unknown (Rt);
4101     }
4102     return true;
4103 }
4104 
4105 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
4106 // from a base register.  The consecutive memory locations start at this address, and the address just above the last
4107 // of those locations can optionally be written back to the base register.
4108 bool
4109 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding)
4110 {
4111 #if 0
4112     if ConditionPassed() then
4113         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4114         address = R[n];
4115 
4116         for i = 0 to 14
4117             if registers<i> == '1' then
4118                 if i == n && wback && i != LowestSetBit(registers) then
4119                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4120                 else
4121                     MemA[address,4] = R[i];
4122                 address = address + 4;
4123 
4124         if registers<15> == '1' then // Only possible for encoding A1
4125             MemA[address,4] = PCStoreValue();
4126         if wback then R[n] = R[n] + 4*BitCount(registers);
4127 #endif
4128 
4129     bool success = false;
4130 
4131     if (ConditionPassed(opcode))
4132     {
4133         uint32_t n;
4134         uint32_t registers = 0;
4135         bool wback;
4136         const uint32_t addr_byte_size = GetAddressByteSize();
4137 
4138         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4139         switch (encoding)
4140         {
4141             case eEncodingT1:
4142                 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4143                 n = Bits32 (opcode, 10, 8);
4144                 registers = Bits32 (opcode, 7, 0);
4145                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
4146                 wback = true;
4147 
4148                 // if BitCount(registers) < 1 then UNPREDICTABLE;
4149                 if (BitCount (registers) < 1)
4150                     return false;
4151 
4152                 break;
4153 
4154             case eEncodingT2:
4155                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4156                 n = Bits32 (opcode, 19, 16);
4157                 registers = Bits32 (opcode, 15, 0);
4158                 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4159                 wback = BitIsSet (opcode, 21);
4160 
4161                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4162                 if ((n == 15) || (BitCount (registers) < 2))
4163                     return false;
4164 
4165                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4166                 if (wback && BitIsSet (registers, n))
4167                     return false;
4168 
4169                 break;
4170 
4171             case eEncodingA1:
4172                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4173                 n = Bits32 (opcode, 19, 16);
4174                 registers = Bits32 (opcode, 15, 0);
4175                 wback = BitIsSet (opcode, 21);
4176 
4177                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4178                 if ((n == 15) || (BitCount (registers) < 1))
4179                     return false;
4180 
4181                 break;
4182 
4183             default:
4184                 return false;
4185         }
4186 
4187         // address = R[n];
4188         int32_t offset = 0;
4189         const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4190         if (!success)
4191             return false;
4192 
4193         EmulateInstruction::Context context;
4194         context.type = EmulateInstruction::eContextRegisterStore;
4195         RegisterInfo base_reg;
4196         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4197 
4198         // for i = 0 to 14
4199         uint32_t lowest_set_bit = 14;
4200         for (uint32_t i = 0; i < 14; ++i)
4201         {
4202             // if registers<i> == '1' then
4203             if (BitIsSet (registers, i))
4204             {
4205                   if (i < lowest_set_bit)
4206                       lowest_set_bit = i;
4207                   // if i == n && wback && i != LowestSetBit(registers) then
4208                   if ((i == n) && wback && (i != lowest_set_bit))
4209                       // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4210                       WriteBits32UnknownToMemory (address + offset);
4211                   else
4212                   {
4213                      // MemA[address,4] = R[i];
4214                       uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4215                       if (!success)
4216                           return false;
4217 
4218                       RegisterInfo data_reg;
4219                       GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4220                       context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4221                       if (!MemAWrite (context, address + offset, data, addr_byte_size))
4222                           return false;
4223                   }
4224 
4225                   // address = address + 4;
4226                   offset += addr_byte_size;
4227             }
4228         }
4229 
4230         // if registers<15> == '1' then // Only possible for encoding A1
4231         //     MemA[address,4] = PCStoreValue();
4232         if (BitIsSet (registers, 15))
4233         {
4234             RegisterInfo pc_reg;
4235             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4236             context.SetRegisterPlusOffset (pc_reg, 8);
4237             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4238             if (!success)
4239                 return false;
4240 
4241             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4242                 return false;
4243         }
4244 
4245         // if wback then R[n] = R[n] + 4*BitCount(registers);
4246         if (wback)
4247         {
4248             offset = addr_byte_size * BitCount (registers);
4249             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4250             context.SetImmediateSigned (offset);
4251             addr_t data = address + offset;
4252             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4253                 return false;
4254         }
4255     }
4256     return true;
4257 }
4258 
4259 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
4260 // from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
4261 // of those locations can optionally be written back to the base register.
4262 bool
4263 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding)
4264 {
4265 #if 0
4266     if ConditionPassed() then
4267         EncodingSpecificOperations();
4268         address = R[n] - 4*BitCount(registers) + 4;
4269 
4270         for i = 0 to 14
4271             if registers<i> == '1' then
4272                 if i == n && wback && i != LowestSetBit(registers) then
4273                     MemA[address,4] = bits(32) UNKNOWN;
4274                 else
4275                     MemA[address,4] = R[i];
4276                 address = address + 4;
4277 
4278         if registers<15> == '1' then
4279             MemA[address,4] = PCStoreValue();
4280 
4281         if wback then R[n] = R[n] - 4*BitCount(registers);
4282 #endif
4283 
4284     bool success = false;
4285 
4286     if (ConditionPassed(opcode))
4287     {
4288         uint32_t n;
4289         uint32_t registers = 0;
4290         bool wback;
4291         const uint32_t addr_byte_size = GetAddressByteSize();
4292 
4293         // EncodingSpecificOperations();
4294         switch (encoding)
4295         {
4296             case eEncodingA1:
4297                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4298                 n = Bits32 (opcode, 19, 16);
4299                 registers = Bits32 (opcode, 15, 0);
4300                 wback = BitIsSet (opcode, 21);
4301 
4302                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4303                 if ((n == 15) || (BitCount (registers) < 1))
4304                     return false;
4305                 break;
4306             default:
4307                 return false;
4308         }
4309 
4310         // address = R[n] - 4*BitCount(registers) + 4;
4311         int32_t offset = 0;
4312         addr_t Rn = ReadCoreReg (n, &success);
4313         if (!success)
4314             return false;
4315 
4316         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4;
4317 
4318         EmulateInstruction::Context context;
4319         context.type = EmulateInstruction::eContextRegisterStore;
4320         RegisterInfo base_reg;
4321         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4322 
4323         // for i = 0 to 14
4324         uint32_t lowest_bit_set = 14;
4325         for (uint32_t i = 0; i < 14; ++i)
4326         {
4327             // if registers<i> == '1' then
4328             if (BitIsSet (registers, i))
4329             {
4330                 if (i < lowest_bit_set)
4331                     lowest_bit_set = i;
4332                 //if i == n && wback && i != LowestSetBit(registers) then
4333                 if ((i == n) && wback && (i != lowest_bit_set))
4334                     // MemA[address,4] = bits(32) UNKNOWN;
4335                     WriteBits32UnknownToMemory (address + offset);
4336                 else
4337                 {
4338                     // MemA[address,4] = R[i];
4339                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4340                     if (!success)
4341                         return false;
4342 
4343                     RegisterInfo data_reg;
4344                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4345                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4346                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4347                         return false;
4348                 }
4349 
4350                 // address = address + 4;
4351                 offset += addr_byte_size;
4352             }
4353         }
4354 
4355         // if registers<15> == '1' then
4356         //    MemA[address,4] = PCStoreValue();
4357         if (BitIsSet (registers, 15))
4358         {
4359             RegisterInfo pc_reg;
4360             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4361             context.SetRegisterPlusOffset (pc_reg, 8);
4362             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4363             if (!success)
4364                 return false;
4365 
4366             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4367                 return false;
4368         }
4369 
4370         // if wback then R[n] = R[n] - 4*BitCount(registers);
4371         if (wback)
4372         {
4373             offset = (addr_byte_size * BitCount (registers)) * -1;
4374             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4375             context.SetImmediateSigned (offset);
4376             addr_t data = Rn + offset;
4377             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4378                 return false;
4379         }
4380     }
4381     return true;
4382 }
4383 
4384 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
4385 // from a base register.  The consecutive memory locations end just below this address, and the address of the first of
4386 // those locations can optionally be written back to the base register.
4387 bool
4388 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding)
4389 {
4390 #if 0
4391     if ConditionPassed() then
4392         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4393         address = R[n] - 4*BitCount(registers);
4394 
4395         for i = 0 to 14
4396             if registers<i> == '1' then
4397                 if i == n && wback && i != LowestSetBit(registers) then
4398                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4399                 else
4400                     MemA[address,4] = R[i];
4401                 address = address + 4;
4402 
4403         if registers<15> == '1' then // Only possible for encoding A1
4404             MemA[address,4] = PCStoreValue();
4405 
4406         if wback then R[n] = R[n] - 4*BitCount(registers);
4407 #endif
4408 
4409 
4410     bool success = false;
4411 
4412     if (ConditionPassed(opcode))
4413     {
4414         uint32_t n;
4415         uint32_t registers = 0;
4416         bool wback;
4417         const uint32_t addr_byte_size = GetAddressByteSize();
4418 
4419         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4420         switch (encoding)
4421         {
4422             case eEncodingT1:
4423                 // if W == '1' && Rn == '1101' then SEE PUSH;
4424                 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
4425                 {
4426                     // See PUSH
4427                 }
4428                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4429                 n = Bits32 (opcode, 19, 16);
4430                 registers = Bits32 (opcode, 15, 0);
4431                 registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
4432                 wback = BitIsSet (opcode, 21);
4433                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4434                 if ((n == 15) || BitCount (registers) < 2)
4435                     return false;
4436                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4437                 if (wback && BitIsSet (registers, n))
4438                     return false;
4439                 break;
4440 
4441             case eEncodingA1:
4442                 // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE PUSH;
4443                 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
4444                 {
4445                     // See Push
4446                 }
4447                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4448                 n = Bits32 (opcode, 19, 16);
4449                 registers = Bits32 (opcode, 15, 0);
4450                 wback = BitIsSet (opcode, 21);
4451                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4452                 if ((n == 15) || BitCount (registers) < 1)
4453                     return false;
4454                 break;
4455 
4456             default:
4457                 return false;
4458         }
4459 
4460         // address = R[n] - 4*BitCount(registers);
4461 
4462         int32_t offset = 0;
4463         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4464         if (!success)
4465         return false;
4466 
4467         addr_t address = Rn - (addr_byte_size * BitCount (registers));
4468 
4469         EmulateInstruction::Context context;
4470         context.type = EmulateInstruction::eContextRegisterStore;
4471         RegisterInfo base_reg;
4472         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4473 
4474         // for i = 0 to 14
4475         uint32_t lowest_set_bit = 14;
4476         for (uint32_t i = 0; i < 14; ++i)
4477         {
4478             // if registers<i> == '1' then
4479             if (BitIsSet (registers, i))
4480             {
4481                 if (i < lowest_set_bit)
4482                     lowest_set_bit = i;
4483                 // if i == n && wback && i != LowestSetBit(registers) then
4484                 if ((i == n) && wback && (i != lowest_set_bit))
4485                     // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4486                     WriteBits32UnknownToMemory (address + offset);
4487                 else
4488                 {
4489                     // MemA[address,4] = R[i];
4490                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4491                     if (!success)
4492                         return false;
4493 
4494                     RegisterInfo data_reg;
4495                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4496                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4497                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4498                         return false;
4499                 }
4500 
4501                 // address = address + 4;
4502                 offset += addr_byte_size;
4503             }
4504         }
4505 
4506         // if registers<15> == '1' then // Only possible for encoding A1
4507         //     MemA[address,4] = PCStoreValue();
4508         if (BitIsSet (registers, 15))
4509         {
4510             RegisterInfo pc_reg;
4511             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4512             context.SetRegisterPlusOffset (pc_reg, 8);
4513             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4514             if (!success)
4515                 return false;
4516 
4517             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4518                 return false;
4519         }
4520 
4521         // if wback then R[n] = R[n] - 4*BitCount(registers);
4522         if (wback)
4523         {
4524             offset = (addr_byte_size * BitCount (registers)) * -1;
4525             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4526             context.SetImmediateSigned (offset);
4527             addr_t data = Rn + offset;
4528             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4529                 return false;
4530         }
4531     }
4532     return true;
4533 }
4534 
4535 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
4536 // from a base register.  The consecutive memory locations start just above this address, and the address of the last
4537 // of those locations can optionally be written back to the base register.
4538 bool
4539 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding)
4540 {
4541 #if 0
4542     if ConditionPassed() then
4543         EncodingSpecificOperations();
4544         address = R[n] + 4;
4545 
4546         for i = 0 to 14
4547             if registers<i> == '1' then
4548                 if i == n && wback && i != LowestSetBit(registers) then
4549                     MemA[address,4] = bits(32) UNKNOWN;
4550                 else
4551                     MemA[address,4] = R[i];
4552                 address = address + 4;
4553 
4554         if registers<15> == '1' then
4555             MemA[address,4] = PCStoreValue();
4556 
4557         if wback then R[n] = R[n] + 4*BitCount(registers);
4558 #endif
4559 
4560     bool success = false;
4561 
4562     if (ConditionPassed(opcode))
4563     {
4564         uint32_t n;
4565         uint32_t registers = 0;
4566         bool wback;
4567         const uint32_t addr_byte_size = GetAddressByteSize();
4568 
4569         // EncodingSpecificOperations();
4570         switch (encoding)
4571         {
4572             case eEncodingA1:
4573                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4574                 n = Bits32 (opcode, 19, 16);
4575                 registers = Bits32 (opcode, 15, 0);
4576                 wback = BitIsSet (opcode, 21);
4577 
4578                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4579                 if ((n == 15) && (BitCount (registers) < 1))
4580                     return false;
4581                 break;
4582             default:
4583                 return false;
4584         }
4585         // address = R[n] + 4;
4586 
4587         int32_t offset = 0;
4588         addr_t Rn = ReadCoreReg (n, &success);
4589         if (!success)
4590             return false;
4591 
4592         addr_t address = Rn + addr_byte_size;
4593 
4594         EmulateInstruction::Context context;
4595         context.type = EmulateInstruction::eContextRegisterStore;
4596         RegisterInfo base_reg;
4597         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4598 
4599         uint32_t lowest_set_bit = 14;
4600         // for i = 0 to 14
4601         for (uint32_t i = 0; i < 14; ++i)
4602         {
4603             // if registers<i> == '1' then
4604             if (BitIsSet (registers, i))
4605             {
4606                 if (i < lowest_set_bit)
4607                     lowest_set_bit = i;
4608                 // if i == n && wback && i != LowestSetBit(registers) then
4609                 if ((i == n) && wback && (i != lowest_set_bit))
4610                     // MemA[address,4] = bits(32) UNKNOWN;
4611                     WriteBits32UnknownToMemory (address + offset);
4612                 // else
4613                 else
4614                 {
4615                     // MemA[address,4] = R[i];
4616                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4617                     if (!success)
4618                         return false;
4619 
4620                     RegisterInfo data_reg;
4621                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4622                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size);
4623                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4624                         return false;
4625                 }
4626 
4627                 // address = address + 4;
4628                 offset += addr_byte_size;
4629             }
4630         }
4631 
4632         // if registers<15> == '1' then
4633             // MemA[address,4] = PCStoreValue();
4634         if (BitIsSet (registers, 15))
4635         {
4636             RegisterInfo pc_reg;
4637             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4638             context.SetRegisterPlusOffset (pc_reg, 8);
4639             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4640             if (!success)
4641             return false;
4642 
4643             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4644                 return false;
4645         }
4646 
4647         // if wback then R[n] = R[n] + 4*BitCount(registers);
4648         if (wback)
4649         {
4650             offset = addr_byte_size * BitCount (registers);
4651             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4652             context.SetImmediateSigned (offset);
4653             addr_t data = Rn + offset;
4654             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4655                 return false;
4656         }
4657     }
4658     return true;
4659 }
4660 
4661 // STR (store immediate) calculates an address from a base register value and an immediate offset, and stores a word
4662 // from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
4663 bool
4664 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding)
4665 {
4666 #if 0
4667     if ConditionPassed() then
4668         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4669         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4670         address = if index then offset_addr else R[n];
4671         if UnalignedSupport() || address<1:0> == '00' then
4672             MemU[address,4] = R[t];
4673         else // Can only occur before ARMv7
4674             MemU[address,4] = bits(32) UNKNOWN;
4675         if wback then R[n] = offset_addr;
4676 #endif
4677 
4678     bool success = false;
4679 
4680     if (ConditionPassed(opcode))
4681     {
4682         const uint32_t addr_byte_size = GetAddressByteSize();
4683 
4684         uint32_t t;
4685         uint32_t n;
4686         uint32_t imm32;
4687         bool index;
4688         bool add;
4689         bool wback;
4690         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4691         switch (encoding)
4692         {
4693             case eEncodingT1:
4694                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
4695                 t = Bits32 (opcode, 2, 0);
4696                 n = Bits32 (opcode, 5, 3);
4697                 imm32 = Bits32 (opcode, 10, 6) << 2;
4698 
4699                 // index = TRUE; add = TRUE; wback = FALSE;
4700                 index = true;
4701                 add = false;
4702                 wback = false;
4703                 break;
4704 
4705             case eEncodingT2:
4706                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4707                 t = Bits32 (opcode, 10, 8);
4708                 n = 13;
4709                 imm32 = Bits32 (opcode, 7, 0) << 2;
4710 
4711                 // index = TRUE; add = TRUE; wback = FALSE;
4712                 index = true;
4713                 add = true;
4714                 wback = false;
4715                 break;
4716 
4717             case eEncodingT3:
4718                 // if Rn == '1111' then UNDEFINED;
4719                 if (Bits32 (opcode, 19, 16) == 15)
4720                     return false;
4721 
4722                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4723                 t = Bits32 (opcode, 15, 12);
4724                 n = Bits32 (opcode, 19, 16);
4725                 imm32 = Bits32 (opcode, 11, 0);
4726 
4727                 // index = TRUE; add = TRUE; wback = FALSE;
4728                 index = true;
4729                 add = true;
4730                 wback = false;
4731 
4732                 // if t == 15 then UNPREDICTABLE;
4733                 if (t == 15)
4734                     return false;
4735                 break;
4736 
4737             case eEncodingT4:
4738                 // if P == '1' && U == '1' && W == '0' then SEE STRT;
4739                 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH;
4740                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4741                 if ((Bits32 (opcode, 19, 16) == 15)
4742                       || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
4743                     return false;
4744 
4745                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4746                 t = Bits32 (opcode, 15, 12);
4747                 n = Bits32 (opcode, 19, 16);
4748                 imm32 = Bits32 (opcode, 7, 0);
4749 
4750                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4751                 index = BitIsSet (opcode, 10);
4752                 add = BitIsSet (opcode, 9);
4753                 wback = BitIsSet (opcode, 8);
4754 
4755                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
4756                 if ((t == 15) || (wback && (n == t)))
4757                     return false;
4758                 break;
4759 
4760             default:
4761                 return false;
4762         }
4763 
4764         addr_t offset_addr;
4765         addr_t address;
4766 
4767         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4768         uint32_t base_address = ReadCoreReg (n, &success);
4769         if (!success)
4770             return false;
4771 
4772         if (add)
4773             offset_addr = base_address + imm32;
4774         else
4775             offset_addr = base_address - imm32;
4776 
4777         // address = if index then offset_addr else R[n];
4778         if (index)
4779             address = offset_addr;
4780         else
4781             address = base_address;
4782 
4783         EmulateInstruction::Context context;
4784         context.type = eContextRegisterStore;
4785         RegisterInfo base_reg;
4786         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4787 
4788         // if UnalignedSupport() || address<1:0> == '00' then
4789         if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
4790         {
4791             // MemU[address,4] = R[t];
4792             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4793             if (!success)
4794                 return false;
4795 
4796             RegisterInfo data_reg;
4797             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4798             int32_t offset = address - base_address;
4799             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4800             if (!MemUWrite (context, address, data, addr_byte_size))
4801                 return false;
4802         }
4803         else
4804         {
4805             // MemU[address,4] = bits(32) UNKNOWN;
4806             WriteBits32UnknownToMemory (address);
4807         }
4808 
4809         // if wback then R[n] = offset_addr;
4810         if (wback)
4811         {
4812             context.type = eContextRegisterLoad;
4813             context.SetAddress (offset_addr);
4814             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4815                 return false;
4816         }
4817     }
4818     return true;
4819 }
4820 
4821 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a
4822 // word from a register to memory.   The offset register value can optionally be shifted.
4823 bool
4824 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding)
4825 {
4826 #if 0
4827     if ConditionPassed() then
4828         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4829         offset = Shift(R[m], shift_t, shift_n, APSR.C);
4830         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4831         address = if index then offset_addr else R[n];
4832         if t == 15 then // Only possible for encoding A1
4833             data = PCStoreValue();
4834         else
4835             data = R[t];
4836         if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4837             MemU[address,4] = data;
4838         else // Can only occur before ARMv7
4839             MemU[address,4] = bits(32) UNKNOWN;
4840         if wback then R[n] = offset_addr;
4841 #endif
4842 
4843     bool success = false;
4844 
4845     if (ConditionPassed(opcode))
4846     {
4847         const uint32_t addr_byte_size = GetAddressByteSize();
4848 
4849         uint32_t t;
4850         uint32_t n;
4851         uint32_t m;
4852         ARM_ShifterType shift_t;
4853         uint32_t shift_n;
4854         bool index;
4855         bool add;
4856         bool wback;
4857 
4858         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4859         switch (encoding)
4860         {
4861             case eEncodingT1:
4862                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4863                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4864                 t = Bits32 (opcode, 2, 0);
4865                 n = Bits32 (opcode, 5, 3);
4866                 m = Bits32 (opcode, 8, 6);
4867 
4868                 // index = TRUE; add = TRUE; wback = FALSE;
4869                 index = true;
4870                 add = true;
4871                 wback = false;
4872 
4873                 // (shift_t, shift_n) = (SRType_LSL, 0);
4874                 shift_t = SRType_LSL;
4875                 shift_n = 0;
4876                 break;
4877 
4878             case eEncodingT2:
4879                 // if Rn == '1111' then UNDEFINED;
4880                 if (Bits32 (opcode, 19, 16) == 15)
4881                     return false;
4882 
4883                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4884                 t = Bits32 (opcode, 15, 12);
4885                 n = Bits32 (opcode, 19, 16);
4886                 m = Bits32 (opcode, 3, 0);
4887 
4888                 // index = TRUE; add = TRUE; wback = FALSE;
4889                 index = true;
4890                 add = true;
4891                 wback = false;
4892 
4893                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4894                 shift_t = SRType_LSL;
4895                 shift_n = Bits32 (opcode, 5, 4);
4896 
4897                 // if t == 15 || BadReg(m) then UNPREDICTABLE;
4898                 if ((t == 15) || (BadReg (m)))
4899                     return false;
4900                 break;
4901 
4902             case eEncodingA1:
4903             {
4904                 // if P == '0' && W == '1' then SEE STRT;
4905                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4906                 t = Bits32 (opcode, 15, 12);
4907                 n = Bits32 (opcode, 19, 16);
4908                 m = Bits32 (opcode, 3, 0);
4909 
4910                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
4911                 index = BitIsSet (opcode, 24);
4912                 add = BitIsSet (opcode, 23);
4913                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
4914 
4915                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
4916                 uint32_t typ = Bits32 (opcode, 6, 5);
4917                 uint32_t imm5 = Bits32 (opcode, 11, 7);
4918                 shift_n = DecodeImmShift(typ, imm5, shift_t);
4919 
4920                 // if m == 15 then UNPREDICTABLE;
4921                 if (m == 15)
4922                     return false;
4923 
4924                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
4925                 if (wback && ((n == 15) || (n == t)))
4926                     return false;
4927 
4928                 break;
4929             }
4930             default:
4931                 return false;
4932         }
4933 
4934         addr_t offset_addr;
4935         addr_t address;
4936         int32_t offset = 0;
4937 
4938         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4939         if (!success)
4940             return false;
4941 
4942         uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
4943         if (!success)
4944             return false;
4945 
4946         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4947         offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success);
4948         if (!success)
4949             return false;
4950 
4951         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4952         if (add)
4953             offset_addr = base_address + offset;
4954         else
4955             offset_addr = base_address - offset;
4956 
4957         // address = if index then offset_addr else R[n];
4958         if (index)
4959             address = offset_addr;
4960         else
4961             address = base_address;
4962 
4963         uint32_t data;
4964         // if t == 15 then // Only possible for encoding A1
4965         if (t == 15)
4966             // data = PCStoreValue();
4967             data = ReadCoreReg (PC_REG, &success);
4968         else
4969             // data = R[t];
4970             data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4971 
4972         if (!success)
4973             return false;
4974 
4975         EmulateInstruction::Context context;
4976         context.type = eContextRegisterStore;
4977 
4978         // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4979         if (UnalignedSupport ()
4980             || (BitIsClear (address, 1) && BitIsClear (address, 0))
4981             || CurrentInstrSet() == eModeARM)
4982         {
4983             // MemU[address,4] = data;
4984 
4985             RegisterInfo base_reg;
4986             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 +  n, base_reg);
4987 
4988             RegisterInfo data_reg;
4989             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4990 
4991             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4992             if (!MemUWrite (context, address, data, addr_byte_size))
4993                 return false;
4994 
4995         }
4996         else
4997             // MemU[address,4] = bits(32) UNKNOWN;
4998             WriteBits32UnknownToMemory (address);
4999 
5000         // if wback then R[n] = offset_addr;
5001         if (wback)
5002         {
5003             context.type = eContextRegisterLoad;
5004             context.SetAddress (offset_addr);
5005             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5006                 return false;
5007         }
5008 
5009     }
5010     return true;
5011 }
5012 
5013 bool
5014 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding)
5015 {
5016 #if 0
5017     if ConditionPassed() then
5018         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5019         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5020         address = if index then offset_addr else R[n];
5021         MemU[address,1] = R[t]<7:0>;
5022         if wback then R[n] = offset_addr;
5023 #endif
5024 
5025 
5026     bool success = false;
5027 
5028     if (ConditionPassed(opcode))
5029     {
5030         uint32_t t;
5031         uint32_t n;
5032         uint32_t imm32;
5033         bool index;
5034         bool add;
5035         bool wback;
5036         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5037         switch (encoding)
5038         {
5039             case eEncodingT1:
5040                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
5041                 t = Bits32 (opcode, 2, 0);
5042                 n = Bits32 (opcode, 5, 3);
5043                 imm32 = Bits32 (opcode, 10, 6);
5044 
5045                 // index = TRUE; add = TRUE; wback = FALSE;
5046                 index = true;
5047                 add = true;
5048                 wback = false;
5049                 break;
5050 
5051             case eEncodingT2:
5052                 // if Rn == '1111' then UNDEFINED;
5053                 if (Bits32 (opcode, 19, 16) == 15)
5054                     return false;
5055 
5056                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5057                 t = Bits32 (opcode, 15, 12);
5058                 n = Bits32 (opcode, 19, 16);
5059                 imm32 = Bits32 (opcode, 11, 0);
5060 
5061                 // index = TRUE; add = TRUE; wback = FALSE;
5062                 index = true;
5063                 add = true;
5064                 wback = false;
5065 
5066                 // if BadReg(t) then UNPREDICTABLE;
5067                 if (BadReg (t))
5068                     return false;
5069                 break;
5070 
5071             case eEncodingT3:
5072                 // if P == '1' && U == '1' && W == '0' then SEE STRBT;
5073                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5074                 if (Bits32 (opcode, 19, 16) == 15)
5075                     return false;
5076 
5077                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5078                 t = Bits32 (opcode, 15, 12);
5079                 n = Bits32 (opcode, 19, 16);
5080                 imm32 = Bits32 (opcode, 7, 0);
5081 
5082                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5083                 index = BitIsSet (opcode, 10);
5084                 add = BitIsSet (opcode, 9);
5085                 wback = BitIsSet (opcode, 8);
5086 
5087                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
5088                 if ((BadReg (t)) || (wback && (n == t)))
5089                     return false;
5090                 break;
5091 
5092             default:
5093                 return false;
5094         }
5095 
5096         addr_t offset_addr;
5097         addr_t address;
5098         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5099         if (!success)
5100             return false;
5101 
5102         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5103         if (add)
5104             offset_addr = base_address + imm32;
5105         else
5106             offset_addr = base_address - imm32;
5107 
5108         // address = if index then offset_addr else R[n];
5109         if (index)
5110             address = offset_addr;
5111         else
5112             address = base_address;
5113 
5114         // MemU[address,1] = R[t]<7:0>
5115         RegisterInfo base_reg;
5116         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5117 
5118         RegisterInfo data_reg;
5119         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5120 
5121         EmulateInstruction::Context context;
5122         context.type = eContextRegisterStore;
5123         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
5124 
5125         uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5126         if (!success)
5127             return false;
5128 
5129         data = Bits32 (data, 7, 0);
5130 
5131         if (!MemUWrite (context, address, data, 1))
5132             return false;
5133 
5134         // if wback then R[n] = offset_addr;
5135         if (wback)
5136         {
5137             context.type = eContextRegisterLoad;
5138             context.SetAddress (offset_addr);
5139             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5140                 return false;
5141         }
5142 
5143     }
5144 
5145     return true;
5146 }
5147 
5148 // STRH (register) calculates an address from a base register value and an offset register value, and stores a
5149 // halfword from a register to memory.  The offset register value can be shifted left by 0, 1, 2, or 3 bits.
5150 bool
5151 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding)
5152 {
5153 #if 0
5154     if ConditionPassed() then
5155         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5156         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5157         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5158         address = if index then offset_addr else R[n];
5159         if UnalignedSupport() || address<0> == '0' then
5160             MemU[address,2] = R[t]<15:0>;
5161         else // Can only occur before ARMv7
5162             MemU[address,2] = bits(16) UNKNOWN;
5163         if wback then R[n] = offset_addr;
5164 #endif
5165 
5166     bool success = false;
5167 
5168     if (ConditionPassed(opcode))
5169     {
5170         uint32_t t;
5171         uint32_t n;
5172         uint32_t m;
5173         bool index;
5174         bool add;
5175         bool wback;
5176         ARM_ShifterType shift_t;
5177         uint32_t shift_n;
5178 
5179         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5180         switch (encoding)
5181         {
5182             case eEncodingT1:
5183                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5184                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5185                 t = Bits32 (opcode, 2, 0);
5186                 n = Bits32 (opcode, 5, 3);
5187                 m = Bits32 (opcode, 8, 6);
5188 
5189                 // index = TRUE; add = TRUE; wback = FALSE;
5190                 index = true;
5191                 add = true;
5192                 wback = false;
5193 
5194                 // (shift_t, shift_n) = (SRType_LSL, 0);
5195                 shift_t = SRType_LSL;
5196                 shift_n = 0;
5197 
5198                 break;
5199 
5200             case eEncodingT2:
5201                 // if Rn == '1111' then UNDEFINED;
5202                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5203                 t = Bits32 (opcode, 15, 12);
5204                 n = Bits32 (opcode, 19, 16);
5205                 m = Bits32 (opcode, 3, 0);
5206                 if (n == 15)
5207                     return false;
5208 
5209                 // index = TRUE; add = TRUE; wback = FALSE;
5210                 index = true;
5211                 add = true;
5212                 wback = false;
5213 
5214                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5215                 shift_t = SRType_LSL;
5216                 shift_n = Bits32 (opcode, 5, 4);
5217 
5218                 // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5219                 if (BadReg (t) || BadReg (m))
5220                     return false;
5221 
5222                 break;
5223 
5224             case eEncodingA1:
5225                 // if P == '0' && W == '1' then SEE STRHT;
5226                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5227                 t = Bits32 (opcode, 15, 12);
5228                 n = Bits32 (opcode, 19, 16);
5229                 m = Bits32 (opcode, 3, 0);
5230 
5231                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5232                 index = BitIsSet (opcode, 24);
5233                 add = BitIsSet (opcode, 23);
5234                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5235 
5236                 // (shift_t, shift_n) = (SRType_LSL, 0);
5237                 shift_t = SRType_LSL;
5238                 shift_n = 0;
5239 
5240                 // if t == 15 || m == 15 then UNPREDICTABLE;
5241                 if ((t == 15) || (m == 15))
5242                     return false;
5243 
5244                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5245                 if (wback && ((n == 15) || (n == t)))
5246                     return false;
5247 
5248                 break;
5249 
5250             default:
5251                 return false;
5252         }
5253 
5254         uint32_t Rm = ReadCoreReg (m, &success);
5255         if (!success)
5256             return false;
5257 
5258         uint32_t Rn = ReadCoreReg (n, &success);
5259         if (!success)
5260             return false;
5261 
5262         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5263         uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
5264         if (!success)
5265             return false;
5266 
5267         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5268         addr_t offset_addr;
5269         if (add)
5270             offset_addr = Rn + offset;
5271         else
5272             offset_addr = Rn - offset;
5273 
5274         // address = if index then offset_addr else R[n];
5275         addr_t address;
5276         if (index)
5277             address = offset_addr;
5278         else
5279             address = Rn;
5280 
5281         EmulateInstruction::Context context;
5282         context.type = eContextRegisterStore;
5283         RegisterInfo base_reg;
5284         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5285         RegisterInfo offset_reg;
5286         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5287 
5288         // if UnalignedSupport() || address<0> == '0' then
5289         if (UnalignedSupport() || BitIsClear (address, 0))
5290         {
5291             // MemU[address,2] = R[t]<15:0>;
5292             uint32_t Rt = ReadCoreReg (t, &success);
5293             if (!success)
5294                 return false;
5295 
5296             EmulateInstruction::Context context;
5297             context.type = eContextRegisterStore;
5298             RegisterInfo base_reg;
5299             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5300             RegisterInfo offset_reg;
5301             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5302             RegisterInfo data_reg;
5303             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5304             context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
5305 
5306             if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2))
5307                 return false;
5308         }
5309         else // Can only occur before ARMv7
5310         {
5311             // MemU[address,2] = bits(16) UNKNOWN;
5312         }
5313 
5314         // if wback then R[n] = offset_addr;
5315         if (wback)
5316         {
5317             context.type = eContextAdjustBaseRegister;
5318             context.SetAddress (offset_addr);
5319             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5320                 return false;
5321         }
5322     }
5323 
5324     return true;
5325 }
5326 
5327 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value,
5328 // and writes the result to the destination register.  It can optionally update the condition flags
5329 // based on the result.
5330 bool
5331 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding)
5332 {
5333 #if 0
5334     // ARM pseudo code...
5335     if ConditionPassed() then
5336         EncodingSpecificOperations();
5337         (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5338         if d == 15 then         // Can only occur for ARM encoding
5339             ALUWritePC(result); // setflags is always FALSE here
5340         else
5341             R[d] = result;
5342             if setflags then
5343                 APSR.N = result<31>;
5344                 APSR.Z = IsZeroBit(result);
5345                 APSR.C = carry;
5346                 APSR.V = overflow;
5347 #endif
5348 
5349     bool success = false;
5350 
5351     if (ConditionPassed(opcode))
5352     {
5353         uint32_t Rd, Rn;
5354         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
5355         bool setflags;
5356         switch (encoding)
5357         {
5358         case eEncodingT1:
5359             Rd = Bits32(opcode, 11, 8);
5360             Rn = Bits32(opcode, 19, 16);
5361             setflags = BitIsSet(opcode, 20);
5362             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5363             if (BadReg(Rd) || BadReg(Rn))
5364                 return false;
5365             break;
5366         case eEncodingA1:
5367             Rd = Bits32(opcode, 15, 12);
5368             Rn = Bits32(opcode, 19, 16);
5369             setflags = BitIsSet(opcode, 20);
5370             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5371 
5372             if (Rd == 15 && setflags)
5373                 return EmulateSUBSPcLrEtc (opcode, encoding);
5374             break;
5375         default:
5376             return false;
5377         }
5378 
5379         // Read the first operand.
5380         int32_t val1 = ReadCoreReg(Rn, &success);
5381         if (!success)
5382             return false;
5383 
5384         AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5385 
5386         EmulateInstruction::Context context;
5387         context.type = EmulateInstruction::eContextImmediate;
5388         context.SetNoArgs ();
5389 
5390         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5391             return false;
5392     }
5393     return true;
5394 }
5395 
5396 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted
5397 // register value, and writes the result to the destination register.  It can optionally update the
5398 // condition flags based on the result.
5399 bool
5400 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding)
5401 {
5402 #if 0
5403     // ARM pseudo code...
5404     if ConditionPassed() then
5405         EncodingSpecificOperations();
5406         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5407         (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5408         if d == 15 then         // Can only occur for ARM encoding
5409             ALUWritePC(result); // setflags is always FALSE here
5410         else
5411             R[d] = result;
5412             if setflags then
5413                 APSR.N = result<31>;
5414                 APSR.Z = IsZeroBit(result);
5415                 APSR.C = carry;
5416                 APSR.V = overflow;
5417 #endif
5418 
5419     bool success = false;
5420 
5421     if (ConditionPassed(opcode))
5422     {
5423         uint32_t Rd, Rn, Rm;
5424         ARM_ShifterType shift_t;
5425         uint32_t shift_n; // the shift applied to the value read from Rm
5426         bool setflags;
5427         switch (encoding)
5428         {
5429         case eEncodingT1:
5430             Rd = Rn = Bits32(opcode, 2, 0);
5431             Rm = Bits32(opcode, 5, 3);
5432             setflags = !InITBlock();
5433             shift_t = SRType_LSL;
5434             shift_n = 0;
5435             break;
5436         case eEncodingT2:
5437             Rd = Bits32(opcode, 11, 8);
5438             Rn = Bits32(opcode, 19, 16);
5439             Rm = Bits32(opcode, 3, 0);
5440             setflags = BitIsSet(opcode, 20);
5441             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5442             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5443                 return false;
5444             break;
5445         case eEncodingA1:
5446             Rd = Bits32(opcode, 15, 12);
5447             Rn = Bits32(opcode, 19, 16);
5448             Rm = Bits32(opcode, 3, 0);
5449             setflags = BitIsSet(opcode, 20);
5450             shift_n = DecodeImmShiftARM(opcode, shift_t);
5451 
5452             if (Rd == 15 && setflags)
5453                 return EmulateSUBSPcLrEtc (opcode, encoding);
5454             break;
5455         default:
5456             return false;
5457         }
5458 
5459         // Read the first operand.
5460         int32_t val1 = ReadCoreReg(Rn, &success);
5461         if (!success)
5462             return false;
5463 
5464         // Read the second operand.
5465         int32_t val2 = ReadCoreReg(Rm, &success);
5466         if (!success)
5467             return false;
5468 
5469         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5470         if (!success)
5471             return false;
5472         AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5473 
5474         EmulateInstruction::Context context;
5475         context.type = EmulateInstruction::eContextImmediate;
5476         context.SetNoArgs ();
5477 
5478         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5479             return false;
5480     }
5481     return true;
5482 }
5483 
5484 // This instruction adds an immediate value to the PC value to form a PC-relative address,
5485 // and writes the result to the destination register.
5486 bool
5487 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding)
5488 {
5489 #if 0
5490     // ARM pseudo code...
5491     if ConditionPassed() then
5492         EncodingSpecificOperations();
5493         result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5494         if d == 15 then         // Can only occur for ARM encodings
5495             ALUWritePC(result);
5496         else
5497             R[d] = result;
5498 #endif
5499 
5500     bool success = false;
5501 
5502     if (ConditionPassed(opcode))
5503     {
5504         uint32_t Rd;
5505         uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5506         bool add;
5507         switch (encoding)
5508         {
5509         case eEncodingT1:
5510             Rd = Bits32(opcode, 10, 8);
5511             imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5512             add = true;
5513             break;
5514         case eEncodingT2:
5515         case eEncodingT3:
5516             Rd = Bits32(opcode, 11, 8);
5517             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5518             add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5519             if (BadReg(Rd))
5520                 return false;
5521             break;
5522         case eEncodingA1:
5523         case eEncodingA2:
5524             Rd = Bits32(opcode, 15, 12);
5525             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5526             add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5527             break;
5528         default:
5529             return false;
5530         }
5531 
5532         // Read the PC value.
5533         uint32_t pc = ReadCoreReg(PC_REG, &success);
5534         if (!success)
5535             return false;
5536 
5537         uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5538 
5539         EmulateInstruction::Context context;
5540         context.type = EmulateInstruction::eContextImmediate;
5541         context.SetNoArgs ();
5542 
5543         if (!WriteCoreReg(context, result, Rd))
5544             return false;
5545     }
5546     return true;
5547 }
5548 
5549 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result
5550 // to the destination register.  It can optionally update the condition flags based on the result.
5551 bool
5552 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding)
5553 {
5554 #if 0
5555     // ARM pseudo code...
5556     if ConditionPassed() then
5557         EncodingSpecificOperations();
5558         result = R[n] AND imm32;
5559         if d == 15 then         // Can only occur for ARM encoding
5560             ALUWritePC(result); // setflags is always FALSE here
5561         else
5562             R[d] = result;
5563             if setflags then
5564                 APSR.N = result<31>;
5565                 APSR.Z = IsZeroBit(result);
5566                 APSR.C = carry;
5567                 // APSR.V unchanged
5568 #endif
5569 
5570     bool success = false;
5571 
5572     if (ConditionPassed(opcode))
5573     {
5574         uint32_t Rd, Rn;
5575         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
5576         bool setflags;
5577         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5578         switch (encoding)
5579         {
5580         case eEncodingT1:
5581             Rd = Bits32(opcode, 11, 8);
5582             Rn = Bits32(opcode, 19, 16);
5583             setflags = BitIsSet(opcode, 20);
5584             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5585             // if Rd == '1111' && S == '1' then SEE TST (immediate);
5586             if (Rd == 15 && setflags)
5587                 return EmulateTSTImm(opcode, eEncodingT1);
5588             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
5589                 return false;
5590             break;
5591         case eEncodingA1:
5592             Rd = Bits32(opcode, 15, 12);
5593             Rn = Bits32(opcode, 19, 16);
5594             setflags = BitIsSet(opcode, 20);
5595             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5596 
5597             if (Rd == 15 && setflags)
5598                 return EmulateSUBSPcLrEtc (opcode, encoding);
5599             break;
5600         default:
5601             return false;
5602         }
5603 
5604         // Read the first operand.
5605         uint32_t val1 = ReadCoreReg(Rn, &success);
5606         if (!success)
5607             return false;
5608 
5609         uint32_t result = val1 & imm32;
5610 
5611         EmulateInstruction::Context context;
5612         context.type = EmulateInstruction::eContextImmediate;
5613         context.SetNoArgs ();
5614 
5615         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5616             return false;
5617     }
5618     return true;
5619 }
5620 
5621 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value,
5622 // and writes the result to the destination register.  It can optionally update the condition flags
5623 // based on the result.
5624 bool
5625 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding)
5626 {
5627 #if 0
5628     // ARM pseudo code...
5629     if ConditionPassed() then
5630         EncodingSpecificOperations();
5631         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5632         result = R[n] AND shifted;
5633         if d == 15 then         // Can only occur for ARM encoding
5634             ALUWritePC(result); // setflags is always FALSE here
5635         else
5636             R[d] = result;
5637             if setflags then
5638                 APSR.N = result<31>;
5639                 APSR.Z = IsZeroBit(result);
5640                 APSR.C = carry;
5641                 // APSR.V unchanged
5642 #endif
5643 
5644     bool success = false;
5645 
5646     if (ConditionPassed(opcode))
5647     {
5648         uint32_t Rd, Rn, Rm;
5649         ARM_ShifterType shift_t;
5650         uint32_t shift_n; // the shift applied to the value read from Rm
5651         bool setflags;
5652         uint32_t carry;
5653         switch (encoding)
5654         {
5655         case eEncodingT1:
5656             Rd = Rn = Bits32(opcode, 2, 0);
5657             Rm = Bits32(opcode, 5, 3);
5658             setflags = !InITBlock();
5659             shift_t = SRType_LSL;
5660             shift_n = 0;
5661             break;
5662         case eEncodingT2:
5663             Rd = Bits32(opcode, 11, 8);
5664             Rn = Bits32(opcode, 19, 16);
5665             Rm = Bits32(opcode, 3, 0);
5666             setflags = BitIsSet(opcode, 20);
5667             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5668             // if Rd == '1111' && S == '1' then SEE TST (register);
5669             if (Rd == 15 && setflags)
5670                 return EmulateTSTReg(opcode, eEncodingT2);
5671             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
5672                 return false;
5673             break;
5674         case eEncodingA1:
5675             Rd = Bits32(opcode, 15, 12);
5676             Rn = Bits32(opcode, 19, 16);
5677             Rm = Bits32(opcode, 3, 0);
5678             setflags = BitIsSet(opcode, 20);
5679             shift_n = DecodeImmShiftARM(opcode, shift_t);
5680 
5681             if (Rd == 15 && setflags)
5682                 return EmulateSUBSPcLrEtc (opcode, encoding);
5683             break;
5684         default:
5685             return false;
5686         }
5687 
5688         // Read the first operand.
5689         uint32_t val1 = ReadCoreReg(Rn, &success);
5690         if (!success)
5691             return false;
5692 
5693         // Read the second operand.
5694         uint32_t val2 = ReadCoreReg(Rm, &success);
5695         if (!success)
5696             return false;
5697 
5698         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5699         if (!success)
5700             return false;
5701         uint32_t result = val1 & shifted;
5702 
5703         EmulateInstruction::Context context;
5704         context.type = EmulateInstruction::eContextImmediate;
5705         context.SetNoArgs ();
5706 
5707         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5708             return false;
5709     }
5710     return true;
5711 }
5712 
5713 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an
5714 // immediate value, and writes the result to the destination register.  It can optionally update the
5715 // condition flags based on the result.
5716 bool
5717 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding)
5718 {
5719 #if 0
5720     // ARM pseudo code...
5721     if ConditionPassed() then
5722         EncodingSpecificOperations();
5723         result = R[n] AND NOT(imm32);
5724         if d == 15 then         // Can only occur for ARM encoding
5725             ALUWritePC(result); // setflags is always FALSE here
5726         else
5727             R[d] = result;
5728             if setflags then
5729                 APSR.N = result<31>;
5730                 APSR.Z = IsZeroBit(result);
5731                 APSR.C = carry;
5732                 // APSR.V unchanged
5733 #endif
5734 
5735     bool success = false;
5736 
5737     if (ConditionPassed(opcode))
5738     {
5739         uint32_t Rd, Rn;
5740         uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn
5741         bool setflags;
5742         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5743         switch (encoding)
5744         {
5745         case eEncodingT1:
5746             Rd = Bits32(opcode, 11, 8);
5747             Rn = Bits32(opcode, 19, 16);
5748             setflags = BitIsSet(opcode, 20);
5749             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5750             if (BadReg(Rd) || BadReg(Rn))
5751                 return false;
5752             break;
5753         case eEncodingA1:
5754             Rd = Bits32(opcode, 15, 12);
5755             Rn = Bits32(opcode, 19, 16);
5756             setflags = BitIsSet(opcode, 20);
5757             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5758 
5759             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5760             if (Rd == 15 && setflags)
5761                 return EmulateSUBSPcLrEtc (opcode, encoding);
5762             break;
5763         default:
5764             return false;
5765         }
5766 
5767         // Read the first operand.
5768         uint32_t val1 = ReadCoreReg(Rn, &success);
5769         if (!success)
5770             return false;
5771 
5772         uint32_t result = val1 & ~imm32;
5773 
5774         EmulateInstruction::Context context;
5775         context.type = EmulateInstruction::eContextImmediate;
5776         context.SetNoArgs ();
5777 
5778         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5779             return false;
5780     }
5781     return true;
5782 }
5783 
5784 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an
5785 // optionally-shifted register value, and writes the result to the destination register.
5786 // It can optionally update the condition flags based on the result.
5787 bool
5788 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding)
5789 {
5790 #if 0
5791     // ARM pseudo code...
5792     if ConditionPassed() then
5793         EncodingSpecificOperations();
5794         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5795         result = R[n] AND NOT(shifted);
5796         if d == 15 then         // Can only occur for ARM encoding
5797             ALUWritePC(result); // setflags is always FALSE here
5798         else
5799             R[d] = result;
5800             if setflags then
5801                 APSR.N = result<31>;
5802                 APSR.Z = IsZeroBit(result);
5803                 APSR.C = carry;
5804                 // APSR.V unchanged
5805 #endif
5806 
5807     bool success = false;
5808 
5809     if (ConditionPassed(opcode))
5810     {
5811         uint32_t Rd, Rn, Rm;
5812         ARM_ShifterType shift_t;
5813         uint32_t shift_n; // the shift applied to the value read from Rm
5814         bool setflags;
5815         uint32_t carry;
5816         switch (encoding)
5817         {
5818         case eEncodingT1:
5819             Rd = Rn = Bits32(opcode, 2, 0);
5820             Rm = Bits32(opcode, 5, 3);
5821             setflags = !InITBlock();
5822             shift_t = SRType_LSL;
5823             shift_n = 0;
5824             break;
5825         case eEncodingT2:
5826             Rd = Bits32(opcode, 11, 8);
5827             Rn = Bits32(opcode, 19, 16);
5828             Rm = Bits32(opcode, 3, 0);
5829             setflags = BitIsSet(opcode, 20);
5830             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5831             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5832                 return false;
5833             break;
5834         case eEncodingA1:
5835             Rd = Bits32(opcode, 15, 12);
5836             Rn = Bits32(opcode, 19, 16);
5837             Rm = Bits32(opcode, 3, 0);
5838             setflags = BitIsSet(opcode, 20);
5839             shift_n = DecodeImmShiftARM(opcode, shift_t);
5840 
5841             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5842             if (Rd == 15 && setflags)
5843                 return EmulateSUBSPcLrEtc (opcode, encoding);
5844             break;
5845         default:
5846             return false;
5847         }
5848 
5849         // Read the first operand.
5850         uint32_t val1 = ReadCoreReg(Rn, &success);
5851         if (!success)
5852             return false;
5853 
5854         // Read the second operand.
5855         uint32_t val2 = ReadCoreReg(Rm, &success);
5856         if (!success)
5857             return false;
5858 
5859         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5860         if (!success)
5861             return false;
5862         uint32_t result = val1 & ~shifted;
5863 
5864         EmulateInstruction::Context context;
5865         context.type = EmulateInstruction::eContextImmediate;
5866         context.SetNoArgs ();
5867 
5868         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5869             return false;
5870     }
5871     return true;
5872 }
5873 
5874 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
5875 // from memory, and writes it to a register.  It can use offset, post-indexed, or pre-indexed addressing.
5876 bool
5877 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding)
5878 {
5879 #if 0
5880     if ConditionPassed() then
5881         EncodingSpecificOperations();
5882         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5883         address = if index then offset_addr else R[n];
5884         data = MemU[address,4];
5885         if wback then R[n] = offset_addr;
5886         if t == 15 then
5887             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5888         elsif UnalignedSupport() || address<1:0> = '00' then
5889             R[t] = data;
5890         else // Can only apply before ARMv7
5891             R[t] = ROR(data, 8*UInt(address<1:0>));
5892 #endif
5893 
5894     bool success = false;
5895 
5896     if (ConditionPassed(opcode))
5897     {
5898         const uint32_t addr_byte_size = GetAddressByteSize();
5899 
5900         uint32_t t;
5901         uint32_t n;
5902         uint32_t imm32;
5903         bool index;
5904         bool add;
5905         bool wback;
5906 
5907         switch (encoding)
5908         {
5909             case eEncodingA1:
5910                 // if Rn == '1111' then SEE LDR (literal);
5911                 // if P == '0' && W == '1' then SEE LDRT;
5912                 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP;
5913                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5914                 t = Bits32 (opcode, 15, 12);
5915                 n = Bits32 (opcode, 19, 16);
5916                 imm32 = Bits32 (opcode, 11, 0);
5917 
5918                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5919                 index = BitIsSet (opcode, 24);
5920                 add = BitIsSet (opcode, 23);
5921                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5922 
5923                 // if wback && n == t then UNPREDICTABLE;
5924                 if (wback && (n == t))
5925                     return false;
5926 
5927                 break;
5928 
5929             default:
5930                 return false;
5931         }
5932 
5933         addr_t address;
5934         addr_t offset_addr;
5935         addr_t base_address = ReadCoreReg (n, &success);
5936         if (!success)
5937             return false;
5938 
5939         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5940         if (add)
5941             offset_addr = base_address + imm32;
5942         else
5943             offset_addr = base_address - imm32;
5944 
5945         // address = if index then offset_addr else R[n];
5946         if (index)
5947             address = offset_addr;
5948         else
5949             address = base_address;
5950 
5951         // data = MemU[address,4];
5952 
5953         RegisterInfo base_reg;
5954         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5955 
5956         EmulateInstruction::Context context;
5957         context.type = eContextRegisterLoad;
5958         context.SetRegisterPlusOffset (base_reg, address - base_address);
5959 
5960         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5961         if (!success)
5962             return false;
5963 
5964         // if wback then R[n] = offset_addr;
5965         if (wback)
5966         {
5967             context.type = eContextAdjustBaseRegister;
5968             context.SetAddress (offset_addr);
5969             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5970                 return false;
5971         }
5972 
5973         // if t == 15 then
5974         if (t == 15)
5975         {
5976             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5977             if (BitIsClear (address, 1) && BitIsClear (address, 0))
5978             {
5979                 // LoadWritePC (data);
5980                 context.type = eContextRegisterLoad;
5981                 context.SetRegisterPlusOffset (base_reg, address - base_address);
5982                 LoadWritePC (context, data);
5983             }
5984             else
5985                   return false;
5986         }
5987         // elsif UnalignedSupport() || address<1:0> = '00' then
5988         else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5989         {
5990             // R[t] = data;
5991             context.type = eContextRegisterLoad;
5992             context.SetRegisterPlusOffset (base_reg, address - base_address);
5993             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5994                 return false;
5995         }
5996         // else // Can only apply before ARMv7
5997         else
5998         {
5999             // R[t] = ROR(data, 8*UInt(address<1:0>));
6000             data = ROR (data, Bits32 (address, 1, 0), &success);
6001             if (!success)
6002                 return false;
6003             context.type = eContextRegisterLoad;
6004             context.SetImmediate (data);
6005             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6006                 return false;
6007         }
6008 
6009     }
6010     return true;
6011 }
6012 
6013 // LDR (register) calculates an address from a base register value and an offset register value, loads a word
6014 // from memory, and writes it to a register.  The offset register value can optionally be shifted.
6015 bool
6016 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding)
6017 {
6018 #if 0
6019     if ConditionPassed() then
6020         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6021         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6022         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6023         address = if index then offset_addr else R[n];
6024         data = MemU[address,4];
6025         if wback then R[n] = offset_addr;
6026         if t == 15 then
6027             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6028         elsif UnalignedSupport() || address<1:0> = '00' then
6029             R[t] = data;
6030         else // Can only apply before ARMv7
6031             if CurrentInstrSet() == InstrSet_ARM then
6032                 R[t] = ROR(data, 8*UInt(address<1:0>));
6033             else
6034                 R[t] = bits(32) UNKNOWN;
6035 #endif
6036 
6037     bool success = false;
6038 
6039     if (ConditionPassed(opcode))
6040     {
6041         const uint32_t addr_byte_size = GetAddressByteSize();
6042 
6043         uint32_t t;
6044         uint32_t n;
6045         uint32_t m;
6046         bool index;
6047         bool add;
6048         bool wback;
6049         ARM_ShifterType shift_t;
6050         uint32_t shift_n;
6051 
6052         switch (encoding)
6053         {
6054             case eEncodingT1:
6055                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6056                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6057                 t = Bits32 (opcode, 2, 0);
6058                 n = Bits32 (opcode, 5, 3);
6059                 m = Bits32 (opcode, 8, 6);
6060 
6061                 // index = TRUE; add = TRUE; wback = FALSE;
6062                 index = true;
6063                 add = true;
6064                 wback = false;
6065 
6066                 // (shift_t, shift_n) = (SRType_LSL, 0);
6067                 shift_t = SRType_LSL;
6068                 shift_n = 0;
6069 
6070                 break;
6071 
6072             case eEncodingT2:
6073                 // if Rn == '1111' then SEE LDR (literal);
6074                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6075                 t = Bits32 (opcode, 15, 12);
6076                 n = Bits32 (opcode, 19, 16);
6077                 m = Bits32 (opcode, 3, 0);
6078 
6079                 // index = TRUE; add = TRUE; wback = FALSE;
6080                 index = true;
6081                 add = true;
6082                 wback = false;
6083 
6084                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6085                 shift_t = SRType_LSL;
6086                 shift_n = Bits32 (opcode, 5, 4);
6087 
6088                 // if BadReg(m) then UNPREDICTABLE;
6089                 if (BadReg (m))
6090                     return false;
6091 
6092                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
6093                 if ((t == 15) && InITBlock() && !LastInITBlock())
6094                     return false;
6095 
6096                 break;
6097 
6098             case eEncodingA1:
6099             {
6100                 // if P == '0' && W == '1' then SEE LDRT;
6101                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6102                 t = Bits32 (opcode, 15, 12);
6103                 n = Bits32 (opcode, 19, 16);
6104                 m = Bits32 (opcode, 3, 0);
6105 
6106                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6107                 index = BitIsSet (opcode, 24);
6108                 add = BitIsSet (opcode, 23);
6109                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6110 
6111                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6112                 uint32_t type = Bits32 (opcode, 6, 5);
6113                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6114                 shift_n = DecodeImmShift (type, imm5, shift_t);
6115 
6116                 // if m == 15 then UNPREDICTABLE;
6117                 if (m == 15)
6118                     return false;
6119 
6120                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6121                 if (wback && ((n == 15) || (n == t)))
6122                     return false;
6123             }
6124                 break;
6125 
6126 
6127             default:
6128                 return false;
6129         }
6130 
6131         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6132         if (!success)
6133             return false;
6134 
6135         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6136         if (!success)
6137             return false;
6138 
6139         addr_t offset_addr;
6140         addr_t address;
6141 
6142         // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an application level alias for the CPSR".
6143         addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success);
6144         if (!success)
6145             return false;
6146 
6147         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6148         if (add)
6149             offset_addr = Rn + offset;
6150         else
6151             offset_addr = Rn - offset;
6152 
6153         // address = if index then offset_addr else R[n];
6154             if (index)
6155                 address = offset_addr;
6156             else
6157                 address = Rn;
6158 
6159         // data = MemU[address,4];
6160         RegisterInfo base_reg;
6161         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6162 
6163         EmulateInstruction::Context context;
6164         context.type = eContextRegisterLoad;
6165         context.SetRegisterPlusOffset (base_reg, address - Rn);
6166 
6167         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
6168         if (!success)
6169             return false;
6170 
6171         // if wback then R[n] = offset_addr;
6172         if (wback)
6173         {
6174             context.type = eContextAdjustBaseRegister;
6175             context.SetAddress (offset_addr);
6176             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6177                 return false;
6178         }
6179 
6180         // if t == 15 then
6181         if (t == 15)
6182         {
6183             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6184             if (BitIsClear (address, 1) && BitIsClear (address, 0))
6185             {
6186                 context.type = eContextRegisterLoad;
6187                 context.SetRegisterPlusOffset (base_reg, address - Rn);
6188                 LoadWritePC (context, data);
6189             }
6190             else
6191                 return false;
6192         }
6193         // elsif UnalignedSupport() || address<1:0> = '00' then
6194         else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
6195         {
6196             // R[t] = data;
6197             context.type = eContextRegisterLoad;
6198             context.SetRegisterPlusOffset (base_reg, address - Rn);
6199             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6200                 return false;
6201         }
6202         else // Can only apply before ARMv7
6203         {
6204             // if CurrentInstrSet() == InstrSet_ARM then
6205             if (CurrentInstrSet () == eModeARM)
6206             {
6207                 // R[t] = ROR(data, 8*UInt(address<1:0>));
6208                 data = ROR (data, Bits32 (address, 1, 0), &success);
6209                 if (!success)
6210                     return false;
6211                 context.type = eContextRegisterLoad;
6212                 context.SetImmediate (data);
6213                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6214                     return false;
6215             }
6216             else
6217             {
6218                 // R[t] = bits(32) UNKNOWN;
6219                 WriteBits32Unknown (t);
6220             }
6221         }
6222     }
6223     return true;
6224 }
6225 
6226 // LDRB (immediate, Thumb)
6227 bool
6228 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6229 {
6230 #if 0
6231     if ConditionPassed() then
6232         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6233         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6234         address = if index then offset_addr else R[n];
6235         R[t] = ZeroExtend(MemU[address,1], 32);
6236         if wback then R[n] = offset_addr;
6237 #endif
6238 
6239     bool success = false;
6240 
6241     if (ConditionPassed(opcode))
6242     {
6243         uint32_t t;
6244         uint32_t n;
6245         uint32_t imm32;
6246         bool index;
6247         bool add;
6248         bool wback;
6249 
6250         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6251         switch (encoding)
6252         {
6253             case eEncodingT1:
6254                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6255                 t = Bits32 (opcode, 2, 0);
6256                 n = Bits32 (opcode, 5, 3);
6257                 imm32 = Bits32 (opcode, 10, 6);
6258 
6259                 // index = TRUE; add = TRUE; wback = FALSE;
6260                 index = true;
6261                 add = true;
6262                 wback= false;
6263 
6264                 break;
6265 
6266             case eEncodingT2:
6267                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6268                 t = Bits32 (opcode, 15, 12);
6269                 n = Bits32 (opcode, 19, 16);
6270                 imm32 = Bits32 (opcode, 11, 0);
6271 
6272                 // index = TRUE; add = TRUE; wback = FALSE;
6273                 index = true;
6274                 add = true;
6275                 wback = false;
6276 
6277                 // if Rt == '1111' then SEE PLD;
6278                 if (t == 15)
6279                     return false; // PLD is not implemented yet
6280 
6281                 // if Rn == '1111' then SEE LDRB (literal);
6282                 if (n == 15)
6283                     return EmulateLDRBLiteral(opcode, eEncodingT1);
6284 
6285                 // if t == 13 then UNPREDICTABLE;
6286                 if (t == 13)
6287                     return false;
6288 
6289                 break;
6290 
6291             case eEncodingT3:
6292                 // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6293                 // if P == '0' && W == '0' then UNDEFINED;
6294                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6295                     return false;
6296 
6297                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6298                 t = Bits32 (opcode, 15, 12);
6299                 n = Bits32 (opcode, 19, 16);
6300                 imm32 = Bits32 (opcode, 7, 0);
6301 
6302                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6303                 index = BitIsSet (opcode, 10);
6304                 add = BitIsSet (opcode, 9);
6305                 wback = BitIsSet (opcode, 8);
6306 
6307                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6308                 if (t == 15)
6309                     return false; // PLD is not implemented yet
6310 
6311                 // if Rn == '1111' then SEE LDRB (literal);
6312                 if (n == 15)
6313                     return EmulateLDRBLiteral(opcode, eEncodingT1);
6314 
6315                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6316                 if (BadReg (t) || (wback && (n == t)))
6317                     return false;
6318 
6319                 break;
6320 
6321             default:
6322                 return false;
6323         }
6324 
6325         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6326         if (!success)
6327             return false;
6328 
6329         addr_t address;
6330         addr_t offset_addr;
6331 
6332         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6333         if (add)
6334             offset_addr = Rn + imm32;
6335         else
6336             offset_addr = Rn - imm32;
6337 
6338         // address = if index then offset_addr else R[n];
6339         if (index)
6340             address = offset_addr;
6341         else
6342             address = Rn;
6343 
6344         // R[t] = ZeroExtend(MemU[address,1], 32);
6345         RegisterInfo base_reg;
6346         RegisterInfo data_reg;
6347         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6348         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6349 
6350         EmulateInstruction::Context context;
6351         context.type = eContextRegisterLoad;
6352         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
6353 
6354         uint64_t data = MemURead (context, address, 1, 0, &success);
6355         if (!success)
6356             return false;
6357 
6358         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6359             return false;
6360 
6361         // if wback then R[n] = offset_addr;
6362         if (wback)
6363         {
6364             context.type = eContextAdjustBaseRegister;
6365             context.SetAddress (offset_addr);
6366             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6367                 return false;
6368         }
6369     }
6370     return true;
6371 }
6372 
6373 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6374 // zero-extends it to form a 32-bit word and writes it to a register.
6375 bool
6376 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6377 {
6378 #if 0
6379     if ConditionPassed() then
6380         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6381         base = Align(PC,4);
6382         address = if add then (base + imm32) else (base - imm32);
6383         R[t] = ZeroExtend(MemU[address,1], 32);
6384 #endif
6385 
6386     bool success = false;
6387 
6388     if (ConditionPassed(opcode))
6389     {
6390         uint32_t t;
6391         uint32_t imm32;
6392         bool add;
6393         switch (encoding)
6394         {
6395             case eEncodingT1:
6396                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6397                 t = Bits32 (opcode, 15, 12);
6398                 imm32 = Bits32 (opcode, 11, 0);
6399                 add = BitIsSet (opcode, 23);
6400 
6401                 // if Rt == '1111' then SEE PLD;
6402                 if (t == 15)
6403                     return false; // PLD is not implemented yet
6404 
6405                 // if t == 13 then UNPREDICTABLE;
6406                 if (t == 13)
6407                     return false;
6408 
6409                 break;
6410 
6411             case eEncodingA1:
6412                 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6413                 t = Bits32 (opcode, 15, 12);
6414                 imm32 = Bits32 (opcode, 11, 0);
6415                 add = BitIsSet (opcode, 23);
6416 
6417                 // if t == 15 then UNPREDICTABLE;
6418                 if (t == 15)
6419                     return false;
6420                 break;
6421 
6422             default:
6423                 return false;
6424         }
6425 
6426         // base = Align(PC,4);
6427         uint32_t pc_val = ReadCoreReg (PC_REG, &success);
6428         if (!success)
6429             return false;
6430 
6431         uint32_t base = AlignPC (pc_val);
6432 
6433         addr_t address;
6434         // address = if add then (base + imm32) else (base - imm32);
6435         if (add)
6436             address = base + imm32;
6437         else
6438             address = base - imm32;
6439 
6440         // R[t] = ZeroExtend(MemU[address,1], 32);
6441         EmulateInstruction::Context context;
6442         context.type = eContextRelativeBranchImmediate;
6443         context.SetImmediate (address - base);
6444 
6445         uint64_t data = MemURead (context, address, 1, 0, &success);
6446         if (!success)
6447             return false;
6448 
6449         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6450             return false;
6451     }
6452     return true;
6453 }
6454 
6455 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from
6456 // memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6457 // optionally be shifted.
6458 bool
6459 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding)
6460 {
6461 #if 0
6462     if ConditionPassed() then
6463         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6464         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6465         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6466         address = if index then offset_addr else R[n];
6467         R[t] = ZeroExtend(MemU[address,1],32);
6468         if wback then R[n] = offset_addr;
6469 #endif
6470 
6471     bool success = false;
6472 
6473     if (ConditionPassed(opcode))
6474     {
6475         uint32_t t;
6476         uint32_t n;
6477         uint32_t m;
6478         bool index;
6479         bool add;
6480         bool wback;
6481         ARM_ShifterType shift_t;
6482         uint32_t shift_n;
6483 
6484         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6485         switch (encoding)
6486         {
6487             case eEncodingT1:
6488                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6489                 t = Bits32 (opcode, 2, 0);
6490                 n = Bits32 (opcode, 5, 3);
6491                 m = Bits32 (opcode, 8, 6);
6492 
6493                 // index = TRUE; add = TRUE; wback = FALSE;
6494                 index = true;
6495                 add = true;
6496                 wback = false;
6497 
6498                 // (shift_t, shift_n) = (SRType_LSL, 0);
6499                 shift_t = SRType_LSL;
6500                 shift_n = 0;
6501                 break;
6502 
6503             case eEncodingT2:
6504                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6505                 t = Bits32 (opcode, 15, 12);
6506                 n = Bits32 (opcode, 19, 16);
6507                 m = Bits32 (opcode, 3, 0);
6508 
6509                 // index = TRUE; add = TRUE; wback = FALSE;
6510                 index = true;
6511                 add = true;
6512                 wback = false;
6513 
6514                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6515                 shift_t = SRType_LSL;
6516                 shift_n = Bits32 (opcode, 5, 4);
6517 
6518                 // if Rt == '1111' then SEE PLD;
6519                 if (t == 15)
6520                     return false; // PLD is not implemented yet
6521 
6522                 // if Rn == '1111' then SEE LDRB (literal);
6523                 if (n == 15)
6524                     return EmulateLDRBLiteral(opcode, eEncodingT1);
6525 
6526                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6527                 if ((t == 13) || BadReg (m))
6528                     return false;
6529                 break;
6530 
6531             case eEncodingA1:
6532             {
6533                 // if P == '0' && W == '1' then SEE LDRBT;
6534                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6535                 t = Bits32 (opcode, 15, 12);
6536                 n = Bits32 (opcode, 19, 16);
6537                 m = Bits32 (opcode, 3, 0);
6538 
6539                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6540                 index = BitIsSet (opcode, 24);
6541                 add = BitIsSet (opcode, 23);
6542                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6543 
6544                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6545                 uint32_t type = Bits32 (opcode, 6, 5);
6546                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6547                 shift_n = DecodeImmShift (type, imm5, shift_t);
6548 
6549                 // if t == 15 || m == 15 then UNPREDICTABLE;
6550                 if ((t == 15) || (m == 15))
6551                     return false;
6552 
6553                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6554                 if (wback && ((n == 15) || (n == t)))
6555                     return false;
6556             }
6557                 break;
6558 
6559             default:
6560                 return false;
6561         }
6562 
6563         addr_t offset_addr;
6564         addr_t address;
6565 
6566         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6567         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6568         if (!success)
6569             return false;
6570 
6571         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6572         if (!success)
6573             return false;
6574 
6575         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6576         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6577         if (!success)
6578             return false;
6579 
6580         if (add)
6581             offset_addr = Rn + offset;
6582         else
6583             offset_addr = Rn - offset;
6584 
6585         // address = if index then offset_addr else R[n];
6586         if (index)
6587             address = offset_addr;
6588         else
6589             address = Rn;
6590 
6591         // R[t] = ZeroExtend(MemU[address,1],32);
6592         RegisterInfo base_reg;
6593         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6594 
6595         EmulateInstruction::Context context;
6596         context.type = eContextRegisterLoad;
6597         context.SetRegisterPlusOffset (base_reg, address - Rn);
6598 
6599         uint64_t data = MemURead (context, address, 1, 0, &success);
6600         if (!success)
6601             return false;
6602 
6603         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6604             return false;
6605 
6606         // if wback then R[n] = offset_addr;
6607         if (wback)
6608         {
6609             context.type = eContextAdjustBaseRegister;
6610             context.SetAddress (offset_addr);
6611             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6612                 return false;
6613         }
6614     }
6615     return true;
6616 }
6617 
6618 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a
6619 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register.  It can use offset,
6620 // post-indexed, or pre-indexed addressing.
6621 bool
6622 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding)
6623 {
6624 #if 0
6625     if ConditionPassed() then
6626         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6627         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6628         address = if index then offset_addr else R[n];
6629         data = MemU[address,2];
6630         if wback then R[n] = offset_addr;
6631         if UnalignedSupport() || address<0> = '0' then
6632             R[t] = ZeroExtend(data, 32);
6633         else // Can only apply before ARMv7
6634             R[t] = bits(32) UNKNOWN;
6635 #endif
6636 
6637 
6638     bool success = false;
6639 
6640     if (ConditionPassed(opcode))
6641     {
6642         uint32_t t;
6643         uint32_t n;
6644         uint32_t imm32;
6645         bool index;
6646         bool add;
6647         bool wback;
6648 
6649         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6650         switch (encoding)
6651         {
6652             case eEncodingT1:
6653                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
6654                 t = Bits32 (opcode, 2, 0);
6655                 n = Bits32 (opcode, 5, 3);
6656                 imm32 = Bits32 (opcode, 10, 6) << 1;
6657 
6658                 // index = TRUE; add = TRUE; wback = FALSE;
6659                 index = true;
6660                 add = true;
6661                 wback = false;
6662 
6663                 break;
6664 
6665             case eEncodingT2:
6666                 // if Rt == '1111' then SEE "Unallocated memory hints";
6667                 // if Rn == '1111' then SEE LDRH (literal);
6668                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6669                 t = Bits32 (opcode, 15, 12);
6670                 n = Bits32 (opcode, 19, 16);
6671                 imm32 = Bits32 (opcode, 11, 0);
6672 
6673                 // index = TRUE; add = TRUE; wback = FALSE;
6674                 index = true;
6675                 add = true;
6676                 wback = false;
6677 
6678                 // if t == 13 then UNPREDICTABLE;
6679                 if (t == 13)
6680                     return false;
6681                 break;
6682 
6683             case eEncodingT3:
6684                 // if Rn == '1111' then SEE LDRH (literal);
6685                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
6686                 // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
6687                 // if P == '0' && W == '0' then UNDEFINED;
6688                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6689                     return false;
6690 
6691                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6692                 t = Bits32 (opcode, 15, 12);
6693                 n = Bits32 (opcode, 19, 16);
6694                 imm32 = Bits32 (opcode, 7, 0);
6695 
6696                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6697                 index = BitIsSet (opcode, 10);
6698                 add = BitIsSet (opcode, 9);
6699                 wback = BitIsSet (opcode, 8);
6700 
6701                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6702                 if (BadReg (t) || (wback && (n == t)))
6703                     return false;
6704                 break;
6705 
6706             default:
6707                 return false;
6708         }
6709 
6710         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6711         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6712         if (!success)
6713             return false;
6714 
6715         addr_t offset_addr;
6716         addr_t address;
6717 
6718         if (add)
6719             offset_addr = Rn + imm32;
6720         else
6721             offset_addr = Rn - imm32;
6722 
6723         // address = if index then offset_addr else R[n];
6724         if (index)
6725             address = offset_addr;
6726         else
6727             address = Rn;
6728 
6729         // data = MemU[address,2];
6730         RegisterInfo base_reg;
6731         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6732 
6733         EmulateInstruction::Context context;
6734         context.type = eContextRegisterLoad;
6735         context.SetRegisterPlusOffset (base_reg, address - Rn);
6736 
6737         uint64_t data = MemURead (context, address, 2, 0, &success);
6738         if (!success)
6739             return false;
6740 
6741         // if wback then R[n] = offset_addr;
6742         if (wback)
6743         {
6744             context.type = eContextAdjustBaseRegister;
6745             context.SetAddress (offset_addr);
6746             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6747                 return false;
6748         }
6749 
6750         // if UnalignedSupport() || address<0> = '0' then
6751         if (UnalignedSupport () || BitIsClear (address, 0))
6752         {
6753             // R[t] = ZeroExtend(data, 32);
6754             context.type = eContextRegisterLoad;
6755             context.SetRegisterPlusOffset (base_reg, address - Rn);
6756             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6757                 return false;
6758         }
6759         else // Can only apply before ARMv7
6760         {
6761             // R[t] = bits(32) UNKNOWN;
6762             WriteBits32Unknown (t);
6763         }
6764     }
6765     return true;
6766 }
6767 
6768 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory,
6769 // zero-extends it to form a 32-bit word, and writes it to a register.
6770 bool
6771 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding)
6772 {
6773 #if 0
6774     if ConditionPassed() then
6775         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6776         base = Align(PC,4);
6777         address = if add then (base + imm32) else (base - imm32);
6778         data = MemU[address,2];
6779         if UnalignedSupport() || address<0> = '0' then
6780             R[t] = ZeroExtend(data, 32);
6781         else // Can only apply before ARMv7
6782             R[t] = bits(32) UNKNOWN;
6783 #endif
6784 
6785     bool success = false;
6786 
6787     if (ConditionPassed(opcode))
6788     {
6789         uint32_t t;
6790         uint32_t imm32;
6791         bool add;
6792 
6793         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6794         switch (encoding)
6795         {
6796             case eEncodingT1:
6797                 // if Rt == '1111' then SEE "Unallocated memory hints";
6798                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6799                 t = Bits32 (opcode, 15, 12);
6800                 imm32 = Bits32 (opcode, 11, 0);
6801                 add = BitIsSet (opcode, 23);
6802 
6803                 // if t == 13 then UNPREDICTABLE;
6804                 if (t == 13)
6805                     return false;
6806 
6807                 break;
6808 
6809             case eEncodingA1:
6810             {
6811                 uint32_t imm4H = Bits32 (opcode, 11, 8);
6812                 uint32_t imm4L = Bits32 (opcode, 3, 0);
6813 
6814                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6815                 t = Bits32 (opcode, 15, 12);
6816                 imm32 = (imm4H << 4) | imm4L;
6817                 add = BitIsSet (opcode, 23);
6818 
6819                 // if t == 15 then UNPREDICTABLE;
6820                 if (t == 15)
6821                     return false;
6822                 break;
6823             }
6824 
6825             default:
6826                 return false;
6827         }
6828 
6829         // base = Align(PC,4);
6830         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6831         if (!success)
6832             return false;
6833 
6834         addr_t base = AlignPC (pc_value);
6835         addr_t address;
6836 
6837         // address = if add then (base + imm32) else (base - imm32);
6838         if (add)
6839             address = base + imm32;
6840         else
6841             address = base - imm32;
6842 
6843         // data = MemU[address,2];
6844         RegisterInfo base_reg;
6845         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
6846 
6847         EmulateInstruction::Context context;
6848         context.type = eContextRegisterLoad;
6849         context.SetRegisterPlusOffset (base_reg, address - base);
6850 
6851         uint64_t data = MemURead (context, address, 2, 0, &success);
6852         if (!success)
6853             return false;
6854 
6855 
6856         // if UnalignedSupport() || address<0> = '0' then
6857         if (UnalignedSupport () || BitIsClear (address, 0))
6858         {
6859             // R[t] = ZeroExtend(data, 32);
6860             context.type = eContextRegisterLoad;
6861             context.SetRegisterPlusOffset (base_reg, address - base);
6862             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6863                 return false;
6864 
6865         }
6866         else // Can only apply before ARMv7
6867         {
6868             // R[t] = bits(32) UNKNOWN;
6869             WriteBits32Unknown (t);
6870         }
6871     }
6872     return true;
6873 }
6874 
6875 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword
6876 // from memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6877 // be shifted left by 0, 1, 2, or 3 bits.
6878 bool
6879 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding)
6880 {
6881 #if 0
6882     if ConditionPassed() then
6883         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6884         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6885         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6886         address = if index then offset_addr else R[n];
6887         data = MemU[address,2];
6888         if wback then R[n] = offset_addr;
6889         if UnalignedSupport() || address<0> = '0' then
6890             R[t] = ZeroExtend(data, 32);
6891         else // Can only apply before ARMv7
6892             R[t] = bits(32) UNKNOWN;
6893 #endif
6894 
6895     bool success = false;
6896 
6897     if (ConditionPassed(opcode))
6898     {
6899         uint32_t t;
6900         uint32_t n;
6901         uint32_t m;
6902         bool index;
6903         bool add;
6904         bool wback;
6905         ARM_ShifterType shift_t;
6906         uint32_t shift_n;
6907 
6908         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6909         switch (encoding)
6910         {
6911             case eEncodingT1:
6912                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6913                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6914                 t = Bits32 (opcode, 2, 0);
6915                 n = Bits32 (opcode, 5, 3);
6916                 m = Bits32 (opcode, 8, 6);
6917 
6918                 // index = TRUE; add = TRUE; wback = FALSE;
6919                 index = true;
6920                 add = true;
6921                 wback = false;
6922 
6923                 // (shift_t, shift_n) = (SRType_LSL, 0);
6924                 shift_t = SRType_LSL;
6925                 shift_n = 0;
6926 
6927                 break;
6928 
6929             case eEncodingT2:
6930                 // if Rn == '1111' then SEE LDRH (literal);
6931                 // if Rt == '1111' then SEE "Unallocated memory hints";
6932                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6933                 t = Bits32 (opcode, 15, 12);
6934                 n = Bits32 (opcode, 19, 16);
6935                 m = Bits32 (opcode, 3, 0);
6936 
6937                 // index = TRUE; add = TRUE; wback = FALSE;
6938                 index = true;
6939                 add = true;
6940                 wback = false;
6941 
6942                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6943                 shift_t = SRType_LSL;
6944                 shift_n = Bits32 (opcode, 5, 4);
6945 
6946                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6947                 if ((t == 13) || BadReg (m))
6948                     return false;
6949                 break;
6950 
6951             case eEncodingA1:
6952                 // if P == '0' && W == '1' then SEE LDRHT;
6953                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6954                 t = Bits32 (opcode, 15, 12);
6955                 n = Bits32 (opcode, 19, 16);
6956                 m = Bits32 (opcode, 3, 0);
6957 
6958                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6959                 index = BitIsSet (opcode, 24);
6960                 add = BitIsSet (opcode, 23);
6961                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6962 
6963                 // (shift_t, shift_n) = (SRType_LSL, 0);
6964                 shift_t = SRType_LSL;
6965                 shift_n = 0;
6966 
6967                 // if t == 15 || m == 15 then UNPREDICTABLE;
6968                 if ((t == 15) || (m == 15))
6969                     return false;
6970 
6971                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6972                 if (wback && ((n == 15) || (n == t)))
6973                     return false;
6974 
6975                 break;
6976 
6977             default:
6978                 return false;
6979         }
6980 
6981         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6982 
6983         uint64_t Rm  = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6984         if (!success)
6985             return false;
6986 
6987         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6988         if (!success)
6989             return false;
6990 
6991         addr_t offset_addr;
6992         addr_t address;
6993 
6994         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6995         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6996         if (!success)
6997             return false;
6998 
6999         if (add)
7000             offset_addr = Rn + offset;
7001         else
7002             offset_addr = Rn - offset;
7003 
7004         // address = if index then offset_addr else R[n];
7005         if (index)
7006             address = offset_addr;
7007         else
7008             address = Rn;
7009 
7010         // data = MemU[address,2];
7011         RegisterInfo base_reg;
7012         RegisterInfo offset_reg;
7013         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7014         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7015 
7016         EmulateInstruction::Context context;
7017         context.type = eContextRegisterLoad;
7018         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7019         uint64_t data = MemURead (context, address, 2, 0, &success);
7020         if (!success)
7021             return false;
7022 
7023         // if wback then R[n] = offset_addr;
7024         if (wback)
7025         {
7026             context.type = eContextAdjustBaseRegister;
7027             context.SetAddress (offset_addr);
7028             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7029                 return false;
7030         }
7031 
7032         // if UnalignedSupport() || address<0> = '0' then
7033         if (UnalignedSupport() || BitIsClear (address, 0))
7034         {
7035             // R[t] = ZeroExtend(data, 32);
7036             context.type = eContextRegisterLoad;
7037             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7038             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
7039                 return false;
7040         }
7041         else // Can only apply before ARMv7
7042         {
7043             // R[t] = bits(32) UNKNOWN;
7044             WriteBits32Unknown (t);
7045         }
7046     }
7047     return true;
7048 }
7049 
7050 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from
7051 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed,
7052 // or pre-indexed addressing.
7053 bool
7054 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding)
7055 {
7056 #if 0
7057     if ConditionPassed() then
7058         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7059         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7060         address = if index then offset_addr else R[n];
7061         R[t] = SignExtend(MemU[address,1], 32);
7062         if wback then R[n] = offset_addr;
7063 #endif
7064 
7065     bool success = false;
7066 
7067     if (ConditionPassed(opcode))
7068     {
7069         uint32_t t;
7070         uint32_t n;
7071         uint32_t imm32;
7072         bool index;
7073         bool add;
7074         bool wback;
7075 
7076         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7077         switch (encoding)
7078         {
7079             case eEncodingT1:
7080                 // if Rt == '1111' then SEE PLI;
7081                 // if Rn == '1111' then SEE LDRSB (literal);
7082                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7083                 t = Bits32 (opcode, 15, 12);
7084                 n = Bits32 (opcode, 19, 16);
7085                 imm32 = Bits32 (opcode, 11, 0);
7086 
7087                 // index = TRUE; add = TRUE; wback = FALSE;
7088                 index = true;
7089                 add = true;
7090                 wback = false;
7091 
7092                 // if t == 13 then UNPREDICTABLE;
7093                 if (t == 13)
7094                     return false;
7095 
7096                 break;
7097 
7098             case eEncodingT2:
7099                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
7100                 // if Rn == '1111' then SEE LDRSB (literal);
7101                 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
7102                 // if P == '0' && W == '0' then UNDEFINED;
7103                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7104                     return false;
7105 
7106                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7107                 t = Bits32 (opcode, 15, 12);
7108                 n = Bits32 (opcode, 19, 16);
7109                 imm32 = Bits32 (opcode, 7, 0);
7110 
7111                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7112                 index = BitIsSet (opcode, 10);
7113                 add = BitIsSet (opcode, 9);
7114                 wback = BitIsSet (opcode, 8);
7115 
7116                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7117                   if (((t == 13) || ((t == 15)
7118                                      && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8))))
7119                       || (wback && (n == t)))
7120                     return false;
7121 
7122                 break;
7123 
7124             case eEncodingA1:
7125             {
7126                 // if Rn == '1111' then SEE LDRSB (literal);
7127                 // if P == '0' && W == '1' then SEE LDRSBT;
7128                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7129                 t = Bits32 (opcode, 15, 12);
7130                 n = Bits32 (opcode, 19, 16);
7131 
7132                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7133                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7134                 imm32 = (imm4H << 4) | imm4L;
7135 
7136                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7137                 index = BitIsSet (opcode, 24);
7138                 add = BitIsSet (opcode, 23);
7139                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
7140 
7141                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7142                 if ((t == 15) || (wback && (n == t)))
7143                     return false;
7144 
7145                 break;
7146             }
7147 
7148             default:
7149                 return false;
7150         }
7151 
7152         uint64_t Rn = ReadCoreReg (n, &success);
7153         if (!success)
7154             return false;
7155 
7156         addr_t offset_addr;
7157         addr_t address;
7158 
7159         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7160         if (add)
7161             offset_addr = Rn + imm32;
7162         else
7163             offset_addr = Rn - imm32;
7164 
7165         // address = if index then offset_addr else R[n];
7166         if (index)
7167             address = offset_addr;
7168         else
7169             address = Rn;
7170 
7171         // R[t] = SignExtend(MemU[address,1], 32);
7172         RegisterInfo base_reg;
7173         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7174 
7175         EmulateInstruction::Context context;
7176         context.type = eContextRegisterLoad;
7177         context.SetRegisterPlusOffset (base_reg, address - Rn);
7178 
7179         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7180         if (!success)
7181             return false;
7182 
7183         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7184         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7185             return false;
7186 
7187         // if wback then R[n] = offset_addr;
7188         if (wback)
7189         {
7190             context.type = eContextAdjustBaseRegister;
7191             context.SetAddress (offset_addr);
7192             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7193                 return false;
7194         }
7195     }
7196 
7197     return true;
7198 }
7199 
7200 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
7201 // sign-extends it to form a 32-bit word, and writes tit to a register.
7202 bool
7203 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding)
7204 {
7205 #if 0
7206     if ConditionPassed() then
7207         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7208         base = Align(PC,4);
7209         address = if add then (base + imm32) else (base - imm32);
7210         R[t] = SignExtend(MemU[address,1], 32);
7211 #endif
7212 
7213     bool success = false;
7214 
7215     if (ConditionPassed(opcode))
7216     {
7217         uint32_t t;
7218         uint32_t imm32;
7219         bool add;
7220 
7221         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7222         switch (encoding)
7223         {
7224             case eEncodingT1:
7225                 // if Rt == '1111' then SEE PLI;
7226                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7227                 t = Bits32 (opcode, 15, 12);
7228                 imm32 = Bits32 (opcode, 11, 0);
7229                 add = BitIsSet (opcode, 23);
7230 
7231                 // if t == 13 then UNPREDICTABLE;
7232                 if (t == 13)
7233                     return false;
7234 
7235                 break;
7236 
7237             case eEncodingA1:
7238             {
7239                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7240                 t = Bits32 (opcode, 15, 12);
7241                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7242                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7243                 imm32 = (imm4H << 4) | imm4L;
7244                 add = BitIsSet (opcode, 23);
7245 
7246                 // if t == 15 then UNPREDICTABLE;
7247                 if (t == 15)
7248                     return false;
7249 
7250                 break;
7251             }
7252 
7253             default:
7254                 return false;
7255         }
7256 
7257         // base = Align(PC,4);
7258         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7259         if (!success)
7260             return false;
7261         uint64_t base = AlignPC (pc_value);
7262 
7263         // address = if add then (base + imm32) else (base - imm32);
7264         addr_t address;
7265         if (add)
7266             address = base + imm32;
7267         else
7268             address = base - imm32;
7269 
7270         // R[t] = SignExtend(MemU[address,1], 32);
7271         RegisterInfo base_reg;
7272         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7273 
7274         EmulateInstruction::Context context;
7275         context.type = eContextRegisterLoad;
7276         context.SetRegisterPlusOffset (base_reg, address - base);
7277 
7278         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7279         if (!success)
7280             return false;
7281 
7282         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7283         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7284             return false;
7285     }
7286     return true;
7287 }
7288 
7289 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from
7290 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7291 // shifted left by 0, 1, 2, or 3 bits.
7292 bool
7293 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding)
7294 {
7295 #if 0
7296     if ConditionPassed() then
7297         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7298         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7299         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7300         address = if index then offset_addr else R[n];
7301         R[t] = SignExtend(MemU[address,1], 32);
7302         if wback then R[n] = offset_addr;
7303 #endif
7304 
7305     bool success = false;
7306 
7307     if (ConditionPassed(opcode))
7308     {
7309         uint32_t t;
7310         uint32_t n;
7311         uint32_t m;
7312         bool index;
7313         bool add;
7314         bool wback;
7315         ARM_ShifterType shift_t;
7316         uint32_t shift_n;
7317 
7318         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7319         switch (encoding)
7320         {
7321             case eEncodingT1:
7322                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7323                 t = Bits32 (opcode, 2, 0);
7324                 n = Bits32 (opcode, 5, 3);
7325                 m = Bits32 (opcode, 8, 6);
7326 
7327                 // index = TRUE; add = TRUE; wback = FALSE;
7328                 index = true;
7329                 add = true;
7330                 wback = false;
7331 
7332                 // (shift_t, shift_n) = (SRType_LSL, 0);
7333                 shift_t = SRType_LSL;
7334                 shift_n = 0;
7335 
7336                 break;
7337 
7338             case eEncodingT2:
7339                 // if Rt == '1111' then SEE PLI;
7340                 // if Rn == '1111' then SEE LDRSB (literal);
7341                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7342                 t = Bits32 (opcode, 15, 12);
7343                 n = Bits32 (opcode, 19, 16);
7344                 m = Bits32 (opcode, 3, 0);
7345 
7346                 // index = TRUE; add = TRUE; wback = FALSE;
7347                 index = true;
7348                 add = true;
7349                 wback = false;
7350 
7351                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7352                 shift_t = SRType_LSL;
7353                 shift_n = Bits32 (opcode, 5, 4);
7354 
7355                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7356                 if ((t == 13) || BadReg (m))
7357                     return false;
7358                 break;
7359 
7360             case eEncodingA1:
7361                 // if P == '0' && W == '1' then SEE LDRSBT;
7362                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7363                 t = Bits32 (opcode, 15, 12);
7364                 n = Bits32 (opcode, 19, 16);
7365                 m = Bits32 (opcode, 3, 0);
7366 
7367                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7368                 index = BitIsSet (opcode, 24);
7369                 add = BitIsSet (opcode, 23);
7370                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7371 
7372                 // (shift_t, shift_n) = (SRType_LSL, 0);
7373                 shift_t = SRType_LSL;
7374                 shift_n = 0;
7375 
7376                 // if t == 15 || m == 15 then UNPREDICTABLE;
7377                 if ((t == 15) || (m == 15))
7378                     return false;
7379 
7380                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7381                 if (wback && ((n == 15) || (n == t)))
7382                     return false;
7383                 break;
7384 
7385             default:
7386                 return false;
7387         }
7388 
7389         uint64_t Rm =  ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7390         if (!success)
7391             return false;
7392 
7393         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7394         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7395         if (!success)
7396             return false;
7397 
7398         addr_t offset_addr;
7399         addr_t address;
7400 
7401         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7402         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7403         if (!success)
7404             return false;
7405 
7406         if (add)
7407             offset_addr = Rn + offset;
7408         else
7409             offset_addr = Rn - offset;
7410 
7411         // address = if index then offset_addr else R[n];
7412         if (index)
7413             address = offset_addr;
7414         else
7415             address = Rn;
7416 
7417         // R[t] = SignExtend(MemU[address,1], 32);
7418         RegisterInfo base_reg;
7419         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7420         RegisterInfo offset_reg;
7421         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7422 
7423         EmulateInstruction::Context context;
7424         context.type = eContextRegisterLoad;
7425         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7426 
7427         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7428         if (!success)
7429             return false;
7430 
7431         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7432         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7433             return false;
7434 
7435         // if wback then R[n] = offset_addr;
7436         if (wback)
7437         {
7438             context.type = eContextAdjustBaseRegister;
7439             context.SetAddress (offset_addr);
7440             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7441                 return false;
7442         }
7443     }
7444     return true;
7445 }
7446 
7447 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from
7448 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed, or
7449 // pre-indexed addressing.
7450 bool
7451 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding)
7452 {
7453 #if 0
7454     if ConditionPassed() then
7455         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7456         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7457         address = if index then offset_addr else R[n];
7458         data = MemU[address,2];
7459         if wback then R[n] = offset_addr;
7460         if UnalignedSupport() || address<0> = '0' then
7461             R[t] = SignExtend(data, 32);
7462         else // Can only apply before ARMv7
7463             R[t] = bits(32) UNKNOWN;
7464 #endif
7465 
7466     bool success = false;
7467 
7468     if (ConditionPassed(opcode))
7469     {
7470         uint32_t t;
7471         uint32_t n;
7472         uint32_t imm32;
7473         bool index;
7474         bool add;
7475         bool wback;
7476 
7477         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7478         switch (encoding)
7479         {
7480             case eEncodingT1:
7481                 // if Rn == '1111' then SEE LDRSH (literal);
7482                 // if Rt == '1111' then SEE "Unallocated memory hints";
7483                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7484                 t = Bits32 (opcode, 15, 12);
7485                 n = Bits32 (opcode, 19, 16);
7486                 imm32 = Bits32 (opcode, 11, 0);
7487 
7488                 // index = TRUE; add = TRUE; wback = FALSE;
7489                 index = true;
7490                 add = true;
7491                 wback = false;
7492 
7493                 // if t == 13 then UNPREDICTABLE;
7494                 if (t == 13)
7495                     return false;
7496 
7497                 break;
7498 
7499             case eEncodingT2:
7500                 // if Rn == '1111' then SEE LDRSH (literal);
7501                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
7502                 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7503                 // if P == '0' && W == '0' then UNDEFINED;
7504                   if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7505                   return false;
7506 
7507                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7508                 t = Bits32 (opcode, 15, 12);
7509                 n = Bits32 (opcode, 19, 16);
7510                 imm32 = Bits32 (opcode, 7, 0);
7511 
7512                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7513                 index = BitIsSet (opcode, 10);
7514                 add = BitIsSet (opcode, 9);
7515                 wback = BitIsSet (opcode, 8);
7516 
7517                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7518                 if (BadReg (t) || (wback && (n == t)))
7519                     return false;
7520 
7521                 break;
7522 
7523             case eEncodingA1:
7524             {
7525                 // if Rn == '1111' then SEE LDRSH (literal);
7526                 // if P == '0' && W == '1' then SEE LDRSHT;
7527                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7528                 t = Bits32 (opcode, 15, 12);
7529                 n = Bits32 (opcode, 19, 16);
7530                 uint32_t imm4H = Bits32 (opcode, 11,8);
7531                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7532                 imm32 = (imm4H << 4) | imm4L;
7533 
7534                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7535                 index = BitIsSet (opcode, 24);
7536                 add = BitIsSet (opcode, 23);
7537                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7538 
7539                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7540                 if ((t == 15) || (wback && (n == t)))
7541                     return false;
7542 
7543                 break;
7544             }
7545 
7546             default:
7547                 return false;
7548         }
7549 
7550         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7551         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7552         if (!success)
7553             return false;
7554 
7555         addr_t offset_addr;
7556         if (add)
7557             offset_addr = Rn + imm32;
7558         else
7559             offset_addr = Rn - imm32;
7560 
7561         // address = if index then offset_addr else R[n];
7562         addr_t address;
7563         if (index)
7564             address = offset_addr;
7565         else
7566             address = Rn;
7567 
7568         // data = MemU[address,2];
7569         RegisterInfo base_reg;
7570         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7571 
7572         EmulateInstruction::Context context;
7573         context.type = eContextRegisterLoad;
7574         context.SetRegisterPlusOffset (base_reg, address - Rn);
7575 
7576         uint64_t data = MemURead (context, address, 2, 0, &success);
7577         if (!success)
7578             return false;
7579 
7580         // if wback then R[n] = offset_addr;
7581         if (wback)
7582         {
7583             context.type = eContextAdjustBaseRegister;
7584             context.SetAddress (offset_addr);
7585             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7586                 return false;
7587         }
7588 
7589         // if UnalignedSupport() || address<0> = '0' then
7590         if (UnalignedSupport() || BitIsClear (address, 0))
7591         {
7592             // R[t] = SignExtend(data, 32);
7593             int64_t signed_data = llvm::SignExtend64<16>(data);
7594             context.type = eContextRegisterLoad;
7595             context.SetRegisterPlusOffset (base_reg, address - Rn);
7596             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7597                 return false;
7598         }
7599         else // Can only apply before ARMv7
7600         {
7601             // R[t] = bits(32) UNKNOWN;
7602             WriteBits32Unknown (t);
7603         }
7604     }
7605     return true;
7606 }
7607 
7608 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory,
7609 // sign-extends it to from a 32-bit word, and writes it to a register.
7610 bool
7611 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding)
7612 {
7613 #if 0
7614     if ConditionPassed() then
7615         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7616         base = Align(PC,4);
7617         address = if add then (base + imm32) else (base - imm32);
7618         data = MemU[address,2];
7619         if UnalignedSupport() || address<0> = '0' then
7620             R[t] = SignExtend(data, 32);
7621         else // Can only apply before ARMv7
7622             R[t] = bits(32) UNKNOWN;
7623 #endif
7624 
7625     bool success = false;
7626 
7627     if (ConditionPassed(opcode))
7628     {
7629         uint32_t t;
7630         uint32_t imm32;
7631         bool add;
7632 
7633         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7634         switch (encoding)
7635         {
7636             case eEncodingT1:
7637                 // if Rt == '1111' then SEE "Unallocated memory hints";
7638                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7639                 t = Bits32  (opcode, 15, 12);
7640                 imm32 = Bits32 (opcode, 11, 0);
7641                 add = BitIsSet (opcode, 23);
7642 
7643                 // if t == 13 then UNPREDICTABLE;
7644                 if (t == 13)
7645                     return false;
7646 
7647                 break;
7648 
7649             case eEncodingA1:
7650             {
7651                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7652                 t = Bits32 (opcode, 15, 12);
7653                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7654                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7655                 imm32 = (imm4H << 4) | imm4L;
7656                 add = BitIsSet (opcode, 23);
7657 
7658                 // if t == 15 then UNPREDICTABLE;
7659                 if (t == 15)
7660                     return false;
7661 
7662                 break;
7663             }
7664             default:
7665                 return false;
7666         }
7667 
7668         // base = Align(PC,4);
7669         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7670         if (!success)
7671             return false;
7672 
7673         uint64_t base = AlignPC (pc_value);
7674 
7675         addr_t address;
7676         // address = if add then (base + imm32) else (base - imm32);
7677         if (add)
7678             address = base + imm32;
7679         else
7680             address = base - imm32;
7681 
7682         // data = MemU[address,2];
7683         RegisterInfo base_reg;
7684         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7685 
7686         EmulateInstruction::Context context;
7687         context.type = eContextRegisterLoad;
7688         context.SetRegisterPlusOffset (base_reg, imm32);
7689 
7690         uint64_t data = MemURead (context, address, 2, 0, &success);
7691         if (!success)
7692             return false;
7693 
7694         // if UnalignedSupport() || address<0> = '0' then
7695         if (UnalignedSupport() || BitIsClear (address, 0))
7696         {
7697             // R[t] = SignExtend(data, 32);
7698             int64_t signed_data = llvm::SignExtend64<16>(data);
7699             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7700                 return false;
7701         }
7702         else // Can only apply before ARMv7
7703         {
7704             // R[t] = bits(32) UNKNOWN;
7705             WriteBits32Unknown (t);
7706         }
7707     }
7708     return true;
7709 }
7710 
7711 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword
7712 // from memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7713 // shifted left by 0, 1, 2, or 3 bits.
7714 bool
7715 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding)
7716 {
7717 #if 0
7718     if ConditionPassed() then
7719         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7720         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7721         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7722         address = if index then offset_addr else R[n];
7723         data = MemU[address,2];
7724         if wback then R[n] = offset_addr;
7725         if UnalignedSupport() || address<0> = '0' then
7726             R[t] = SignExtend(data, 32);
7727         else // Can only apply before ARMv7
7728             R[t] = bits(32) UNKNOWN;
7729 #endif
7730 
7731     bool success = false;
7732 
7733     if (ConditionPassed(opcode))
7734     {
7735         uint32_t t;
7736         uint32_t n;
7737         uint32_t m;
7738         bool index;
7739         bool add;
7740         bool wback;
7741         ARM_ShifterType shift_t;
7742         uint32_t shift_n;
7743 
7744         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7745         switch (encoding)
7746         {
7747             case eEncodingT1:
7748                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
7749                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7750                 t = Bits32 (opcode, 2, 0);
7751                 n = Bits32 (opcode, 5, 3);
7752                 m = Bits32 (opcode, 8, 6);
7753 
7754                 // index = TRUE; add = TRUE; wback = FALSE;
7755                 index = true;
7756                 add = true;
7757                 wback = false;
7758 
7759                 // (shift_t, shift_n) = (SRType_LSL, 0);
7760                 shift_t = SRType_LSL;
7761                 shift_n = 0;
7762 
7763                 break;
7764 
7765             case eEncodingT2:
7766                 // if Rn == '1111' then SEE LDRSH (literal);
7767                 // if Rt == '1111' then SEE "Unallocated memory hints";
7768                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7769                 t = Bits32 (opcode, 15, 12);
7770                 n = Bits32 (opcode, 19, 16);
7771                 m = Bits32 (opcode, 3, 0);
7772 
7773                 // index = TRUE; add = TRUE; wback = FALSE;
7774                 index = true;
7775                 add = true;
7776                 wback = false;
7777 
7778                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7779                 shift_t = SRType_LSL;
7780                 shift_n = Bits32 (opcode, 5, 4);
7781 
7782                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7783                 if ((t == 13) || BadReg (m))
7784                     return false;
7785 
7786                 break;
7787 
7788             case eEncodingA1:
7789                 // if P == '0' && W == '1' then SEE LDRSHT;
7790                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7791                 t = Bits32 (opcode, 15, 12);
7792                 n = Bits32 (opcode, 19, 16);
7793                 m = Bits32 (opcode, 3, 0);
7794 
7795                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7796                 index = BitIsSet (opcode, 24);
7797                 add = BitIsSet (opcode, 23);
7798                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7799 
7800                 // (shift_t, shift_n) = (SRType_LSL, 0);
7801                 shift_t = SRType_LSL;
7802                 shift_n = 0;
7803 
7804                 // if t == 15 || m == 15 then UNPREDICTABLE;
7805                 if ((t == 15) || (m == 15))
7806                     return false;
7807 
7808                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7809                 if (wback && ((n == 15) || (n == t)))
7810                     return false;
7811 
7812                 break;
7813 
7814             default:
7815                 return false;
7816         }
7817 
7818         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7819         if (!success)
7820             return false;
7821 
7822         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7823         if (!success)
7824             return false;
7825 
7826         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7827         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7828         if (!success)
7829             return false;
7830 
7831         addr_t offset_addr;
7832         addr_t address;
7833 
7834         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7835         if (add)
7836             offset_addr = Rn + offset;
7837         else
7838             offset_addr = Rn - offset;
7839 
7840         // address = if index then offset_addr else R[n];
7841         if (index)
7842             address = offset_addr;
7843         else
7844             address = Rn;
7845 
7846         // data = MemU[address,2];
7847         RegisterInfo base_reg;
7848         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7849 
7850         RegisterInfo offset_reg;
7851         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7852 
7853         EmulateInstruction::Context context;
7854         context.type = eContextRegisterLoad;
7855         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7856 
7857         uint64_t data = MemURead (context, address, 2, 0, &success);
7858         if (!success)
7859             return false;
7860 
7861         // if wback then R[n] = offset_addr;
7862         if (wback)
7863         {
7864             context.type = eContextAdjustBaseRegister;
7865             context.SetAddress (offset_addr);
7866             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7867                 return false;
7868         }
7869 
7870         // if UnalignedSupport() || address<0> = '0' then
7871         if (UnalignedSupport() || BitIsClear (address, 0))
7872         {
7873             // R[t] = SignExtend(data, 32);
7874             context.type = eContextRegisterLoad;
7875             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7876 
7877             int64_t signed_data = llvm::SignExtend64<16>(data);
7878             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7879                 return false;
7880         }
7881         else // Can only apply before ARMv7
7882         {
7883             // R[t] = bits(32) UNKNOWN;
7884             WriteBits32Unknown (t);
7885         }
7886     }
7887     return true;
7888 }
7889 
7890 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7891 // register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7892 bool
7893 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding)
7894 {
7895 #if 0
7896     if ConditionPassed() then
7897         EncodingSpecificOperations();
7898         rotated = ROR(R[m], rotation);
7899         R[d] = SignExtend(rotated<7:0>, 32);
7900 #endif
7901 
7902     bool success = false;
7903 
7904     if (ConditionPassed(opcode))
7905     {
7906         uint32_t d;
7907         uint32_t m;
7908         uint32_t rotation;
7909 
7910         // EncodingSpecificOperations();
7911         switch (encoding)
7912         {
7913             case eEncodingT1:
7914                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7915                 d = Bits32 (opcode, 2, 0);
7916                 m = Bits32 (opcode, 5, 3);
7917                 rotation = 0;
7918 
7919                 break;
7920 
7921             case eEncodingT2:
7922                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7923                 d = Bits32 (opcode, 11, 8);
7924                 m = Bits32 (opcode, 3, 0);
7925                 rotation = Bits32 (opcode, 5, 4) << 3;
7926 
7927                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7928                 if (BadReg (d) || BadReg (m))
7929                     return false;
7930 
7931                 break;
7932 
7933             case eEncodingA1:
7934                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7935                 d = Bits32 (opcode, 15, 12);
7936                 m = Bits32 (opcode, 3, 0);
7937                 rotation = Bits32 (opcode, 11, 10) << 3;
7938 
7939                 // if d == 15 || m == 15 then UNPREDICTABLE;
7940                 if ((d == 15) || (m == 15))
7941                     return false;
7942 
7943                 break;
7944 
7945             default:
7946                 return false;
7947         }
7948 
7949         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7950         if (!success)
7951             return false;
7952 
7953         // rotated = ROR(R[m], rotation);
7954         uint64_t rotated = ROR (Rm, rotation, &success);
7955         if (!success)
7956             return false;
7957 
7958         // R[d] = SignExtend(rotated<7:0>, 32);
7959         int64_t data = llvm::SignExtend64<8>(rotated);
7960 
7961         RegisterInfo source_reg;
7962         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7963 
7964         EmulateInstruction::Context context;
7965         context.type = eContextRegisterLoad;
7966         context.SetRegister (source_reg);
7967 
7968         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7969             return false;
7970     }
7971     return true;
7972 }
7973 
7974 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7975 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7976 bool
7977 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding)
7978 {
7979 #if 0
7980     if ConditionPassed() then
7981         EncodingSpecificOperations();
7982         rotated = ROR(R[m], rotation);
7983         R[d] = SignExtend(rotated<15:0>, 32);
7984 #endif
7985 
7986     bool success = false;
7987 
7988     if (ConditionPassed(opcode))
7989     {
7990         uint32_t d;
7991         uint32_t m;
7992         uint32_t rotation;
7993 
7994         // EncodingSpecificOperations();
7995         switch (encoding)
7996         {
7997             case eEncodingT1:
7998                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7999                 d = Bits32 (opcode, 2, 0);
8000                 m = Bits32 (opcode, 5, 3);
8001                 rotation = 0;
8002 
8003                 break;
8004 
8005             case eEncodingT2:
8006                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8007                 d = Bits32 (opcode, 11, 8);
8008                 m = Bits32 (opcode, 3, 0);
8009                 rotation = Bits32 (opcode, 5, 4) << 3;
8010 
8011                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8012                 if (BadReg (d) || BadReg (m))
8013                     return false;
8014 
8015                 break;
8016 
8017             case eEncodingA1:
8018                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8019                 d = Bits32 (opcode, 15, 12);
8020                 m = Bits32 (opcode, 3, 0);
8021                 rotation = Bits32 (opcode, 11, 10) << 3;
8022 
8023                 // if d == 15 || m == 15 then UNPREDICTABLE;
8024                 if ((d == 15) || (m == 15))
8025                     return false;
8026 
8027                 break;
8028 
8029             default:
8030                 return false;
8031         }
8032 
8033         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8034         if (!success)
8035             return false;
8036 
8037         // rotated = ROR(R[m], rotation);
8038         uint64_t rotated = ROR (Rm, rotation, &success);
8039         if (!success)
8040             return false;
8041 
8042         // R[d] = SignExtend(rotated<15:0>, 32);
8043         RegisterInfo source_reg;
8044         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8045 
8046         EmulateInstruction::Context context;
8047         context.type = eContextRegisterLoad;
8048         context.SetRegister (source_reg);
8049 
8050         int64_t data = llvm::SignExtend64<16> (rotated);
8051         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
8052             return false;
8053     }
8054 
8055     return true;
8056 }
8057 
8058 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination
8059 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
8060 bool
8061 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding)
8062 {
8063 #if 0
8064     if ConditionPassed() then
8065         EncodingSpecificOperations();
8066         rotated = ROR(R[m], rotation);
8067         R[d] = ZeroExtend(rotated<7:0>, 32);
8068 #endif
8069 
8070     bool success = false;
8071 
8072     if (ConditionPassed(opcode))
8073     {
8074         uint32_t d;
8075         uint32_t m;
8076         uint32_t rotation;
8077 
8078         // EncodingSpecificOperations();
8079         switch (encoding)
8080         {
8081             case eEncodingT1:
8082                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8083                 d = Bits32 (opcode, 2, 0);
8084                 m = Bits32 (opcode, 5, 3);
8085                 rotation = 0;
8086 
8087                 break;
8088 
8089             case eEncodingT2:
8090                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8091                 d = Bits32 (opcode, 11, 8);
8092                 m = Bits32 (opcode, 3, 0);
8093                   rotation = Bits32 (opcode, 5, 4) << 3;
8094 
8095                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8096                 if (BadReg (d) || BadReg (m))
8097                   return false;
8098 
8099                 break;
8100 
8101             case eEncodingA1:
8102                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8103                 d = Bits32 (opcode, 15, 12);
8104                 m = Bits32 (opcode, 3, 0);
8105                 rotation = Bits32 (opcode, 11, 10) << 3;
8106 
8107                 // if d == 15 || m == 15 then UNPREDICTABLE;
8108                 if ((d == 15) || (m == 15))
8109                     return false;
8110 
8111                 break;
8112 
8113             default:
8114                 return false;
8115         }
8116 
8117         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8118         if (!success)
8119             return false;
8120 
8121         // rotated = ROR(R[m], rotation);
8122         uint64_t rotated = ROR (Rm, rotation, &success);
8123         if (!success)
8124             return false;
8125 
8126         // R[d] = ZeroExtend(rotated<7:0>, 32);
8127         RegisterInfo source_reg;
8128         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8129 
8130         EmulateInstruction::Context context;
8131         context.type = eContextRegisterLoad;
8132         context.SetRegister (source_reg);
8133 
8134         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0)))
8135             return false;
8136     }
8137     return true;
8138 }
8139 
8140 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination
8141 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
8142 bool
8143 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding)
8144 {
8145 #if 0
8146     if ConditionPassed() then
8147         EncodingSpecificOperations();
8148         rotated = ROR(R[m], rotation);
8149         R[d] = ZeroExtend(rotated<15:0>, 32);
8150 #endif
8151 
8152     bool success = false;
8153 
8154     if (ConditionPassed(opcode))
8155     {
8156         uint32_t d;
8157         uint32_t m;
8158         uint32_t rotation;
8159 
8160         switch (encoding)
8161         {
8162             case eEncodingT1:
8163                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8164                 d = Bits32 (opcode, 2, 0);
8165                 m = Bits32 (opcode, 5, 3);
8166                 rotation = 0;
8167 
8168                 break;
8169 
8170             case eEncodingT2:
8171                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8172                 d = Bits32 (opcode, 11, 8);
8173                 m = Bits32 (opcode, 3, 0);
8174                 rotation = Bits32 (opcode, 5, 4) << 3;
8175 
8176                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8177                 if (BadReg (d) || BadReg (m))
8178                   return false;
8179 
8180                 break;
8181 
8182             case eEncodingA1:
8183                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8184                 d = Bits32 (opcode, 15, 12);
8185                 m = Bits32 (opcode, 3, 0);
8186                 rotation = Bits32 (opcode, 11, 10) << 3;
8187 
8188                 // if d == 15 || m == 15 then UNPREDICTABLE;
8189                 if ((d == 15) || (m == 15))
8190                     return false;
8191 
8192                 break;
8193 
8194             default:
8195                 return false;
8196         }
8197 
8198         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8199         if (!success)
8200             return false;
8201 
8202         // rotated = ROR(R[m], rotation);
8203         uint64_t rotated = ROR (Rm, rotation, &success);
8204         if (!success)
8205             return false;
8206 
8207         // R[d] = ZeroExtend(rotated<15:0>, 32);
8208         RegisterInfo source_reg;
8209         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8210 
8211         EmulateInstruction::Context context;
8212         context.type = eContextRegisterLoad;
8213         context.SetRegister (source_reg);
8214 
8215         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0)))
8216             return false;
8217     }
8218     return true;
8219 }
8220 
8221 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following
8222 // word respectively.
8223 bool
8224 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding)
8225 {
8226 #if 0
8227     if ConditionPassed() then
8228         EncodingSpecificOperations();
8229         if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8230             UNPREDICTABLE;
8231         else
8232             address = if increment then R[n] else R[n]-8;
8233             if wordhigher then address = address+4;
8234             CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8235             BranchWritePC(MemA[address,4]);
8236             if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8237 #endif
8238 
8239     bool success = false;
8240 
8241     if (ConditionPassed(opcode))
8242     {
8243         uint32_t n;
8244         bool wback;
8245         bool increment;
8246         bool wordhigher;
8247 
8248         // EncodingSpecificOperations();
8249         switch (encoding)
8250         {
8251             case eEncodingT1:
8252                 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE;
8253                 n = Bits32 (opcode, 19, 16);
8254                 wback = BitIsSet (opcode, 21);
8255                 increment = false;
8256                 wordhigher = false;
8257 
8258                 // if n == 15 then UNPREDICTABLE;
8259                 if (n == 15)
8260                     return false;
8261 
8262                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8263                 if (InITBlock() && !LastInITBlock())
8264                     return false;
8265 
8266                 break;
8267 
8268             case eEncodingT2:
8269                 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8270                 n = Bits32 (opcode, 19, 16);
8271                 wback = BitIsSet (opcode, 21);
8272                 increment = true;
8273                 wordhigher = false;
8274 
8275                 // if n == 15 then UNPREDICTABLE;
8276                 if (n == 15)
8277                     return false;
8278 
8279                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8280                 if (InITBlock() && !LastInITBlock())
8281                     return false;
8282 
8283                 break;
8284 
8285             case eEncodingA1:
8286                 // n = UInt(Rn);
8287                 n = Bits32 (opcode, 19, 16);
8288 
8289                 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8290                 wback = BitIsSet (opcode, 21);
8291                 increment = BitIsSet (opcode, 23);
8292                 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23));
8293 
8294                 // if n == 15 then UNPREDICTABLE;
8295                 if (n == 15)
8296                     return false;
8297 
8298                 break;
8299 
8300             default:
8301                 return false;
8302         }
8303 
8304         // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8305         if (!CurrentModeIsPrivileged ())
8306             // UNPREDICTABLE;
8307             return false;
8308         else
8309         {
8310             uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8311             if (!success)
8312                 return false;
8313 
8314             addr_t address;
8315             // address = if increment then R[n] else R[n]-8;
8316             if (increment)
8317                 address = Rn;
8318             else
8319                 address = Rn - 8;
8320 
8321             // if wordhigher then address = address+4;
8322             if (wordhigher)
8323                 address = address + 4;
8324 
8325             // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8326             RegisterInfo base_reg;
8327             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8328 
8329             EmulateInstruction::Context context;
8330             context.type = eContextReturnFromException;
8331             context.SetRegisterPlusOffset (base_reg, address - Rn);
8332 
8333             uint64_t data = MemARead (context, address + 4, 4, 0, &success);
8334             if (!success)
8335                 return false;
8336 
8337             CPSRWriteByInstr (data, 15, true);
8338 
8339             // BranchWritePC(MemA[address,4]);
8340             uint64_t data2 = MemARead (context, address, 4, 0, &success);
8341             if (!success)
8342                 return false;
8343 
8344             BranchWritePC (context, data2);
8345 
8346             // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8347             if (wback)
8348             {
8349                 context.type = eContextAdjustBaseRegister;
8350                 if (increment)
8351                 {
8352                     context.SetOffset (8);
8353                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8))
8354                         return false;
8355                 }
8356                 else
8357                 {
8358                     context.SetOffset (-8);
8359                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8))
8360                         return false;
8361                 }
8362             } // if wback
8363         }
8364     } // if ConditionPassed()
8365     return true;
8366 }
8367 
8368 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
8369 // and writes the result to the destination register.  It can optionally update the condition flags based on
8370 // the result.
8371 bool
8372 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding)
8373 {
8374 #if 0
8375     // ARM pseudo code...
8376     if ConditionPassed() then
8377         EncodingSpecificOperations();
8378         result = R[n] EOR imm32;
8379         if d == 15 then         // Can only occur for ARM encoding
8380             ALUWritePC(result); // setflags is always FALSE here
8381         else
8382             R[d] = result;
8383             if setflags then
8384                 APSR.N = result<31>;
8385                 APSR.Z = IsZeroBit(result);
8386                 APSR.C = carry;
8387                 // APSR.V unchanged
8388 #endif
8389 
8390     bool success = false;
8391 
8392     if (ConditionPassed(opcode))
8393     {
8394         uint32_t Rd, Rn;
8395         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8396         bool setflags;
8397         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8398         switch (encoding)
8399         {
8400         case eEncodingT1:
8401             Rd = Bits32(opcode, 11, 8);
8402             Rn = Bits32(opcode, 19, 16);
8403             setflags = BitIsSet(opcode, 20);
8404             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8405             // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8406             if (Rd == 15 && setflags)
8407                 return EmulateTEQImm (opcode, eEncodingT1);
8408             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8409                 return false;
8410             break;
8411         case eEncodingA1:
8412             Rd = Bits32(opcode, 15, 12);
8413             Rn = Bits32(opcode, 19, 16);
8414             setflags = BitIsSet(opcode, 20);
8415             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8416 
8417             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8418             if (Rd == 15 && setflags)
8419                 return EmulateSUBSPcLrEtc (opcode, encoding);
8420             break;
8421         default:
8422             return false;
8423         }
8424 
8425         // Read the first operand.
8426         uint32_t val1 = ReadCoreReg(Rn, &success);
8427         if (!success)
8428             return false;
8429 
8430         uint32_t result = val1 ^ imm32;
8431 
8432         EmulateInstruction::Context context;
8433         context.type = EmulateInstruction::eContextImmediate;
8434         context.SetNoArgs ();
8435 
8436         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8437             return false;
8438     }
8439     return true;
8440 }
8441 
8442 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an
8443 // optionally-shifted register value, and writes the result to the destination register.
8444 // It can optionally update the condition flags based on the result.
8445 bool
8446 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding)
8447 {
8448 #if 0
8449     // ARM pseudo code...
8450     if ConditionPassed() then
8451         EncodingSpecificOperations();
8452         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8453         result = R[n] EOR shifted;
8454         if d == 15 then         // Can only occur for ARM encoding
8455             ALUWritePC(result); // setflags is always FALSE here
8456         else
8457             R[d] = result;
8458             if setflags then
8459                 APSR.N = result<31>;
8460                 APSR.Z = IsZeroBit(result);
8461                 APSR.C = carry;
8462                 // APSR.V unchanged
8463 #endif
8464 
8465     bool success = false;
8466 
8467     if (ConditionPassed(opcode))
8468     {
8469         uint32_t Rd, Rn, Rm;
8470         ARM_ShifterType shift_t;
8471         uint32_t shift_n; // the shift applied to the value read from Rm
8472         bool setflags;
8473         uint32_t carry;
8474         switch (encoding)
8475         {
8476         case eEncodingT1:
8477             Rd = Rn = Bits32(opcode, 2, 0);
8478             Rm = Bits32(opcode, 5, 3);
8479             setflags = !InITBlock();
8480             shift_t = SRType_LSL;
8481             shift_n = 0;
8482             break;
8483         case eEncodingT2:
8484             Rd = Bits32(opcode, 11, 8);
8485             Rn = Bits32(opcode, 19, 16);
8486             Rm = Bits32(opcode, 3, 0);
8487             setflags = BitIsSet(opcode, 20);
8488             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8489             // if Rd == '1111' && S == '1' then SEE TEQ (register);
8490             if (Rd == 15 && setflags)
8491                 return EmulateTEQReg (opcode, eEncodingT1);
8492             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8493                 return false;
8494             break;
8495         case eEncodingA1:
8496             Rd = Bits32(opcode, 15, 12);
8497             Rn = Bits32(opcode, 19, 16);
8498             Rm = Bits32(opcode, 3, 0);
8499             setflags = BitIsSet(opcode, 20);
8500             shift_n = DecodeImmShiftARM(opcode, shift_t);
8501 
8502             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8503             if (Rd == 15 && setflags)
8504                 return EmulateSUBSPcLrEtc (opcode, encoding);
8505             break;
8506         default:
8507             return false;
8508         }
8509 
8510         // Read the first operand.
8511         uint32_t val1 = ReadCoreReg(Rn, &success);
8512         if (!success)
8513             return false;
8514 
8515         // Read the second operand.
8516         uint32_t val2 = ReadCoreReg(Rm, &success);
8517         if (!success)
8518             return false;
8519 
8520         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8521         if (!success)
8522             return false;
8523         uint32_t result = val1 ^ shifted;
8524 
8525         EmulateInstruction::Context context;
8526         context.type = EmulateInstruction::eContextImmediate;
8527         context.SetNoArgs ();
8528 
8529         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8530             return false;
8531     }
8532     return true;
8533 }
8534 
8535 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and
8536 // writes the result to the destination register.  It can optionally update the condition flags based
8537 // on the result.
8538 bool
8539 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding)
8540 {
8541 #if 0
8542     // ARM pseudo code...
8543     if ConditionPassed() then
8544         EncodingSpecificOperations();
8545         result = R[n] OR imm32;
8546         if d == 15 then         // Can only occur for ARM encoding
8547             ALUWritePC(result); // setflags is always FALSE here
8548         else
8549             R[d] = result;
8550             if setflags then
8551                 APSR.N = result<31>;
8552                 APSR.Z = IsZeroBit(result);
8553                 APSR.C = carry;
8554                 // APSR.V unchanged
8555 #endif
8556 
8557     bool success = false;
8558 
8559     if (ConditionPassed(opcode))
8560     {
8561         uint32_t Rd, Rn;
8562         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8563         bool setflags;
8564         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8565         switch (encoding)
8566         {
8567         case eEncodingT1:
8568             Rd = Bits32(opcode, 11, 8);
8569             Rn = Bits32(opcode, 19, 16);
8570             setflags = BitIsSet(opcode, 20);
8571             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8572             // if Rn == '1111' then SEE MOV (immediate);
8573             if (Rn == 15)
8574                 return EmulateMOVRdImm (opcode, eEncodingT2);
8575             if (BadReg(Rd) || Rn == 13)
8576                 return false;
8577             break;
8578         case eEncodingA1:
8579             Rd = Bits32(opcode, 15, 12);
8580             Rn = Bits32(opcode, 19, 16);
8581             setflags = BitIsSet(opcode, 20);
8582             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8583 
8584             if (Rd == 15 && setflags)
8585                 return EmulateSUBSPcLrEtc (opcode, encoding);
8586             break;
8587         default:
8588             return false;
8589         }
8590 
8591         // Read the first operand.
8592         uint32_t val1 = ReadCoreReg(Rn, &success);
8593         if (!success)
8594             return false;
8595 
8596         uint32_t result = val1 | imm32;
8597 
8598         EmulateInstruction::Context context;
8599         context.type = EmulateInstruction::eContextImmediate;
8600         context.SetNoArgs ();
8601 
8602         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8603             return false;
8604     }
8605     return true;
8606 }
8607 
8608 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register
8609 // value, and writes the result to the destination register.  It can optionally update the condition flags based
8610 // on the result.
8611 bool
8612 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding)
8613 {
8614 #if 0
8615     // ARM pseudo code...
8616     if ConditionPassed() then
8617         EncodingSpecificOperations();
8618         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8619         result = R[n] OR shifted;
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 unchanged
8629 #endif
8630 
8631     bool success = false;
8632 
8633     if (ConditionPassed(opcode))
8634     {
8635         uint32_t Rd, Rn, Rm;
8636         ARM_ShifterType shift_t;
8637         uint32_t shift_n; // the shift applied to the value read from Rm
8638         bool setflags;
8639         uint32_t carry;
8640         switch (encoding)
8641         {
8642         case eEncodingT1:
8643             Rd = Rn = Bits32(opcode, 2, 0);
8644             Rm = Bits32(opcode, 5, 3);
8645             setflags = !InITBlock();
8646             shift_t = SRType_LSL;
8647             shift_n = 0;
8648             break;
8649         case eEncodingT2:
8650             Rd = Bits32(opcode, 11, 8);
8651             Rn = Bits32(opcode, 19, 16);
8652             Rm = Bits32(opcode, 3, 0);
8653             setflags = BitIsSet(opcode, 20);
8654             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8655             // if Rn == '1111' then SEE MOV (register);
8656             if (Rn == 15)
8657                 return EmulateMOVRdRm (opcode, eEncodingT3);
8658             if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
8659                 return false;
8660             break;
8661         case eEncodingA1:
8662             Rd = Bits32(opcode, 15, 12);
8663             Rn = Bits32(opcode, 19, 16);
8664             Rm = Bits32(opcode, 3, 0);
8665             setflags = BitIsSet(opcode, 20);
8666             shift_n = DecodeImmShiftARM(opcode, shift_t);
8667 
8668             if (Rd == 15 && setflags)
8669                 return EmulateSUBSPcLrEtc (opcode, encoding);
8670             break;
8671         default:
8672             return false;
8673         }
8674 
8675         // Read the first operand.
8676         uint32_t val1 = ReadCoreReg(Rn, &success);
8677         if (!success)
8678             return false;
8679 
8680         // Read the second operand.
8681         uint32_t val2 = ReadCoreReg(Rm, &success);
8682         if (!success)
8683             return false;
8684 
8685         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8686         if (!success)
8687             return false;
8688         uint32_t result = val1 | shifted;
8689 
8690         EmulateInstruction::Context context;
8691         context.type = EmulateInstruction::eContextImmediate;
8692         context.SetNoArgs ();
8693 
8694         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8695             return false;
8696     }
8697     return true;
8698 }
8699 
8700 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to
8701 // the destination register. It can optionally update the condition flags based on the result.
8702 bool
8703 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding)
8704 {
8705 #if 0
8706     // ARM pseudo code...
8707     if ConditionPassed() then
8708         EncodingSpecificOperations();
8709         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
8710         if d == 15 then         // Can only occur for ARM encoding
8711             ALUWritePC(result); // setflags is always FALSE here
8712         else
8713             R[d] = result;
8714             if setflags then
8715                 APSR.N = result<31>;
8716                 APSR.Z = IsZeroBit(result);
8717                 APSR.C = carry;
8718                 APSR.V = overflow;
8719 #endif
8720 
8721     bool success = false;
8722 
8723     uint32_t Rd; // the destination register
8724     uint32_t Rn; // the first operand
8725     bool setflags;
8726     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8727     switch (encoding) {
8728     case eEncodingT1:
8729         Rd = Bits32(opcode, 2, 0);
8730         Rn = Bits32(opcode, 5, 3);
8731         setflags = !InITBlock();
8732         imm32 = 0;
8733         break;
8734     case eEncodingT2:
8735         Rd = Bits32(opcode, 11, 8);
8736         Rn = Bits32(opcode, 19, 16);
8737         setflags = BitIsSet(opcode, 20);
8738         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8739         if (BadReg(Rd) || BadReg(Rn))
8740             return false;
8741         break;
8742     case eEncodingA1:
8743         Rd = Bits32(opcode, 15, 12);
8744         Rn = Bits32(opcode, 19, 16);
8745         setflags = BitIsSet(opcode, 20);
8746         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8747 
8748         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8749         if (Rd == 15 && setflags)
8750             return EmulateSUBSPcLrEtc (opcode, encoding);
8751         break;
8752     default:
8753         return false;
8754     }
8755     // Read the register value from the operand register Rn.
8756     uint32_t reg_val = ReadCoreReg(Rn, &success);
8757     if (!success)
8758         return false;
8759 
8760     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
8761 
8762     EmulateInstruction::Context context;
8763     context.type = EmulateInstruction::eContextImmediate;
8764     context.SetNoArgs ();
8765 
8766     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8767         return false;
8768 
8769     return true;
8770 }
8771 
8772 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the
8773 // result to the destination register. It can optionally update the condition flags based on the result.
8774 bool
8775 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding)
8776 {
8777 #if 0
8778     // ARM pseudo code...
8779     if ConditionPassed() then
8780         EncodingSpecificOperations();
8781         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8782         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
8783         if d == 15 then         // Can only occur for ARM encoding
8784             ALUWritePC(result); // setflags is always FALSE here
8785         else
8786             R[d] = result;
8787             if setflags then
8788                 APSR.N = result<31>;
8789                 APSR.Z = IsZeroBit(result);
8790                 APSR.C = carry;
8791                 APSR.V = overflow;
8792 #endif
8793 
8794     bool success = false;
8795 
8796     uint32_t Rd; // the destination register
8797     uint32_t Rn; // the first operand
8798     uint32_t Rm; // the second operand
8799     bool setflags;
8800     ARM_ShifterType shift_t;
8801     uint32_t shift_n; // the shift applied to the value read from Rm
8802     switch (encoding) {
8803     case eEncodingT1:
8804         Rd = Bits32(opcode, 11, 8);
8805         Rn = Bits32(opcode, 19, 16);
8806         Rm = Bits32(opcode, 3, 0);
8807         setflags = BitIsSet(opcode, 20);
8808         shift_n = DecodeImmShiftThumb(opcode, shift_t);
8809         // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
8810         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8811             return false;
8812         break;
8813     case eEncodingA1:
8814         Rd = Bits32(opcode, 15, 12);
8815         Rn = Bits32(opcode, 19, 16);
8816         Rm = Bits32(opcode, 3, 0);
8817         setflags = BitIsSet(opcode, 20);
8818         shift_n = DecodeImmShiftARM(opcode, shift_t);
8819 
8820         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8821         if (Rd == 15 && setflags)
8822             return EmulateSUBSPcLrEtc (opcode, encoding);
8823         break;
8824     default:
8825         return false;
8826     }
8827     // Read the register value from register Rn.
8828     uint32_t val1 = ReadCoreReg(Rn, &success);
8829     if (!success)
8830         return false;
8831 
8832     // Read the register value from register Rm.
8833     uint32_t val2 = ReadCoreReg(Rm, &success);
8834     if (!success)
8835         return false;
8836 
8837     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8838     if (!success)
8839         return false;
8840     AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
8841 
8842     EmulateInstruction::Context context;
8843     context.type = EmulateInstruction::eContextImmediate;
8844     context.SetNoArgs();
8845     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8846         return false;
8847 
8848     return true;
8849 }
8850 
8851 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from
8852 // an immediate value, and writes the result to the destination register. It can optionally update the condition
8853 // flags based on the result.
8854 bool
8855 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding)
8856 {
8857 #if 0
8858     // ARM pseudo code...
8859     if ConditionPassed() then
8860         EncodingSpecificOperations();
8861         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
8862         if d == 15 then
8863             ALUWritePC(result); // setflags is always FALSE here
8864         else
8865             R[d] = result;
8866             if setflags then
8867                 APSR.N = result<31>;
8868                 APSR.Z = IsZeroBit(result);
8869                 APSR.C = carry;
8870                 APSR.V = overflow;
8871 #endif
8872 
8873     bool success = false;
8874 
8875     uint32_t Rd; // the destination register
8876     uint32_t Rn; // the first operand
8877     bool setflags;
8878     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8879     switch (encoding) {
8880     case eEncodingA1:
8881         Rd = Bits32(opcode, 15, 12);
8882         Rn = Bits32(opcode, 19, 16);
8883         setflags = BitIsSet(opcode, 20);
8884         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8885 
8886         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8887         if (Rd == 15 && setflags)
8888             return EmulateSUBSPcLrEtc  (opcode, encoding);
8889         break;
8890     default:
8891         return false;
8892     }
8893     // Read the register value from the operand register Rn.
8894     uint32_t reg_val = ReadCoreReg(Rn, &success);
8895     if (!success)
8896         return false;
8897 
8898     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
8899 
8900     EmulateInstruction::Context context;
8901     context.type = EmulateInstruction::eContextImmediate;
8902     context.SetNoArgs ();
8903 
8904     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8905         return false;
8906 
8907     return true;
8908 }
8909 
8910 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an
8911 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the
8912 // condition flags based on the result.
8913 bool
8914 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding)
8915 {
8916 #if 0
8917     // ARM pseudo code...
8918     if ConditionPassed() then
8919         EncodingSpecificOperations();
8920         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8921         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
8922         if d == 15 then
8923             ALUWritePC(result); // setflags is always FALSE here
8924         else
8925             R[d] = result;
8926             if setflags then
8927                 APSR.N = result<31>;
8928                 APSR.Z = IsZeroBit(result);
8929                 APSR.C = carry;
8930                 APSR.V = overflow;
8931 #endif
8932 
8933     bool success = false;
8934 
8935     uint32_t Rd; // the destination register
8936     uint32_t Rn; // the first operand
8937     uint32_t Rm; // the second operand
8938     bool setflags;
8939     ARM_ShifterType shift_t;
8940     uint32_t shift_n; // the shift applied to the value read from Rm
8941     switch (encoding) {
8942     case eEncodingA1:
8943         Rd = Bits32(opcode, 15, 12);
8944         Rn = Bits32(opcode, 19, 16);
8945         Rm = Bits32(opcode, 3, 0);
8946         setflags = BitIsSet(opcode, 20);
8947         shift_n = DecodeImmShiftARM(opcode, shift_t);
8948 
8949         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8950         if (Rd == 15 && setflags)
8951             return EmulateSUBSPcLrEtc (opcode, encoding);
8952         break;
8953     default:
8954         return false;
8955     }
8956     // Read the register value from register Rn.
8957     uint32_t val1 = ReadCoreReg(Rn, &success);
8958     if (!success)
8959         return false;
8960 
8961     // Read the register value from register Rm.
8962     uint32_t val2 = ReadCoreReg(Rm, &success);
8963     if (!success)
8964         return false;
8965 
8966     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8967     if (!success)
8968         return false;
8969     AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
8970 
8971     EmulateInstruction::Context context;
8972     context.type = EmulateInstruction::eContextImmediate;
8973     context.SetNoArgs();
8974     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8975         return false;
8976 
8977     return true;
8978 }
8979 
8980 // Subtract with Carry (immediate) subtracts an immediate value and the value of
8981 // NOT (Carry flag) from a register value, and writes the result to the destination register.
8982 // It can optionally update the condition flags based on the result.
8983 bool
8984 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding)
8985 {
8986 #if 0
8987     // ARM pseudo code...
8988     if ConditionPassed() then
8989         EncodingSpecificOperations();
8990         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
8991         if d == 15 then         // Can only occur for ARM encoding
8992             ALUWritePC(result); // setflags is always FALSE here
8993         else
8994             R[d] = result;
8995             if setflags then
8996                 APSR.N = result<31>;
8997                 APSR.Z = IsZeroBit(result);
8998                 APSR.C = carry;
8999                 APSR.V = overflow;
9000 #endif
9001 
9002     bool success = false;
9003 
9004     uint32_t Rd; // the destination register
9005     uint32_t Rn; // the first operand
9006     bool setflags;
9007     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
9008     switch (encoding) {
9009     case eEncodingT1:
9010         Rd = Bits32(opcode, 11, 8);
9011         Rn = Bits32(opcode, 19, 16);
9012         setflags = BitIsSet(opcode, 20);
9013         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9014         if (BadReg(Rd) || BadReg(Rn))
9015             return false;
9016         break;
9017     case eEncodingA1:
9018         Rd = Bits32(opcode, 15, 12);
9019         Rn = Bits32(opcode, 19, 16);
9020         setflags = BitIsSet(opcode, 20);
9021         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9022 
9023         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9024         if (Rd == 15 && setflags)
9025             return EmulateSUBSPcLrEtc (opcode, encoding);
9026         break;
9027     default:
9028         return false;
9029     }
9030     // Read the register value from the operand register Rn.
9031     uint32_t reg_val = ReadCoreReg(Rn, &success);
9032     if (!success)
9033         return false;
9034 
9035     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
9036 
9037     EmulateInstruction::Context context;
9038     context.type = EmulateInstruction::eContextImmediate;
9039     context.SetNoArgs ();
9040 
9041     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9042         return false;
9043 
9044     return true;
9045 }
9046 
9047 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of
9048 // NOT (Carry flag) from a register value, and writes the result to the destination register.
9049 // It can optionally update the condition flags based on the result.
9050 bool
9051 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding)
9052 {
9053 #if 0
9054     // ARM pseudo code...
9055     if ConditionPassed() then
9056         EncodingSpecificOperations();
9057         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9058         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
9059         if d == 15 then         // Can only occur for ARM encoding
9060             ALUWritePC(result); // setflags is always FALSE here
9061         else
9062             R[d] = result;
9063             if setflags then
9064                 APSR.N = result<31>;
9065                 APSR.Z = IsZeroBit(result);
9066                 APSR.C = carry;
9067                 APSR.V = overflow;
9068 #endif
9069 
9070     bool success = false;
9071 
9072     uint32_t Rd; // the destination register
9073     uint32_t Rn; // the first operand
9074     uint32_t Rm; // the second operand
9075     bool setflags;
9076     ARM_ShifterType shift_t;
9077     uint32_t shift_n; // the shift applied to the value read from Rm
9078     switch (encoding) {
9079     case eEncodingT1:
9080         Rd = Rn = Bits32(opcode, 2, 0);
9081         Rm = Bits32(opcode, 5, 3);
9082         setflags = !InITBlock();
9083         shift_t = SRType_LSL;
9084         shift_n = 0;
9085         break;
9086     case eEncodingT2:
9087         Rd = Bits32(opcode, 11, 8);
9088         Rn = Bits32(opcode, 19, 16);
9089         Rm = Bits32(opcode, 3, 0);
9090         setflags = BitIsSet(opcode, 20);
9091         shift_n = DecodeImmShiftThumb(opcode, shift_t);
9092         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9093             return false;
9094         break;
9095     case eEncodingA1:
9096         Rd = Bits32(opcode, 15, 12);
9097         Rn = Bits32(opcode, 19, 16);
9098         Rm = Bits32(opcode, 3, 0);
9099         setflags = BitIsSet(opcode, 20);
9100         shift_n = DecodeImmShiftARM(opcode, shift_t);
9101 
9102         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9103         if (Rd == 15 && setflags)
9104             return EmulateSUBSPcLrEtc (opcode, encoding);
9105         break;
9106     default:
9107         return false;
9108     }
9109     // Read the register value from register Rn.
9110     uint32_t val1 = ReadCoreReg(Rn, &success);
9111     if (!success)
9112         return false;
9113 
9114     // Read the register value from register Rm.
9115     uint32_t val2 = ReadCoreReg(Rm, &success);
9116     if (!success)
9117         return false;
9118 
9119     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9120     if (!success)
9121         return false;
9122     AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
9123 
9124     EmulateInstruction::Context context;
9125     context.type = EmulateInstruction::eContextImmediate;
9126     context.SetNoArgs();
9127     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9128         return false;
9129 
9130     return true;
9131 }
9132 
9133 // This instruction subtracts an immediate value from a register value, and writes the result
9134 // to the destination register.  It can optionally update the condition flags based on the result.
9135 bool
9136 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding)
9137 {
9138 #if 0
9139     // ARM pseudo code...
9140     if ConditionPassed() then
9141         EncodingSpecificOperations();
9142         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9143         R[d] = result;
9144         if setflags then
9145             APSR.N = result<31>;
9146             APSR.Z = IsZeroBit(result);
9147             APSR.C = carry;
9148             APSR.V = overflow;
9149 #endif
9150 
9151     bool success = false;
9152 
9153     uint32_t Rd; // the destination register
9154     uint32_t Rn; // the first operand
9155     bool setflags;
9156     uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9157     switch (encoding) {
9158     case eEncodingT1:
9159         Rd = Bits32(opcode, 2, 0);
9160         Rn = Bits32(opcode, 5, 3);
9161         setflags = !InITBlock();
9162         imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9163         break;
9164     case eEncodingT2:
9165         Rd = Rn = Bits32(opcode, 10, 8);
9166         setflags = !InITBlock();
9167         imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9168         break;
9169     case eEncodingT3:
9170         Rd = Bits32(opcode, 11, 8);
9171         Rn = Bits32(opcode, 19, 16);
9172         setflags = BitIsSet(opcode, 20);
9173         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9174 
9175         // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9176         if (Rd == 15 && setflags)
9177             return EmulateCMPImm (opcode, eEncodingT2);
9178 
9179         // if Rn == '1101' then SEE SUB (SP minus immediate);
9180         if (Rn == 13)
9181             return EmulateSUBSPImm (opcode, eEncodingT2);
9182 
9183         // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9184         if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9185             return false;
9186         break;
9187     case eEncodingT4:
9188         Rd = Bits32(opcode, 11, 8);
9189         Rn = Bits32(opcode, 19, 16);
9190         setflags = BitIsSet(opcode, 20);
9191         imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9192 
9193         // if Rn == '1111' then SEE ADR;
9194         if (Rn == 15)
9195             return EmulateADR (opcode, eEncodingT2);
9196 
9197         // if Rn == '1101' then SEE SUB (SP minus immediate);
9198         if (Rn == 13)
9199             return EmulateSUBSPImm (opcode, eEncodingT3);
9200 
9201         if (BadReg(Rd))
9202             return false;
9203         break;
9204     default:
9205         return false;
9206     }
9207     // Read the register value from the operand register Rn.
9208     uint32_t reg_val = ReadCoreReg(Rn, &success);
9209     if (!success)
9210         return false;
9211 
9212     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9213 
9214     EmulateInstruction::Context context;
9215     context.type = EmulateInstruction::eContextImmediate;
9216     context.SetNoArgs ();
9217 
9218     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9219         return false;
9220 
9221     return true;
9222 }
9223 
9224 // This instruction subtracts an immediate value from a register value, and writes the result
9225 // to the destination register.  It can optionally update the condition flags based on the result.
9226 bool
9227 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9228 {
9229 #if 0
9230     // ARM pseudo code...
9231     if ConditionPassed() then
9232         EncodingSpecificOperations();
9233         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9234         if d == 15 then
9235             ALUWritePC(result); // setflags is always FALSE here
9236         else
9237             R[d] = result;
9238             if setflags then
9239                 APSR.N = result<31>;
9240                 APSR.Z = IsZeroBit(result);
9241                 APSR.C = carry;
9242                 APSR.V = overflow;
9243 #endif
9244 
9245     bool success = false;
9246 
9247     if (ConditionPassed(opcode))
9248     {
9249         uint32_t Rd; // the destination register
9250         uint32_t Rn; // the first operand
9251         bool setflags;
9252         uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9253         switch (encoding) {
9254         case eEncodingA1:
9255             Rd = Bits32(opcode, 15, 12);
9256             Rn = Bits32(opcode, 19, 16);
9257             setflags = BitIsSet(opcode, 20);
9258             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9259 
9260             // if Rn == '1111' && S == '0' then SEE ADR;
9261             if (Rn == 15 && !setflags)
9262                 return EmulateADR (opcode, eEncodingA2);
9263 
9264             // if Rn == '1101' then SEE SUB (SP minus immediate);
9265             if (Rn == 13)
9266                 return EmulateSUBSPImm (opcode, eEncodingA1);
9267 
9268             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9269             if (Rd == 15 && setflags)
9270                 return EmulateSUBSPcLrEtc (opcode, encoding);
9271             break;
9272         default:
9273             return false;
9274         }
9275         // Read the register value from the operand register Rn.
9276         uint32_t reg_val = ReadCoreReg(Rn, &success);
9277         if (!success)
9278             return false;
9279 
9280         AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9281 
9282         EmulateInstruction::Context context;
9283         if (Rd == 13)
9284             context.type = EmulateInstruction::eContextAdjustStackPointer;
9285         else
9286             context.type = EmulateInstruction::eContextRegisterPlusOffset;
9287 
9288         RegisterInfo dwarf_reg;
9289         GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
9290         int64_t imm32_signed = imm32;
9291         context.SetRegisterPlusOffset (dwarf_reg, -imm32_signed);
9292 
9293         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9294             return false;
9295     }
9296     return true;
9297 }
9298 
9299 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an
9300 // immediate value.  It updates the condition flags based on the result, and discards the result.
9301 bool
9302 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding)
9303 {
9304 #if 0
9305     // ARM pseudo code...
9306     if ConditionPassed() then
9307         EncodingSpecificOperations();
9308         result = R[n] EOR imm32;
9309         APSR.N = result<31>;
9310         APSR.Z = IsZeroBit(result);
9311         APSR.C = carry;
9312         // APSR.V unchanged
9313 #endif
9314 
9315     bool success = false;
9316 
9317     if (ConditionPassed(opcode))
9318     {
9319         uint32_t Rn;
9320         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9321         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9322         switch (encoding)
9323         {
9324         case eEncodingT1:
9325             Rn = Bits32(opcode, 19, 16);
9326             imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9327             if (BadReg(Rn))
9328                 return false;
9329             break;
9330         case eEncodingA1:
9331             Rn = Bits32(opcode, 19, 16);
9332             imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9333             break;
9334         default:
9335             return false;
9336         }
9337 
9338         // Read the first operand.
9339         uint32_t val1 = ReadCoreReg(Rn, &success);
9340         if (!success)
9341             return false;
9342 
9343         uint32_t result = val1 ^ imm32;
9344 
9345         EmulateInstruction::Context context;
9346         context.type = EmulateInstruction::eContextImmediate;
9347         context.SetNoArgs ();
9348 
9349         if (!WriteFlags(context, result, carry))
9350             return false;
9351     }
9352     return true;
9353 }
9354 
9355 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an
9356 // optionally-shifted register value.  It updates the condition flags based on the result, and discards
9357 // the result.
9358 bool
9359 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding)
9360 {
9361 #if 0
9362     // ARM pseudo code...
9363     if ConditionPassed() then
9364         EncodingSpecificOperations();
9365         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9366         result = R[n] EOR shifted;
9367         APSR.N = result<31>;
9368         APSR.Z = IsZeroBit(result);
9369         APSR.C = carry;
9370         // APSR.V unchanged
9371 #endif
9372 
9373     bool success = false;
9374 
9375     if (ConditionPassed(opcode))
9376     {
9377         uint32_t Rn, Rm;
9378         ARM_ShifterType shift_t;
9379         uint32_t shift_n; // the shift applied to the value read from Rm
9380         uint32_t carry;
9381         switch (encoding)
9382         {
9383         case eEncodingT1:
9384             Rn = Bits32(opcode, 19, 16);
9385             Rm = Bits32(opcode, 3, 0);
9386             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9387             if (BadReg(Rn) || BadReg(Rm))
9388                 return false;
9389             break;
9390         case eEncodingA1:
9391             Rn = Bits32(opcode, 19, 16);
9392             Rm = Bits32(opcode, 3, 0);
9393             shift_n = DecodeImmShiftARM(opcode, shift_t);
9394             break;
9395         default:
9396             return false;
9397         }
9398 
9399         // Read the first operand.
9400         uint32_t val1 = ReadCoreReg(Rn, &success);
9401         if (!success)
9402             return false;
9403 
9404         // Read the second operand.
9405         uint32_t val2 = ReadCoreReg(Rm, &success);
9406         if (!success)
9407             return false;
9408 
9409         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9410         if (!success)
9411             return false;
9412         uint32_t result = val1 ^ shifted;
9413 
9414         EmulateInstruction::Context context;
9415         context.type = EmulateInstruction::eContextImmediate;
9416         context.SetNoArgs ();
9417 
9418         if (!WriteFlags(context, result, carry))
9419             return false;
9420     }
9421     return true;
9422 }
9423 
9424 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value.
9425 // It updates the condition flags based on the result, and discards the result.
9426 bool
9427 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding)
9428 {
9429 #if 0
9430     // ARM pseudo code...
9431     if ConditionPassed() then
9432         EncodingSpecificOperations();
9433         result = R[n] AND imm32;
9434         APSR.N = result<31>;
9435         APSR.Z = IsZeroBit(result);
9436         APSR.C = carry;
9437         // APSR.V unchanged
9438 #endif
9439 
9440     bool success = false;
9441 
9442     if (ConditionPassed(opcode))
9443     {
9444         uint32_t Rn;
9445         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9446         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9447         switch (encoding)
9448         {
9449         case eEncodingT1:
9450             Rn = Bits32(opcode, 19, 16);
9451             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9452             if (BadReg(Rn))
9453                 return false;
9454             break;
9455         case eEncodingA1:
9456             Rn = Bits32(opcode, 19, 16);
9457             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9458             break;
9459         default:
9460             return false;
9461         }
9462 
9463         // Read the first operand.
9464         uint32_t val1 = ReadCoreReg(Rn, &success);
9465         if (!success)
9466             return false;
9467 
9468         uint32_t result = val1 & imm32;
9469 
9470         EmulateInstruction::Context context;
9471         context.type = EmulateInstruction::eContextImmediate;
9472         context.SetNoArgs ();
9473 
9474         if (!WriteFlags(context, result, carry))
9475             return false;
9476     }
9477     return true;
9478 }
9479 
9480 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value.
9481 // It updates the condition flags based on the result, and discards the result.
9482 bool
9483 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding)
9484 {
9485 #if 0
9486     // ARM pseudo code...
9487     if ConditionPassed() then
9488         EncodingSpecificOperations();
9489         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9490         result = R[n] AND shifted;
9491         APSR.N = result<31>;
9492         APSR.Z = IsZeroBit(result);
9493         APSR.C = carry;
9494         // APSR.V unchanged
9495 #endif
9496 
9497     bool success = false;
9498 
9499     if (ConditionPassed(opcode))
9500     {
9501         uint32_t Rn, Rm;
9502         ARM_ShifterType shift_t;
9503         uint32_t shift_n; // the shift applied to the value read from Rm
9504         uint32_t carry;
9505         switch (encoding)
9506         {
9507         case eEncodingT1:
9508             Rn = Bits32(opcode, 2, 0);
9509             Rm = Bits32(opcode, 5, 3);
9510             shift_t = SRType_LSL;
9511             shift_n = 0;
9512             break;
9513         case eEncodingT2:
9514             Rn = Bits32(opcode, 19, 16);
9515             Rm = Bits32(opcode, 3, 0);
9516             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9517             if (BadReg(Rn) || BadReg(Rm))
9518                 return false;
9519             break;
9520         case eEncodingA1:
9521             Rn = Bits32(opcode, 19, 16);
9522             Rm = Bits32(opcode, 3, 0);
9523             shift_n = DecodeImmShiftARM(opcode, shift_t);
9524             break;
9525         default:
9526             return false;
9527         }
9528 
9529         // Read the first operand.
9530         uint32_t val1 = ReadCoreReg(Rn, &success);
9531         if (!success)
9532             return false;
9533 
9534         // Read the second operand.
9535         uint32_t val2 = ReadCoreReg(Rm, &success);
9536         if (!success)
9537             return false;
9538 
9539         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9540         if (!success)
9541             return false;
9542         uint32_t result = val1 & shifted;
9543 
9544         EmulateInstruction::Context context;
9545         context.type = EmulateInstruction::eContextImmediate;
9546         context.SetNoArgs ();
9547 
9548         if (!WriteFlags(context, result, carry))
9549             return false;
9550     }
9551     return true;
9552 }
9553 
9554 // A8.6.216 SUB (SP minus register)
9555 bool
9556 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding)
9557 {
9558 #if 0
9559     if ConditionPassed() then
9560         EncodingSpecificOperations();
9561         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9562         (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
9563         if d == 15 then // Can only occur for ARM encoding
9564             ALUWritePC(result); // setflags is always FALSE here
9565         else
9566             R[d] = result;
9567             if setflags then
9568                 APSR.N = result<31>;
9569                 APSR.Z = IsZeroBit(result);
9570                 APSR.C = carry;
9571                 APSR.V = overflow;
9572 #endif
9573 
9574     bool success = false;
9575 
9576     if (ConditionPassed(opcode))
9577     {
9578         uint32_t d;
9579         uint32_t m;
9580         bool setflags;
9581         ARM_ShifterType shift_t;
9582         uint32_t shift_n;
9583 
9584         switch (encoding)
9585         {
9586             case eEncodingT1:
9587                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
9588                 d = Bits32 (opcode, 11, 8);
9589                 m = Bits32 (opcode, 3, 0);
9590                 setflags = BitIsSet (opcode, 20);
9591 
9592                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9593                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9594 
9595                 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE;
9596                 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
9597                     return false;
9598 
9599                 // if d == 15 || BadReg(m) then UNPREDICTABLE;
9600                 if ((d == 15) || BadReg (m))
9601                     return false;
9602                 break;
9603 
9604             case eEncodingA1:
9605                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
9606                 d = Bits32 (opcode, 15, 12);
9607                 m = Bits32 (opcode, 3, 0);
9608                 setflags = BitIsSet (opcode, 20);
9609 
9610                 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9611                 if (d == 15 && setflags)
9612                     EmulateSUBSPcLrEtc (opcode, encoding);
9613 
9614                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9615                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9616                 break;
9617 
9618             default:
9619                 return false;
9620         }
9621 
9622         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9623         uint32_t Rm = ReadCoreReg (m, &success);
9624         if (!success)
9625             return false;
9626 
9627         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9628         if (!success)
9629             return false;
9630 
9631         // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
9632         uint32_t sp_val = ReadCoreReg (SP_REG, &success);
9633         if (!success)
9634             return false;
9635 
9636         AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1);
9637 
9638         EmulateInstruction::Context context;
9639         context.type = eContextArithmetic;
9640         RegisterInfo sp_reg;
9641         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
9642         RegisterInfo dwarf_reg;
9643         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
9644         context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
9645 
9646         if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9647             return false;
9648     }
9649     return true;
9650 }
9651 
9652 
9653 // A8.6.7 ADD (register-shifted register)
9654 bool
9655 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding)
9656 {
9657 #if 0
9658     if ConditionPassed() then
9659         EncodingSpecificOperations();
9660         shift_n = UInt(R[s]<7:0>);
9661         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9662         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
9663         R[d] = result;
9664         if setflags then
9665             APSR.N = result<31>;
9666             APSR.Z = IsZeroBit(result);
9667             APSR.C = carry;
9668             APSR.V = overflow;
9669 #endif
9670 
9671     bool success = false;
9672 
9673     if (ConditionPassed(opcode))
9674     {
9675         uint32_t d;
9676         uint32_t n;
9677         uint32_t m;
9678         uint32_t s;
9679         bool setflags;
9680         ARM_ShifterType shift_t;
9681 
9682         switch (encoding)
9683         {
9684             case eEncodingA1:
9685                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
9686                 d = Bits32 (opcode, 15, 12);
9687                 n = Bits32 (opcode, 19, 16);
9688                 m = Bits32 (opcode, 3, 0);
9689                 s = Bits32 (opcode, 11, 8);
9690 
9691                 // setflags = (S == '1'); shift_t = DecodeRegShift(type);
9692                 setflags = BitIsSet (opcode, 20);
9693                 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5));
9694 
9695                 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
9696                 if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
9697                     return false;
9698                 break;
9699 
9700             default:
9701                 return false;
9702         }
9703 
9704         // shift_n = UInt(R[s]<7:0>);
9705         uint32_t Rs = ReadCoreReg (s, &success);
9706         if (!success)
9707             return false;
9708 
9709         uint32_t shift_n = Bits32 (Rs, 7, 0);
9710 
9711         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9712         uint32_t Rm = ReadCoreReg (m, &success);
9713         if (!success)
9714             return false;
9715 
9716         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9717         if (!success)
9718             return false;
9719 
9720         // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
9721         uint32_t Rn = ReadCoreReg (n, &success);
9722         if (!success)
9723             return false;
9724 
9725         AddWithCarryResult res = AddWithCarry (Rn, shifted, 0);
9726 
9727         // R[d] = result;
9728         EmulateInstruction::Context context;
9729         context.type = eContextArithmetic;
9730         RegisterInfo reg_n;
9731         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9732         RegisterInfo reg_m;
9733         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9734 
9735         context.SetRegisterRegisterOperands (reg_n, reg_m);
9736 
9737         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result))
9738             return false;
9739 
9740         // if setflags then
9741             // APSR.N = result<31>;
9742             // APSR.Z = IsZeroBit(result);
9743             // APSR.C = carry;
9744             // APSR.V = overflow;
9745         if (setflags)
9746             return WriteFlags (context, res.result, res.carry_out, res.overflow);
9747     }
9748     return true;
9749 }
9750 
9751 // A8.6.213 SUB (register)
9752 bool
9753 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding)
9754 {
9755 #if 0
9756     if ConditionPassed() then
9757         EncodingSpecificOperations();
9758         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9759         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
9760         if d == 15 then // Can only occur for ARM encoding
9761             ALUWritePC(result); // setflags is always FALSE here
9762         else
9763             R[d] = result;
9764             if setflags then
9765                 APSR.N = result<31>;
9766                 APSR.Z = IsZeroBit(result);
9767                 APSR.C = carry;
9768                 APSR.V = overflow;
9769 #endif
9770 
9771     bool success = false;
9772 
9773     if (ConditionPassed(opcode))
9774     {
9775         uint32_t d;
9776         uint32_t n;
9777         uint32_t m;
9778         bool setflags;
9779         ARM_ShifterType shift_t;
9780         uint32_t shift_n;
9781 
9782         switch (encoding)
9783         {
9784             case eEncodingT1:
9785                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
9786                 d = Bits32 (opcode, 2, 0);
9787                 n = Bits32 (opcode, 5, 3);
9788                 m = Bits32 (opcode, 8, 6);
9789                 setflags = !InITBlock();
9790 
9791                 // (shift_t, shift_n) = (SRType_LSL, 0);
9792                 shift_t = SRType_LSL;
9793                 shift_n = 0;
9794 
9795                 break;
9796 
9797             case eEncodingT2:
9798                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1");
9799                 d = Bits32 (opcode, 11, 8);
9800                 n = Bits32 (opcode, 19, 16);
9801                 m = Bits32 (opcode, 3, 0);
9802                 setflags = BitIsSet (opcode, 20);
9803 
9804                 // if Rd == "1111" && S == "1" then SEE CMP (register);
9805                 if (d == 15 && setflags == 1)
9806                     return EmulateCMPImm (opcode, eEncodingT3);
9807 
9808                 // if Rn == "1101" then SEE SUB (SP minus register);
9809                 if (n == 13)
9810                     return EmulateSUBSPReg (opcode, eEncodingT1);
9811 
9812                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9813                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9814 
9815                 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE;
9816                 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m))
9817                     return false;
9818 
9819                 break;
9820 
9821             case eEncodingA1:
9822                 // if Rn == '1101' then SEE SUB (SP minus register);
9823                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
9824                 d = Bits32 (opcode, 15, 12);
9825                 n = Bits32 (opcode, 19, 16);
9826                 m = Bits32 (opcode, 3, 0);
9827                 setflags = BitIsSet (opcode, 20);
9828 
9829                 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9830                 if ((d == 15) && setflags)
9831                     EmulateSUBSPcLrEtc (opcode, encoding);
9832 
9833                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9834                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9835 
9836                 break;
9837 
9838             default:
9839                 return false;
9840         }
9841 
9842         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9843         uint32_t Rm = ReadCoreReg (m, &success);
9844         if (!success)
9845             return false;
9846 
9847         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9848         if (!success)
9849             return false;
9850 
9851         // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
9852         uint32_t Rn = ReadCoreReg (n, &success);
9853         if (!success)
9854             return false;
9855 
9856         AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1);
9857 
9858         // if d == 15 then // Can only occur for ARM encoding
9859             // ALUWritePC(result); // setflags is always FALSE here
9860         // else
9861             // R[d] = result;
9862             // if setflags then
9863                 // APSR.N = result<31>;
9864                 // APSR.Z = IsZeroBit(result);
9865                 // APSR.C = carry;
9866                 // APSR.V = overflow;
9867 
9868         EmulateInstruction::Context context;
9869         context.type = eContextArithmetic;
9870         RegisterInfo reg_n;
9871         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9872         RegisterInfo reg_m;
9873         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9874         context.SetRegisterRegisterOperands (reg_n, reg_m);
9875 
9876         if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9877             return false;
9878     }
9879     return true;
9880 }
9881 
9882 // A8.6.202 STREX
9883 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a
9884 // word from a register to memory if the executing processor has exclusive access to the memory addressed.
9885 bool
9886 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding)
9887 {
9888 #if 0
9889     if ConditionPassed() then
9890         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9891         address = R[n] + imm32;
9892         if ExclusiveMonitorsPass(address,4) then
9893             MemA[address,4] = R[t];
9894             R[d] = 0;
9895         else
9896             R[d] = 1;
9897 #endif
9898 
9899     bool success = false;
9900 
9901     if (ConditionPassed(opcode))
9902     {
9903         uint32_t d;
9904         uint32_t t;
9905         uint32_t n;
9906         uint32_t imm32;
9907         const uint32_t addr_byte_size = GetAddressByteSize();
9908 
9909         switch (encoding)
9910         {
9911             case eEncodingT1:
9912                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
9913                 d = Bits32 (opcode, 11, 8);
9914                 t = Bits32 (opcode, 15, 12);
9915                 n = Bits32 (opcode, 19, 16);
9916                 imm32 = Bits32 (opcode, 7, 0) << 2;
9917 
9918                 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
9919                 if (BadReg (d) || BadReg (t) || (n == 15))
9920                   return false;
9921 
9922                 // if d == n || d == t then UNPREDICTABLE;
9923                 if ((d == n) || (d == t))
9924                   return false;
9925 
9926                 break;
9927 
9928             case eEncodingA1:
9929                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset
9930                 d = Bits32 (opcode, 15, 12);
9931                 t = Bits32 (opcode, 3, 0);
9932                 n = Bits32 (opcode, 19, 16);
9933                 imm32 = 0;
9934 
9935                 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
9936                 if ((d == 15) || (t == 15) || (n == 15))
9937                     return false;
9938 
9939                 // if d == n || d == t then UNPREDICTABLE;
9940                 if ((d == n) || (d == t))
9941                     return false;
9942 
9943                 break;
9944 
9945             default:
9946                 return false;
9947         }
9948 
9949         // address = R[n] + imm32;
9950         uint32_t Rn = ReadCoreReg (n, &success);
9951         if (!success)
9952             return false;
9953 
9954         addr_t address = Rn + imm32;
9955 
9956         RegisterInfo base_reg;
9957         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9958         RegisterInfo data_reg;
9959         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9960         EmulateInstruction::Context context;
9961         context.type = eContextRegisterStore;
9962         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32);
9963 
9964         // if ExclusiveMonitorsPass(address,4) then
9965         // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this
9966         //                                                         always return true.
9967         if (true)
9968         {
9969             // MemA[address,4] = R[t];
9970             uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
9971             if (!success)
9972                 return false;
9973 
9974             if (!MemAWrite (context, address, Rt, addr_byte_size))
9975                 return false;
9976 
9977             // R[d] = 0;
9978             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0))
9979                 return false;
9980         }
9981 #if 0 // unreachable because if true
9982         else
9983         {
9984             // R[d] = 1;
9985             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
9986                 return false;
9987         }
9988 #endif // unreachable because if true
9989     }
9990     return true;
9991 }
9992 
9993 // A8.6.197 STRB (immediate, ARM)
9994 bool
9995 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9996 {
9997 #if 0
9998     if ConditionPassed() then
9999         EncodingSpecificOperations();
10000         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10001         address = if index then offset_addr else R[n];
10002         MemU[address,1] = R[t]<7:0>;
10003         if wback then R[n] = offset_addr;
10004 #endif
10005 
10006     bool success = false;
10007 
10008     if (ConditionPassed(opcode))
10009     {
10010         uint32_t t;
10011         uint32_t n;
10012         uint32_t imm32;
10013         bool index;
10014         bool add;
10015         bool wback;
10016 
10017         switch (encoding)
10018         {
10019             case eEncodingA1:
10020                 // if P == '0' && W == '1' then SEE STRBT;
10021                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10022                 t = Bits32 (opcode, 15, 12);
10023                 n = Bits32 (opcode, 19, 16);
10024                 imm32 = Bits32 (opcode, 11, 0);
10025 
10026                 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10027                 index = BitIsSet (opcode, 24);
10028                 add = BitIsSet (opcode, 23);
10029                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10030 
10031                 // if t == 15 then UNPREDICTABLE;
10032                 if (t == 15)
10033                     return false;
10034 
10035                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10036                 if (wback && ((n == 15) || (n == t)))
10037                     return false;
10038 
10039                 break;
10040 
10041             default:
10042                 return false;
10043         }
10044 
10045         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10046         uint32_t Rn = ReadCoreReg (n, &success);
10047         if (!success)
10048             return false;
10049 
10050         addr_t offset_addr;
10051         if (add)
10052             offset_addr = Rn + imm32;
10053         else
10054             offset_addr = Rn - imm32;
10055 
10056         // address = if index then offset_addr else R[n];
10057         addr_t address;
10058         if (index)
10059             address = offset_addr;
10060         else
10061             address = Rn;
10062 
10063         // MemU[address,1] = R[t]<7:0>;
10064         uint32_t Rt = ReadCoreReg (t, &success);
10065         if (!success)
10066             return false;
10067 
10068         RegisterInfo base_reg;
10069         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10070         RegisterInfo data_reg;
10071         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10072         EmulateInstruction::Context context;
10073         context.type = eContextRegisterStore;
10074         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10075 
10076         if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1))
10077             return false;
10078 
10079         // if wback then R[n] = offset_addr;
10080         if (wback)
10081         {
10082             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10083                 return false;
10084         }
10085     }
10086     return true;
10087 }
10088 
10089 // A8.6.194 STR (immediate, ARM)
10090 bool
10091 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding)
10092 {
10093 #if 0
10094     if ConditionPassed() then
10095         EncodingSpecificOperations();
10096         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10097         address = if index then offset_addr else R[n];
10098         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10099         if wback then R[n] = offset_addr;
10100 #endif
10101 
10102     bool success = false;
10103 
10104     if (ConditionPassed(opcode))
10105     {
10106         uint32_t t;
10107         uint32_t n;
10108         uint32_t imm32;
10109         bool index;
10110         bool add;
10111         bool wback;
10112 
10113         const uint32_t addr_byte_size = GetAddressByteSize();
10114 
10115         switch (encoding)
10116         {
10117             case eEncodingA1:
10118                 // if P == '0' && W == '1' then SEE STRT;
10119                 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == '000000000100' then SEE PUSH;
10120                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10121                 t = Bits32 (opcode, 15, 12);
10122                 n = Bits32 (opcode, 19, 16);
10123                 imm32 = Bits32 (opcode, 11, 0);
10124 
10125                 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10126                 index = BitIsSet (opcode, 24);
10127                 add = BitIsSet (opcode, 23);
10128                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10129 
10130                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10131                 if (wback && ((n == 15) || (n == t)))
10132                     return false;
10133 
10134                 break;
10135 
10136             default:
10137                 return false;
10138         }
10139 
10140         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10141         uint32_t Rn = ReadCoreReg (n, &success);
10142         if (!success)
10143             return false;
10144 
10145         addr_t offset_addr;
10146         if (add)
10147             offset_addr = Rn + imm32;
10148         else
10149             offset_addr = Rn - imm32;
10150 
10151         // address = if index then offset_addr else R[n];
10152         addr_t address;
10153         if (index)
10154             address = offset_addr;
10155         else
10156             address = Rn;
10157 
10158         RegisterInfo base_reg;
10159         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10160         RegisterInfo data_reg;
10161         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10162         EmulateInstruction::Context context;
10163         context.type = eContextRegisterStore;
10164         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10165 
10166         // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10167         uint32_t Rt = ReadCoreReg (t, &success);
10168         if (!success)
10169             return false;
10170 
10171         if (t == 15)
10172         {
10173             uint32_t pc_value = ReadCoreReg (PC_REG, &success);
10174             if (!success)
10175                 return false;
10176 
10177             if (!MemUWrite (context, address, pc_value, addr_byte_size))
10178                 return false;
10179         }
10180         else
10181         {
10182             if (!MemUWrite (context, address, Rt, addr_byte_size))
10183                   return false;
10184         }
10185 
10186         // if wback then R[n] = offset_addr;
10187         if (wback)
10188         {
10189             context.type = eContextAdjustBaseRegister;
10190             context.SetImmediate (offset_addr);
10191 
10192             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10193                 return false;
10194         }
10195     }
10196     return true;
10197 }
10198 
10199 // A8.6.66 LDRD (immediate)
10200 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two
10201 // words from memory, and writes them to two registers.  It can use offset, post-indexed, or pre-indexed addressing.
10202 bool
10203 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding)
10204 {
10205 #if 0
10206     if ConditionPassed() then
10207         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10208         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10209         address = if index then offset_addr else R[n];
10210         R[t] = MemA[address,4];
10211         R[t2] = MemA[address+4,4];
10212         if wback then R[n] = offset_addr;
10213 #endif
10214 
10215     bool success = false;
10216 
10217     if (ConditionPassed(opcode))
10218     {
10219         uint32_t t;
10220         uint32_t t2;
10221         uint32_t n;
10222         uint32_t imm32;
10223         bool index;
10224         bool add;
10225         bool wback;
10226 
10227         switch (encoding)
10228         {
10229             case eEncodingT1:
10230                 //if P == '0' && W == '0' then SEE 'Related encodings';
10231                 //if Rn == '1111' then SEE LDRD (literal);
10232                 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
10233                 t = Bits32 (opcode, 15, 12);
10234                 t2 = Bits32 (opcode, 11, 8);
10235                 n = Bits32 (opcode, 19, 16);
10236                 imm32 = Bits32 (opcode, 7, 0) << 2;
10237 
10238                 //index = (P == '1'); add = (U == '1'); wback = (W == '1');
10239                 index = BitIsSet (opcode, 24);
10240                 add = BitIsSet (opcode, 23);
10241                 wback = BitIsSet (opcode, 21);
10242 
10243                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10244                 if (wback && ((n == t) || (n == t2)))
10245                     return false;
10246 
10247                 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10248                 if (BadReg (t) || BadReg (t2) || (t == t2))
10249                     return false;
10250 
10251                 break;
10252 
10253             case eEncodingA1:
10254                 //if Rn == '1111' then SEE LDRD (literal);
10255                 //if Rt<0> == '1' then UNPREDICTABLE;
10256                 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10257                 t = Bits32 (opcode, 15, 12);
10258                 if (BitIsSet (t, 0))
10259                     return false;
10260                 t2 = t + 1;
10261                 n = Bits32 (opcode, 19, 16);
10262                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10263 
10264                 //index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10265                 index = BitIsSet (opcode, 24);
10266                 add = BitIsSet (opcode, 23);
10267                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10268 
10269                 //if P == '0' && W == '1' then UNPREDICTABLE;
10270                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10271                     return false;
10272 
10273                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10274                 if (wback && ((n == t) || (n == t2)))
10275                     return false;
10276 
10277                 //if t2 == 15 then UNPREDICTABLE;
10278                 if (t2 == 15)
10279                     return false;
10280 
10281                 break;
10282 
10283             default:
10284                 return false;
10285         }
10286 
10287         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10288         uint32_t Rn = ReadCoreReg (n, &success);
10289         if (!success)
10290             return false;
10291 
10292         addr_t offset_addr;
10293         if (add)
10294                   offset_addr = Rn + imm32;
10295         else
10296             offset_addr = Rn - imm32;
10297 
10298         //address = if index then offset_addr else R[n];
10299         addr_t address;
10300         if (index)
10301             address = offset_addr;
10302         else
10303             address = Rn;
10304 
10305         //R[t] = MemA[address,4];
10306         RegisterInfo base_reg;
10307         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10308 
10309         EmulateInstruction::Context context;
10310         if (n == 13)
10311             context.type = eContextPopRegisterOffStack;
10312         else
10313             context.type = eContextRegisterLoad;
10314         context.SetAddress(address);
10315 
10316         const uint32_t addr_byte_size = GetAddressByteSize();
10317         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10318         if (!success)
10319             return false;
10320 
10321         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10322             return false;
10323 
10324         //R[t2] = MemA[address+4,4];
10325         context.SetAddress(address + 4);
10326         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10327         if (!success)
10328             return false;
10329 
10330         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10331             return false;
10332 
10333         //if wback then R[n] = offset_addr;
10334         if (wback)
10335         {
10336             context.type = eContextAdjustBaseRegister;
10337             context.SetAddress (offset_addr);
10338 
10339             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10340                 return false;
10341         }
10342     }
10343     return true;
10344 }
10345 
10346 // A8.6.68 LDRD (register)
10347 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two
10348 // words from memory, and writes them to two registers.  It can use offset, post-indexed or pre-indexed addressing.
10349 bool
10350 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding)
10351 {
10352 #if 0
10353     if ConditionPassed() then
10354         EncodingSpecificOperations();
10355         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10356         address = if index then offset_addr else R[n];
10357         R[t] = MemA[address,4];
10358         R[t2] = MemA[address+4,4];
10359         if wback then R[n] = offset_addr;
10360 #endif
10361 
10362     bool success = false;
10363 
10364     if (ConditionPassed(opcode))
10365     {
10366         uint32_t t;
10367         uint32_t t2;
10368         uint32_t n;
10369         uint32_t m;
10370         bool index;
10371         bool add;
10372         bool wback;
10373 
10374         switch (encoding)
10375         {
10376             case eEncodingA1:
10377                 // if Rt<0> == '1' then UNPREDICTABLE;
10378                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10379                 t = Bits32 (opcode, 15, 12);
10380                 if (BitIsSet (t, 0))
10381                     return false;
10382                 t2 = t + 1;
10383                 n = Bits32 (opcode, 19, 16);
10384                 m = Bits32 (opcode, 3, 0);
10385 
10386                 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10387                 index = BitIsSet (opcode, 24);
10388                 add = BitIsSet (opcode, 23);
10389                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10390 
10391                 // if P == '0' && W == '1' then UNPREDICTABLE;
10392                   if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10393                   return false;
10394 
10395                 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10396                   if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10397                   return false;
10398 
10399                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10400                   if (wback && ((n == 15) || (n == t) || (n == t2)))
10401                   return false;
10402 
10403                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10404                 if ((ArchVersion() < 6) && wback && (m == n))
10405                   return false;
10406                 break;
10407 
10408             default:
10409                 return false;
10410         }
10411 
10412         uint32_t Rn = ReadCoreReg (n, &success);
10413         if (!success)
10414             return false;
10415         RegisterInfo base_reg;
10416         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10417 
10418         uint32_t Rm = ReadCoreReg (m, &success);
10419         if (!success)
10420             return false;
10421         RegisterInfo offset_reg;
10422         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10423 
10424         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10425         addr_t offset_addr;
10426         if (add)
10427             offset_addr = Rn + Rm;
10428         else
10429             offset_addr = Rn - Rm;
10430 
10431         // address = if index then offset_addr else R[n];
10432         addr_t address;
10433         if (index)
10434             address = offset_addr;
10435         else
10436             address = Rn;
10437 
10438         EmulateInstruction::Context context;
10439         if (n == 13)
10440             context.type = eContextPopRegisterOffStack;
10441         else
10442             context.type = eContextRegisterLoad;
10443         context.SetAddress(address);
10444 
10445         // R[t] = MemA[address,4];
10446         const uint32_t addr_byte_size = GetAddressByteSize();
10447         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10448         if (!success)
10449             return false;
10450 
10451         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10452             return false;
10453 
10454         // R[t2] = MemA[address+4,4];
10455 
10456         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10457         if (!success)
10458             return false;
10459 
10460         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10461             return false;
10462 
10463         // if wback then R[n] = offset_addr;
10464         if (wback)
10465         {
10466             context.type = eContextAdjustBaseRegister;
10467             context.SetAddress (offset_addr);
10468 
10469             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10470                 return false;
10471         }
10472     }
10473     return true;
10474 }
10475 
10476 // A8.6.200 STRD (immediate)
10477 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and
10478 // stores two words from two registers to memory.  It can use offset, post-indexed, or pre-indexed addressing.
10479 bool
10480 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding)
10481 {
10482 #if 0
10483     if ConditionPassed() then
10484         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10485         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10486         address = if index then offset_addr else R[n];
10487         MemA[address,4] = R[t];
10488         MemA[address+4,4] = R[t2];
10489         if wback then R[n] = offset_addr;
10490 #endif
10491 
10492     bool success = false;
10493 
10494     if (ConditionPassed(opcode))
10495     {
10496         uint32_t t;
10497         uint32_t t2;
10498         uint32_t n;
10499         uint32_t imm32;
10500         bool index;
10501         bool add;
10502         bool wback;
10503 
10504         switch (encoding)
10505         {
10506             case eEncodingT1:
10507                 // if P == '0' && W == '0' then SEE 'Related encodings';
10508                 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
10509                 t = Bits32 (opcode, 15, 12);
10510                 t2 = Bits32 (opcode, 11, 8);
10511                 n = Bits32 (opcode, 19, 16);
10512                 imm32 = Bits32 (opcode, 7, 0) << 2;
10513 
10514                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
10515                 index = BitIsSet (opcode, 24);
10516                 add = BitIsSet (opcode, 23);
10517                 wback = BitIsSet (opcode, 21);
10518 
10519                 // if wback && (n == t || n == t2) then UNPREDICTABLE;
10520                 if (wback && ((n == t) || (n == t2)))
10521                     return false;
10522 
10523                 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10524                 if ((n == 15) || BadReg (t) || BadReg (t2))
10525                     return false;
10526 
10527                 break;
10528 
10529             case eEncodingA1:
10530                 // if Rt<0> == '1' then UNPREDICTABLE;
10531                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10532                 t = Bits32 (opcode, 15, 12);
10533                 if (BitIsSet (t, 0))
10534                     return false;
10535 
10536                 t2 = t + 1;
10537                 n = Bits32 (opcode, 19, 16);
10538                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10539 
10540                 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10541                 index = BitIsSet (opcode, 24);
10542                 add = BitIsSet (opcode, 23);
10543                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10544 
10545                 // if P == '0' && W == '1' then UNPREDICTABLE;
10546                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10547                     return false;
10548 
10549                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10550                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10551                     return false;
10552 
10553                 // if t2 == 15 then UNPREDICTABLE;
10554                 if (t2 == 15)
10555                     return false;
10556 
10557                 break;
10558 
10559             default:
10560                 return false;
10561         }
10562 
10563         RegisterInfo base_reg;
10564         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10565 
10566         uint32_t Rn = ReadCoreReg (n, &success);
10567         if (!success)
10568             return false;
10569 
10570         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10571         addr_t offset_addr;
10572         if (add)
10573             offset_addr = Rn + imm32;
10574         else
10575             offset_addr = Rn - imm32;
10576 
10577         //address = if index then offset_addr else R[n];
10578         addr_t address;
10579         if (index)
10580             address = offset_addr;
10581         else
10582             address = Rn;
10583 
10584         //MemA[address,4] = R[t];
10585         RegisterInfo data_reg;
10586         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10587 
10588         uint32_t data = ReadCoreReg (t, &success);
10589         if (!success)
10590             return false;
10591 
10592         EmulateInstruction::Context context;
10593         if (n == 13)
10594             context.type = eContextPushRegisterOnStack;
10595         else
10596             context.type = eContextRegisterStore;
10597         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10598 
10599         const uint32_t addr_byte_size = GetAddressByteSize();
10600 
10601         if (!MemAWrite (context, address, data, addr_byte_size))
10602             return false;
10603 
10604         //MemA[address+4,4] = R[t2];
10605         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10606         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10607 
10608         data = ReadCoreReg (t2, &success);
10609         if (!success)
10610             return false;
10611 
10612         if (!MemAWrite (context, address + 4, data, addr_byte_size))
10613             return false;
10614 
10615         //if wback then R[n] = offset_addr;
10616         if (wback)
10617         {
10618             context.type = eContextAdjustBaseRegister;
10619             context.SetAddress (offset_addr);
10620 
10621             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10622                 return false;
10623         }
10624     }
10625     return true;
10626 }
10627 
10628 
10629 // A8.6.201 STRD (register)
10630 bool
10631 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding)
10632 {
10633 #if 0
10634     if ConditionPassed() then
10635         EncodingSpecificOperations();
10636         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10637         address = if index then offset_addr else R[n];
10638         MemA[address,4] = R[t];
10639         MemA[address+4,4] = R[t2];
10640         if wback then R[n] = offset_addr;
10641 #endif
10642 
10643     bool success = false;
10644 
10645     if (ConditionPassed(opcode))
10646     {
10647         uint32_t t;
10648         uint32_t t2;
10649         uint32_t n;
10650         uint32_t m;
10651         bool index;
10652         bool add;
10653         bool wback;
10654 
10655         switch (encoding)
10656         {
10657             case eEncodingA1:
10658                 // if Rt<0> == '1' then UNPREDICTABLE;
10659                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10660                 t = Bits32 (opcode, 15, 12);
10661                 if (BitIsSet (t, 0))
10662                    return false;
10663 
10664                 t2 = t+1;
10665                 n = Bits32 (opcode, 19, 16);
10666                 m = Bits32 (opcode, 3, 0);
10667 
10668                 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10669                 index = BitIsSet (opcode, 24);
10670                 add = BitIsSet (opcode, 23);
10671                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10672 
10673                 // if P == '0' && W == '1' then UNPREDICTABLE;
10674                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10675                    return false;
10676 
10677                 // if t2 == 15 || m == 15 then UNPREDICTABLE;
10678                 if ((t2 == 15) || (m == 15))
10679                    return false;
10680 
10681                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10682                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10683                    return false;
10684 
10685                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10686                 if ((ArchVersion() < 6) && wback && (m == n))
10687                    return false;
10688 
10689                 break;
10690 
10691             default:
10692                 return false;
10693         }
10694 
10695         RegisterInfo base_reg;
10696         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10697         RegisterInfo offset_reg;
10698         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10699         RegisterInfo data_reg;
10700 
10701         uint32_t Rn = ReadCoreReg (n, &success);
10702         if (!success)
10703             return false;
10704 
10705         uint32_t Rm = ReadCoreReg (m, &success);
10706         if (!success)
10707             return false;
10708 
10709         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10710         addr_t offset_addr;
10711         if (add)
10712             offset_addr = Rn + Rm;
10713         else
10714             offset_addr = Rn - Rm;
10715 
10716         // address = if index then offset_addr else R[n];
10717         addr_t address;
10718         if (index)
10719             address = offset_addr;
10720         else
10721             address = Rn;
10722                           // MemA[address,4] = R[t];
10723         uint32_t Rt = ReadCoreReg (t, &success);
10724         if (!success)
10725             return false;
10726 
10727         EmulateInstruction::Context context;
10728         if (t == 13)
10729             context.type = eContextPushRegisterOnStack;
10730         else
10731             context.type = eContextRegisterStore;
10732 
10733         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10734         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10735 
10736         const uint32_t addr_byte_size = GetAddressByteSize();
10737 
10738         if (!MemAWrite (context, address, Rt, addr_byte_size))
10739             return false;
10740 
10741         // MemA[address+4,4] = R[t2];
10742         uint32_t Rt2 = ReadCoreReg (t2, &success);
10743         if (!success)
10744             return false;
10745 
10746         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10747 
10748         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10749 
10750         if (!MemAWrite (context, address + 4, Rt2, addr_byte_size))
10751             return false;
10752 
10753         // if wback then R[n] = offset_addr;
10754         if (wback)
10755         {
10756             context.type = eContextAdjustBaseRegister;
10757             context.SetAddress (offset_addr);
10758 
10759             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10760                 return false;
10761 
10762         }
10763     }
10764     return true;
10765 }
10766 
10767 // A8.6.319 VLDM
10768 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from
10769 // an ARM core register.
10770 bool
10771 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding)
10772 {
10773 #if 0
10774     if ConditionPassed() then
10775         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10776         address = if add then R[n] else R[n]-imm32;
10777         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10778         for r = 0 to regs-1
10779             if single_regs then
10780                 S[d+r] = MemA[address,4]; address = address+4;
10781             else
10782                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10783                 // Combine the word-aligned words in the correct order for current endianness.
10784                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10785 #endif
10786 
10787     bool success = false;
10788 
10789     if (ConditionPassed(opcode))
10790     {
10791         bool single_regs;
10792         bool add;
10793         bool wback;
10794         uint32_t d;
10795         uint32_t n;
10796         uint32_t imm32;
10797         uint32_t regs;
10798 
10799         switch (encoding)
10800         {
10801             case eEncodingT1:
10802             case eEncodingA1:
10803                 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
10804                 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
10805                 // if P == '1' && W == '0' then SEE VLDR;
10806                 // if P == U && W == '1' then UNDEFINED;
10807                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10808                     return false;
10809 
10810                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10811                 // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
10812                 single_regs = false;
10813                 add = BitIsSet (opcode, 23);
10814                 wback = BitIsSet (opcode, 21);
10815 
10816                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
10817                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10818                 n = Bits32 (opcode, 19, 16);
10819                 imm32 = Bits32 (opcode, 7, 0) << 2;
10820 
10821                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'.
10822                 regs = Bits32 (opcode, 7, 0) / 2;
10823 
10824                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10825                 if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
10826                     return false;
10827 
10828                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10829                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10830                     return false;
10831 
10832                 break;
10833 
10834             case eEncodingT2:
10835             case eEncodingA2:
10836                 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
10837                 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
10838                 // if P == '1' && W == '0' then SEE VLDR;
10839                 // if P == U && W == '1' then UNDEFINED;
10840                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10841                     return false;
10842 
10843                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10844                 // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn);
10845                 single_regs = true;
10846                 add = BitIsSet (opcode, 23);
10847                 wback = BitIsSet (opcode, 21);
10848                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10849                 n = Bits32 (opcode, 19, 16);
10850 
10851                 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
10852                 imm32 = Bits32 (opcode, 7, 0) << 2;
10853                 regs = Bits32 (opcode, 7, 0);
10854 
10855                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10856                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10857                     return false;
10858 
10859                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10860                 if ((regs == 0) || ((d + regs) > 32))
10861                     return false;
10862                 break;
10863 
10864             default:
10865                 return false;
10866         }
10867 
10868         RegisterInfo base_reg;
10869         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10870 
10871         uint32_t Rn = ReadCoreReg (n, &success);
10872         if (!success)
10873             return false;
10874 
10875         // address = if add then R[n] else R[n]-imm32;
10876         addr_t address;
10877         if (add)
10878             address = Rn;
10879         else
10880             address = Rn - imm32;
10881 
10882         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10883         EmulateInstruction::Context context;
10884 
10885         if (wback)
10886         {
10887             uint32_t value;
10888             if (add)
10889                 value = Rn + imm32;
10890             else
10891                 value = Rn - imm32;
10892 
10893             context.type = eContextAdjustBaseRegister;
10894             context.SetImmediateSigned (value - Rn);
10895             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10896                 return false;
10897 
10898         }
10899 
10900         const uint32_t addr_byte_size = GetAddressByteSize();
10901         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10902 
10903         context.type = eContextRegisterLoad;
10904 
10905         // for r = 0 to regs-1
10906         for (uint32_t r = 0; r < regs; ++r)
10907         {
10908             if (single_regs)
10909             {
10910                 // S[d+r] = MemA[address,4]; address = address+4;
10911                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10912 
10913                 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10914                 if (!success)
10915                     return false;
10916 
10917                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10918                     return false;
10919 
10920                 address = address + 4;
10921             }
10922             else
10923             {
10924                 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10925                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10926                 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10927                 if (!success)
10928                     return false;
10929 
10930                 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10931                 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10932                 if (!success)
10933                     return false;
10934 
10935                 address = address + 8;
10936                 // // Combine the word-aligned words in the correct order for current endianness.
10937                 // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10938                 uint64_t data;
10939                 if (GetByteOrder() == eByteOrderBig)
10940                 {
10941                     data = word1;
10942                     data = (data << 32) | word2;
10943                 }
10944                 else
10945                 {
10946                     data = word2;
10947                     data = (data << 32) | word1;
10948                 }
10949 
10950                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10951                     return false;
10952             }
10953         }
10954     }
10955     return true;
10956 }
10957 
10958 // A8.6.399 VSTM
10959 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an
10960 // ARM core register.
10961 bool
10962 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding)
10963 {
10964 #if 0
10965     if ConditionPassed() then
10966         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10967         address = if add then R[n] else R[n]-imm32;
10968         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10969         for r = 0 to regs-1
10970             if single_regs then
10971                 MemA[address,4] = S[d+r]; address = address+4;
10972             else
10973                 // Store as two word-aligned words in the correct order for current endianness.
10974                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10975                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10976                 address = address+8;
10977 #endif
10978 
10979     bool success = false;
10980 
10981     if (ConditionPassed (opcode))
10982     {
10983         bool single_regs;
10984         bool add;
10985         bool wback;
10986         uint32_t d;
10987         uint32_t n;
10988         uint32_t imm32;
10989         uint32_t regs;
10990 
10991         switch (encoding)
10992         {
10993             case eEncodingT1:
10994             case eEncodingA1:
10995                 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
10996                 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
10997                 // if P == '1' && W == '0' then SEE VSTR;
10998                 // if P == U && W == '1' then UNDEFINED;
10999                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
11000                     return false;
11001 
11002                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
11003                 // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
11004                 single_regs = false;
11005                 add = BitIsSet (opcode, 23);
11006                 wback = BitIsSet (opcode, 21);
11007 
11008                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
11009                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11010                 n = Bits32 (opcode, 19, 16);
11011                 imm32 = Bits32 (opcode, 7, 0) << 2;
11012 
11013                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'.
11014                 regs = Bits32 (opcode, 7, 0) / 2;
11015 
11016                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
11017                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11018                     return false;
11019 
11020                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11021                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11022                     return false;
11023 
11024                 break;
11025 
11026             case eEncodingT2:
11027             case eEncodingA2:
11028                 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11029                 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11030                 // if P == '1' && W == '0' then SEE VSTR;
11031                 // if P == U && W == '1' then UNDEFINED;
11032                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
11033                     return false;
11034 
11035                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
11036                 // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn);
11037                 single_regs = true;
11038                 add = BitIsSet (opcode, 23);
11039                 wback = BitIsSet (opcode, 21);
11040                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11041                 n = Bits32 (opcode, 19, 16);
11042 
11043                 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
11044                 imm32 = Bits32 (opcode, 7, 0) << 2;
11045                 regs = Bits32 (opcode, 7, 0);
11046 
11047                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
11048                 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM)))
11049                     return false;
11050 
11051                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11052                 if ((regs == 0) || ((d + regs) > 32))
11053                     return false;
11054 
11055                 break;
11056 
11057             default:
11058                 return false;
11059         }
11060 
11061         RegisterInfo base_reg;
11062         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11063 
11064         uint32_t Rn = ReadCoreReg (n, &success);
11065         if (!success)
11066             return false;
11067 
11068         // address = if add then R[n] else R[n]-imm32;
11069         addr_t address;
11070         if (add)
11071             address = Rn;
11072         else
11073             address = Rn - imm32;
11074 
11075         EmulateInstruction::Context context;
11076         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11077         if (wback)
11078         {
11079             uint32_t value;
11080             if (add)
11081                 value = Rn + imm32;
11082             else
11083                 value = Rn - imm32;
11084 
11085             context.type = eContextAdjustBaseRegister;
11086             context.SetRegisterPlusOffset (base_reg, value - Rn);
11087 
11088             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11089                 return false;
11090         }
11091 
11092         const uint32_t addr_byte_size = GetAddressByteSize();
11093         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11094 
11095         context.type = eContextRegisterStore;
11096         // for r = 0 to regs-1
11097         for (uint32_t r = 0; r < regs; ++r)
11098         {
11099 
11100             if (single_regs)
11101             {
11102                 // MemA[address,4] = S[d+r]; address = address+4;
11103                 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
11104                 if (!success)
11105                     return false;
11106 
11107                 RegisterInfo data_reg;
11108                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
11109                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11110                 if (!MemAWrite (context, address, data, addr_byte_size))
11111                     return false;
11112 
11113                 address = address + 4;
11114             }
11115             else
11116             {
11117                 // // Store as two word-aligned words in the correct order for current endianness.
11118                 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
11119                 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
11120                 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
11121                 if (!success)
11122                     return false;
11123 
11124                 RegisterInfo data_reg;
11125                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
11126 
11127                 if (GetByteOrder() == eByteOrderBig)
11128                 {
11129                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11130                     if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11131                         return false;
11132 
11133                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11134                     if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size))
11135                         return false;
11136                 }
11137                 else
11138                 {
11139                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11140                     if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11141                         return false;
11142 
11143                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11144                     if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11145                         return false;
11146                 }
11147                 // address = address+8;
11148                 address = address + 8;
11149             }
11150         }
11151     }
11152     return true;
11153 }
11154 
11155 // A8.6.320
11156 // This instruction loads a single extension register from memory, using an address from an ARM core register, with
11157 // an optional offset.
11158 bool
11159 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
11160 {
11161 #if 0
11162     if ConditionPassed() then
11163         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11164         base = if n == 15 then Align(PC,4) else R[n];
11165         address = if add then (base + imm32) else (base - imm32);
11166         if single_reg then
11167             S[d] = MemA[address,4];
11168         else
11169             word1 = MemA[address,4]; word2 = MemA[address+4,4];
11170             // Combine the word-aligned words in the correct order for current endianness.
11171             D[d] = if BigEndian() then word1:word2 else word2:word1;
11172 #endif
11173 
11174     bool success = false;
11175 
11176     if (ConditionPassed (opcode))
11177     {
11178         bool single_reg;
11179         bool add;
11180         uint32_t imm32;
11181         uint32_t d;
11182         uint32_t n;
11183 
11184         switch (encoding)
11185         {
11186             case eEncodingT1:
11187             case eEncodingA1:
11188                 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11189                 single_reg = false;
11190                 add = BitIsSet (opcode, 23);
11191                 imm32 = Bits32 (opcode, 7, 0) << 2;
11192 
11193                 // d = UInt(D:Vd); n = UInt(Rn);
11194                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11195                 n = Bits32 (opcode, 19, 16);
11196 
11197                 break;
11198 
11199             case eEncodingT2:
11200             case eEncodingA2:
11201                 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11202                 single_reg = true;
11203                 add = BitIsSet (opcode, 23);
11204                 imm32 = Bits32 (opcode, 7, 0) << 2;
11205 
11206                 // d = UInt(Vd:D); n = UInt(Rn);
11207                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11208                 n = Bits32 (opcode, 19, 16);
11209 
11210                 break;
11211 
11212             default:
11213                 return false;
11214         }
11215         RegisterInfo base_reg;
11216         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11217 
11218         uint32_t Rn = ReadCoreReg (n, &success);
11219         if (!success)
11220             return false;
11221 
11222         // base = if n == 15 then Align(PC,4) else R[n];
11223         uint32_t base;
11224         if (n == 15)
11225             base = AlignPC (Rn);
11226         else
11227             base = Rn;
11228 
11229         // address = if add then (base + imm32) else (base - imm32);
11230         addr_t address;
11231         if (add)
11232             address = base + imm32;
11233         else
11234             address = base - imm32;
11235 
11236         const uint32_t addr_byte_size = GetAddressByteSize();
11237         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11238 
11239         EmulateInstruction::Context context;
11240         context.type = eContextRegisterLoad;
11241         context.SetRegisterPlusOffset (base_reg, address - base);
11242 
11243         if (single_reg)
11244         {
11245             // S[d] = MemA[address,4];
11246             uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
11247             if (!success)
11248                 return false;
11249 
11250             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data))
11251                 return false;
11252         }
11253         else
11254         {
11255             // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11256             uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
11257             if (!success)
11258                 return false;
11259 
11260             context.SetRegisterPlusOffset (base_reg, (address + 4) - base);
11261             uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
11262             if (!success)
11263                 return false;
11264             // // Combine the word-aligned words in the correct order for current endianness.
11265             // D[d] = if BigEndian() then word1:word2 else word2:word1;
11266             uint64_t data64;
11267             if (GetByteOrder() == eByteOrderBig)
11268             {
11269                 data64 = word1;
11270                 data64 = (data64 << 32) | word2;
11271             }
11272             else
11273             {
11274                 data64 = word2;
11275                 data64 = (data64 << 32) | word1;
11276             }
11277 
11278             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64))
11279                 return false;
11280         }
11281     }
11282     return true;
11283 }
11284 
11285 // A8.6.400 VSTR
11286 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an
11287 // optional offset.
11288 bool
11289 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
11290 {
11291 #if 0
11292     if ConditionPassed() then
11293         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11294         address = if add then (R[n] + imm32) else (R[n] - imm32);
11295         if single_reg then
11296             MemA[address,4] = S[d];
11297         else
11298             // Store as two word-aligned words in the correct order for current endianness.
11299             MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11300             MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11301 #endif
11302 
11303     bool success = false;
11304 
11305     if (ConditionPassed (opcode))
11306     {
11307         bool single_reg;
11308         bool add;
11309         uint32_t imm32;
11310         uint32_t d;
11311         uint32_t n;
11312 
11313         switch (encoding)
11314         {
11315             case eEncodingT1:
11316             case eEncodingA1:
11317                 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11318                 single_reg = false;
11319                 add = BitIsSet (opcode, 23);
11320                 imm32 = Bits32 (opcode, 7, 0) << 2;
11321 
11322                 // d = UInt(D:Vd); n = UInt(Rn);
11323                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11324                 n = Bits32 (opcode, 19, 16);
11325 
11326                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11327                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11328                     return false;
11329 
11330                 break;
11331 
11332             case eEncodingT2:
11333             case eEncodingA2:
11334                 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11335                 single_reg = true;
11336                 add = BitIsSet (opcode, 23);
11337                 imm32 = Bits32 (opcode, 7, 0) << 2;
11338 
11339                 // d = UInt(Vd:D); n = UInt(Rn);
11340                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11341                 n = Bits32 (opcode, 19, 16);
11342 
11343                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11344                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11345                     return false;
11346 
11347                 break;
11348 
11349             default:
11350                 return false;
11351         }
11352 
11353         RegisterInfo base_reg;
11354         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11355 
11356         uint32_t Rn = ReadCoreReg (n, &success);
11357         if (!success)
11358             return false;
11359 
11360         // address = if add then (R[n] + imm32) else (R[n] - imm32);
11361         addr_t address;
11362         if (add)
11363             address = Rn + imm32;
11364         else
11365             address = Rn - imm32;
11366 
11367         const uint32_t addr_byte_size = GetAddressByteSize();
11368         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11369 
11370         RegisterInfo data_reg;
11371         GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg);
11372         EmulateInstruction::Context context;
11373         context.type = eContextRegisterStore;
11374         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11375 
11376         if (single_reg)
11377         {
11378             // MemA[address,4] = S[d];
11379             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11380             if (!success)
11381                 return false;
11382 
11383             if (!MemAWrite (context, address, data, addr_byte_size))
11384                 return false;
11385         }
11386         else
11387         {
11388             // // Store as two word-aligned words in the correct order for current endianness.
11389             // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11390             // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11391             uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11392             if (!success)
11393                 return false;
11394 
11395             if (GetByteOrder() == eByteOrderBig)
11396             {
11397                 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11398                     return false;
11399 
11400                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11401                 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size))
11402                     return false;
11403             }
11404             else
11405             {
11406                 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11407                     return false;
11408 
11409                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11410                 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11411                     return false;
11412             }
11413         }
11414     }
11415     return true;
11416 }
11417 
11418 // A8.6.307 VLDI1 (multiple single elements)
11419 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving.  Every
11420 // element of each register is loaded.
11421 bool
11422 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding)
11423 {
11424 #if 0
11425     if ConditionPassed() then
11426         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11427         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11428         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11429         for r = 0 to regs-1
11430             for e = 0 to elements-1
11431                 Elem[D[d+r],e,esize] = MemU[address,ebytes];
11432                 address = address + ebytes;
11433 #endif
11434 
11435     bool success = false;
11436 
11437     if (ConditionPassed (opcode))
11438     {
11439         uint32_t regs;
11440         uint32_t alignment;
11441         uint32_t ebytes;
11442         uint32_t esize;
11443         uint32_t elements;
11444         uint32_t d;
11445         uint32_t n;
11446         uint32_t m;
11447         bool wback;
11448         bool register_index;
11449 
11450         switch (encoding)
11451         {
11452             case eEncodingT1:
11453             case eEncodingA1:
11454             {
11455                 // case type of
11456                     // when '0111'
11457                         // regs = 1; if align<1> == '1' then UNDEFINED;
11458                     // when '1010'
11459                         // regs = 2; if align == '11' then UNDEFINED;
11460                     // when '0110'
11461                         // regs = 3; if align<1> == '1' then UNDEFINED;
11462                     // when '0010'
11463                         // regs = 4;
11464                     // otherwise
11465                         // SEE 'Related encodings';
11466                 uint32_t type = Bits32 (opcode, 11, 8);
11467                 uint32_t align = Bits32 (opcode, 5, 4);
11468                 if (type == 7) // '0111'
11469                 {
11470                     regs = 1;
11471                     if (BitIsSet (align, 1))
11472                         return false;
11473                 }
11474                 else if (type == 10) // '1010'
11475                 {
11476                     regs = 2;
11477                     if (align == 3)
11478                         return false;
11479 
11480                 }
11481                 else if (type == 6) // '0110'
11482                 {
11483                     regs = 3;
11484                     if (BitIsSet (align, 1))
11485                         return false;
11486                 }
11487                 else if (type == 2) // '0010'
11488                 {
11489                     regs = 4;
11490                 }
11491                 else
11492                     return false;
11493 
11494                 // alignment = if align == '00' then 1 else 4 << UInt(align);
11495                 if (align == 0)
11496                     alignment = 1;
11497                 else
11498                     alignment = 4 << align;
11499 
11500                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11501                 ebytes = 1 << Bits32 (opcode, 7, 6);
11502                 esize = 8 * ebytes;
11503                 elements = 8 / ebytes;
11504 
11505                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11506                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11507                 n = Bits32 (opcode, 19, 15);
11508                 m = Bits32 (opcode, 3, 0);
11509 
11510                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11511                 wback = (m != 15);
11512                 register_index = ((m != 15) && (m != 13));
11513 
11514                 // if d+regs > 32 then UNPREDICTABLE;
11515                 if ((d + regs) > 32)
11516                     return false;
11517             }
11518                 break;
11519 
11520             default:
11521                 return false;
11522         }
11523 
11524         RegisterInfo base_reg;
11525         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11526 
11527         uint32_t Rn = ReadCoreReg (n, &success);
11528         if (!success)
11529             return false;
11530 
11531         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11532         addr_t address = Rn;
11533         if ((address % alignment) != 0)
11534             return false;
11535 
11536         EmulateInstruction::Context context;
11537         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11538         if (wback)
11539         {
11540             uint32_t Rm = ReadCoreReg (m, &success);
11541             if (!success)
11542                 return false;
11543 
11544             uint32_t offset;
11545             if (register_index)
11546                 offset = Rm;
11547             else
11548                 offset = 8 * regs;
11549 
11550             uint32_t value = Rn + offset;
11551             context.type = eContextAdjustBaseRegister;
11552             context.SetRegisterPlusOffset (base_reg, offset);
11553 
11554             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11555                 return false;
11556 
11557         }
11558 
11559         // for r = 0 to regs-1
11560         for (uint32_t r = 0; r < regs; ++r)
11561         {
11562             // for e = 0 to elements-1
11563             uint64_t assembled_data = 0;
11564             for (uint32_t e = 0; e < elements; ++e)
11565             {
11566                 // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11567                 context.type = eContextRegisterLoad;
11568                 context.SetRegisterPlusOffset (base_reg, address - Rn);
11569                 uint64_t data = MemURead (context, address, ebytes, 0, &success);
11570                 if (!success)
11571                     return false;
11572 
11573                 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data
11574 
11575                 // address = address + ebytes;
11576                 address = address + ebytes;
11577             }
11578             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data))
11579                 return false;
11580         }
11581     }
11582     return true;
11583 }
11584 
11585 // A8.6.308 VLD1 (single element to one lane)
11586 //
11587 bool
11588 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding)
11589 {
11590 #if 0
11591     if ConditionPassed() then
11592         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11593         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11594         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11595         Elem[D[d],index,esize] = MemU[address,ebytes];
11596 #endif
11597 
11598     bool success = false;
11599 
11600     if (ConditionPassed (opcode))
11601     {
11602         uint32_t ebytes;
11603         uint32_t esize;
11604         uint32_t index;
11605         uint32_t alignment;
11606         uint32_t d;
11607         uint32_t n;
11608         uint32_t m;
11609         bool wback;
11610         bool register_index;
11611 
11612         switch (encoding)
11613         {
11614             case eEncodingT1:
11615             case eEncodingA1:
11616             {
11617                 uint32_t size = Bits32 (opcode, 11, 10);
11618                 uint32_t index_align = Bits32 (opcode, 7, 4);
11619                 // if size == '11' then SEE VLD1 (single element to all lanes);
11620                 if (size == 3)
11621                    return EmulateVLD1SingleAll (opcode, encoding);
11622                 // case size of
11623                 if (size == 0) // when '00'
11624                 {
11625                     // if index_align<0> != '0' then UNDEFINED;
11626                     if (BitIsClear (index_align, 0))
11627                         return false;
11628 
11629                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11630                     ebytes = 1;
11631                     esize = 8;
11632                     index = Bits32 (index_align, 3, 1);
11633                     alignment = 1;
11634                 }
11635                 else if (size == 1) // when '01'
11636                 {
11637                     // if index_align<1> != '0' then UNDEFINED;
11638                     if (BitIsClear (index_align, 1))
11639                         return false;
11640 
11641                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11642                     ebytes = 2;
11643                     esize = 16;
11644                     index = Bits32 (index_align, 3, 2);
11645 
11646                     // alignment = if index_align<0> == '0' then 1 else 2;
11647                     if (BitIsClear (index_align, 0))
11648                         alignment = 1;
11649                     else
11650                         alignment = 2;
11651                 }
11652                 else if (size == 2) // when '10'
11653                 {
11654                     // if index_align<2> != '0' then UNDEFINED;
11655                     if (BitIsClear (index_align, 2))
11656                         return false;
11657 
11658                     // if index_align<1:0> != '00' && index_align<1:0> != '11' then UNDEFINED;
11659                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11660                         return false;
11661 
11662                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11663                     ebytes = 4;
11664                     esize = 32;
11665                     index = Bit32 (index_align, 3);
11666 
11667                     // alignment = if index_align<1:0> == '00' then 1 else 4;
11668                     if (Bits32 (index_align, 1, 0) == 0)
11669                         alignment = 1;
11670                     else
11671                         alignment = 4;
11672                 }
11673                 else
11674                 {
11675                     return false;
11676                 }
11677                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11678                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11679                 n = Bits32 (opcode, 19, 16);
11680                 m = Bits32 (opcode, 3, 0);
11681 
11682                 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
11683                 wback = (m != 15);
11684                 register_index = ((m != 15) && (m != 13));
11685 
11686                 if (n == 15)
11687                     return false;
11688 
11689             }
11690                 break;
11691 
11692             default:
11693                 return false;
11694         }
11695 
11696         RegisterInfo base_reg;
11697         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11698 
11699         uint32_t Rn = ReadCoreReg (n, &success);
11700         if (!success)
11701             return false;
11702 
11703         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11704         addr_t address = Rn;
11705         if ((address % alignment) != 0)
11706             return false;
11707 
11708         EmulateInstruction::Context context;
11709         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11710         if (wback)
11711         {
11712             uint32_t Rm = ReadCoreReg (m, &success);
11713             if (!success)
11714                 return false;
11715 
11716             uint32_t offset;
11717             if (register_index)
11718                 offset = Rm;
11719             else
11720                 offset = ebytes;
11721 
11722             uint32_t value = Rn + offset;
11723 
11724             context.type = eContextAdjustBaseRegister;
11725             context.SetRegisterPlusOffset (base_reg, offset);
11726 
11727             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11728                 return false;
11729         }
11730 
11731         // Elem[D[d],index,esize] = MemU[address,ebytes];
11732         uint32_t element = MemURead (context, address, esize, 0, &success);
11733         if (!success)
11734             return false;
11735 
11736         element = element << (index * esize);
11737 
11738         uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11739         if (!success)
11740             return false;
11741 
11742         uint64_t all_ones = -1;
11743         uint64_t mask = all_ones << ((index+1) * esize);  // mask is all 1's to left of where 'element' goes, & all 0's
11744                                                           // at element & to the right of element.
11745         if (index > 0)
11746             mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes.
11747                                                                      // now mask should be 0's where element goes & 1's
11748                                                                      // everywhere else.
11749 
11750         uint64_t masked_reg = reg_data & mask;  // Take original reg value & zero out 'element' bits
11751         reg_data = masked_reg & element;        // Put 'element' into those bits in reg_data.
11752 
11753         context.type = eContextRegisterLoad;
11754         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data))
11755             return false;
11756     }
11757     return true;
11758 }
11759 
11760 // A8.6.391 VST1 (multiple single elements)
11761 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four registers, without
11762 // interleaving.  Every element of each register is stored.
11763 bool
11764 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding)
11765 {
11766 #if 0
11767     if ConditionPassed() then
11768         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11769         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11770         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11771         for r = 0 to regs-1
11772             for e = 0 to elements-1
11773                 MemU[address,ebytes] = Elem[D[d+r],e,esize];
11774                 address = address + ebytes;
11775 #endif
11776 
11777     bool success = false;
11778 
11779     if (ConditionPassed (opcode))
11780     {
11781         uint32_t regs;
11782         uint32_t alignment;
11783         uint32_t ebytes;
11784         uint32_t esize;
11785         uint32_t elements;
11786         uint32_t d;
11787         uint32_t n;
11788         uint32_t m;
11789         bool wback;
11790         bool register_index;
11791 
11792         switch (encoding)
11793         {
11794             case eEncodingT1:
11795             case eEncodingA1:
11796             {
11797                 uint32_t type = Bits32 (opcode, 11, 8);
11798                 uint32_t align = Bits32 (opcode, 5, 4);
11799 
11800                 // case type of
11801                 if (type == 7)    // when '0111'
11802                 {
11803                     // regs = 1; if align<1> == '1' then UNDEFINED;
11804                     regs = 1;
11805                     if (BitIsSet (align, 1))
11806                         return false;
11807                 }
11808                 else if (type == 10) // when '1010'
11809                 {
11810                     // regs = 2; if align == '11' then UNDEFINED;
11811                     regs = 2;
11812                     if (align == 3)
11813                         return false;
11814                 }
11815                 else if (type == 6) // when '0110'
11816                 {
11817                     // regs = 3; if align<1> == '1' then UNDEFINED;
11818                     regs = 3;
11819                     if (BitIsSet (align, 1))
11820                         return false;
11821                 }
11822                 else if (type == 2) // when '0010'
11823                     // regs = 4;
11824                     regs = 4;
11825                 else // otherwise
11826                     // SEE 'Related encodings';
11827                     return false;
11828 
11829                 // alignment = if align == '00' then 1 else 4 << UInt(align);
11830                 if (align == 0)
11831                     alignment = 1;
11832                 else
11833                     alignment = 4 << align;
11834 
11835                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11836                 ebytes = 1 << Bits32 (opcode,7, 6);
11837                 esize = 8 * ebytes;
11838                 elements = 8 / ebytes;
11839 
11840                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11841                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11842                 n = Bits32 (opcode, 19, 16);
11843                 m = Bits32 (opcode, 3, 0);
11844 
11845                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11846                 wback = (m != 15);
11847                 register_index = ((m != 15) && (m != 13));
11848 
11849                 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11850                 if ((d + regs) > 32)
11851                     return false;
11852 
11853                 if (n == 15)
11854                     return false;
11855 
11856             }
11857                 break;
11858 
11859             default:
11860                 return false;
11861         }
11862 
11863         RegisterInfo base_reg;
11864         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11865 
11866         uint32_t Rn = ReadCoreReg (n, &success);
11867         if (!success)
11868             return false;
11869 
11870         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11871         addr_t address = Rn;
11872         if ((address % alignment) != 0)
11873             return false;
11874 
11875         EmulateInstruction::Context context;
11876         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11877         if (wback)
11878         {
11879             uint32_t Rm = ReadCoreReg (m, &success);
11880             if (!success)
11881                 return false;
11882 
11883             uint32_t offset;
11884             if (register_index)
11885                 offset = Rm;
11886             else
11887                 offset = 8 * regs;
11888 
11889             context.type = eContextAdjustBaseRegister;
11890             context.SetRegisterPlusOffset (base_reg, offset);
11891 
11892             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11893                 return false;
11894         }
11895 
11896         RegisterInfo data_reg;
11897         context.type = eContextRegisterStore;
11898         // for r = 0 to regs-1
11899         for (uint32_t r = 0; r < regs; ++r)
11900         {
11901             GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
11902             uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
11903             if (!success)
11904                 return false;
11905 
11906              // for e = 0 to elements-1
11907             for (uint32_t e = 0; e < elements; ++e)
11908             {
11909                 // MemU[address,ebytes] = Elem[D[d+r],e,esize];
11910                 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize);
11911 
11912                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11913                 if (!MemUWrite (context, address, word, ebytes))
11914                     return false;
11915 
11916                 // address = address + ebytes;
11917                 address = address + ebytes;
11918             }
11919         }
11920     }
11921     return true;
11922 }
11923 
11924 // A8.6.392 VST1 (single element from one lane)
11925 // This instruction stores one element to memory from one element of a register.
11926 bool
11927 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding)
11928 {
11929 #if 0
11930     if ConditionPassed() then
11931         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11932         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11933         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11934         MemU[address,ebytes] = Elem[D[d],index,esize];
11935 #endif
11936 
11937     bool success = false;
11938 
11939     if (ConditionPassed (opcode))
11940     {
11941         uint32_t ebytes;
11942         uint32_t esize;
11943         uint32_t index;
11944         uint32_t alignment;
11945         uint32_t d;
11946         uint32_t n;
11947         uint32_t m;
11948         bool wback;
11949         bool register_index;
11950 
11951         switch (encoding)
11952         {
11953             case eEncodingT1:
11954             case eEncodingA1:
11955             {
11956                 uint32_t size = Bits32 (opcode, 11, 10);
11957                 uint32_t index_align = Bits32 (opcode, 7, 4);
11958 
11959                 // if size == '11' then UNDEFINED;
11960                 if (size == 3)
11961                     return false;
11962 
11963                 // case size of
11964                 if (size == 0) // when '00'
11965                 {
11966                     // if index_align<0> != '0' then UNDEFINED;
11967                     if (BitIsClear (index_align, 0))
11968                         return false;
11969                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11970                     ebytes = 1;
11971                     esize = 8;
11972                     index = Bits32 (index_align, 3, 1);
11973                     alignment = 1;
11974                 }
11975                 else if (size == 1) // when '01'
11976                 {
11977                     // if index_align<1> != '0' then UNDEFINED;
11978                     if (BitIsClear (index_align, 1))
11979                         return false;
11980 
11981                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11982                     ebytes = 2;
11983                     esize = 16;
11984                     index = Bits32 (index_align, 3, 2);
11985 
11986                     // alignment = if index_align<0> == '0' then 1 else 2;
11987                     if (BitIsClear (index_align, 0))
11988                         alignment = 1;
11989                     else
11990                         alignment = 2;
11991                 }
11992                 else if (size == 2) // when '10'
11993                 {
11994                     // if index_align<2> != '0' then UNDEFINED;
11995                     if (BitIsClear (index_align, 2))
11996                         return false;
11997 
11998                     // if index_align<1:0> != '00' && index_align<1:0> != '11' then UNDEFINED;
11999                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
12000                         return false;
12001 
12002                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
12003                     ebytes = 4;
12004                     esize = 32;
12005                     index = Bit32 (index_align, 3);
12006 
12007                     // alignment = if index_align<1:0> == '00' then 1 else 4;
12008                     if (Bits32 (index_align, 1, 0) == 0)
12009                         alignment = 1;
12010                     else
12011                         alignment = 4;
12012                 }
12013                 else
12014                 {
12015                     return false;
12016                 }
12017                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12018                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
12019                 n = Bits32 (opcode, 19, 16);
12020                 m = Bits32 (opcode, 3, 0);
12021 
12022                 // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15 then UNPREDICTABLE;
12023                 wback = (m != 15);
12024                 register_index = ((m != 15) && (m != 13));
12025 
12026                 if (n == 15)
12027                     return false;
12028             }
12029                 break;
12030 
12031             default:
12032                 return false;
12033         }
12034 
12035         RegisterInfo base_reg;
12036         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12037 
12038         uint32_t Rn = ReadCoreReg (n, &success);
12039         if (!success)
12040             return false;
12041 
12042         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12043         addr_t address = Rn;
12044         if ((address % alignment) != 0)
12045             return false;
12046 
12047         EmulateInstruction::Context context;
12048         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12049         if (wback)
12050         {
12051             uint32_t Rm = ReadCoreReg (m, &success);
12052             if (!success)
12053                 return false;
12054 
12055             uint32_t offset;
12056             if (register_index)
12057                 offset = Rm;
12058             else
12059                 offset = ebytes;
12060 
12061             context.type = eContextAdjustBaseRegister;
12062             context.SetRegisterPlusOffset (base_reg, offset);
12063 
12064             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
12065                 return false;
12066         }
12067 
12068         // MemU[address,ebytes] = Elem[D[d],index,esize];
12069         uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12070         if (!success)
12071             return false;
12072 
12073         uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1,  index * esize);
12074 
12075         RegisterInfo data_reg;
12076         GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg);
12077         context.type = eContextRegisterStore;
12078         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
12079 
12080         if (!MemUWrite (context, address, word, ebytes))
12081             return false;
12082     }
12083     return true;
12084 }
12085 
12086 // A8.6.309 VLD1 (single element to all lanes)
12087 // This instruction loads one element from memory into every element of one or two vectors.
12088 bool
12089 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding)
12090 {
12091 #if 0
12092     if ConditionPassed() then
12093         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12094         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12095         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12096         replicated_element = Replicate(MemU[address,ebytes], elements);
12097         for r = 0 to regs-1
12098             D[d+r] = replicated_element;
12099 #endif
12100 
12101     bool success = false;
12102 
12103     if (ConditionPassed (opcode))
12104     {
12105         uint32_t ebytes;
12106         uint32_t elements;
12107         uint32_t regs;
12108         uint32_t alignment;
12109         uint32_t d;
12110         uint32_t n;
12111         uint32_t m;
12112         bool wback;
12113         bool register_index;
12114 
12115         switch (encoding)
12116         {
12117             case eEncodingT1:
12118             case eEncodingA1:
12119             {
12120                 //if size == '11' || (size == '00' && a == '1') then UNDEFINED;
12121                 uint32_t size = Bits32 (opcode, 7, 6);
12122                 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4)))
12123                     return false;
12124 
12125                 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0' then 1 else 2;
12126                 ebytes = 1 << size;
12127                 elements = 8 / ebytes;
12128                 if (BitIsClear (opcode, 5))
12129                     regs = 1;
12130                 else
12131                     regs = 2;
12132 
12133                 //alignment = if a == '0' then 1 else ebytes;
12134                 if (BitIsClear (opcode, 4))
12135                     alignment = 1;
12136                 else
12137                     alignment = ebytes;
12138 
12139                 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12140                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
12141                 n = Bits32 (opcode, 19, 16);
12142                 m = Bits32 (opcode, 3, 0);
12143 
12144                 //wback = (m != 15); register_index = (m != 15 && m != 13);
12145                 wback = (m != 15);
12146                 register_index = ((m != 15) && (m != 13));
12147 
12148                 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12149                 if ((d + regs) > 32)
12150                     return false;
12151 
12152                 if (n == 15)
12153                     return false;
12154             }
12155             break;
12156 
12157             default:
12158                 return false;
12159         }
12160 
12161         RegisterInfo base_reg;
12162         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12163 
12164         uint32_t Rn = ReadCoreReg (n, &success);
12165         if (!success)
12166             return false;
12167 
12168         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12169         addr_t address = Rn;
12170         if ((address % alignment) != 0)
12171             return false;
12172 
12173         EmulateInstruction::Context context;
12174         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12175         if (wback)
12176         {
12177             uint32_t Rm = ReadCoreReg (m, &success);
12178             if (!success)
12179                 return false;
12180 
12181             uint32_t offset;
12182             if (register_index)
12183                 offset = Rm;
12184             else
12185                 offset = ebytes;
12186 
12187             context.type = eContextAdjustBaseRegister;
12188             context.SetRegisterPlusOffset (base_reg, offset);
12189 
12190             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
12191                 return false;
12192         }
12193 
12194         // replicated_element = Replicate(MemU[address,ebytes], elements);
12195 
12196         context.type = eContextRegisterLoad;
12197         uint64_t word = MemURead (context, address, ebytes, 0, &success);
12198         if (!success)
12199             return false;
12200 
12201         uint64_t replicated_element = 0;
12202         uint32_t esize = ebytes * 8;
12203         for (uint32_t e = 0; e < elements; ++e)
12204             replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0);
12205 
12206         // for r = 0 to regs-1
12207         for (uint32_t r = 0; r < regs; ++r)
12208         {
12209             // D[d+r] = replicated_element;
12210             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element))
12211                 return false;
12212         }
12213     }
12214     return true;
12215 }
12216 
12217 // B6.2.13 SUBS PC, LR and related instructions
12218 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack.  It subtracts the
12219 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR.
12220 bool
12221 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding)
12222 {
12223 #if 0
12224     if ConditionPassed() then
12225         EncodingSpecificOperations();
12226         if CurrentInstrSet() == InstrSet_ThumbEE then
12227             UNPREDICTABLE;
12228         operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12229         case opcode of
12230             when '0000' result = R[n] AND operand2; // AND
12231             when '0001' result = R[n] EOR operand2; // EOR
12232             when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12233             when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12234             when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12235             when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12236             when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12237             when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12238             when '1100' result = R[n] OR operand2; // ORR
12239             when '1101' result = operand2; // MOV
12240             when '1110' result = R[n] AND NOT(operand2); // BIC
12241             when '1111' result = NOT(operand2); // MVN
12242         CPSRWriteByInstr(SPSR[], '1111', TRUE);
12243         BranchWritePC(result);
12244 #endif
12245 
12246     bool success = false;
12247 
12248     if (ConditionPassed (opcode))
12249     {
12250         uint32_t n;
12251         uint32_t m;
12252         uint32_t imm32;
12253         bool register_form;
12254         ARM_ShifterType shift_t;
12255         uint32_t shift_n;
12256         uint32_t code;
12257 
12258         switch (encoding)
12259         {
12260             case eEncodingT1:
12261                 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
12262                 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010'; // = SUB
12263                 n = 14;
12264                 imm32 = Bits32 (opcode, 7, 0);
12265                 register_form = false;
12266                 code = 2;
12267 
12268                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12269                 if (InITBlock() && !LastInITBlock())
12270                     return false;
12271 
12272                 break;
12273 
12274             case eEncodingA1:
12275                 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12276                 n = Bits32 (opcode, 19, 16);
12277                 imm32 = ARMExpandImm (opcode);
12278                 register_form = false;
12279                 code = Bits32 (opcode, 24, 21);
12280 
12281                 break;
12282 
12283             case eEncodingA2:
12284                 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12285                 n = Bits32 (opcode, 19, 16);
12286                 m = Bits32 (opcode, 3, 0);
12287                 register_form = true;
12288 
12289                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12290                 shift_n = DecodeImmShiftARM (opcode, shift_t);
12291 
12292                 break;
12293 
12294             default:
12295                 return false;
12296         }
12297 
12298         // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12299         uint32_t operand2;
12300         if (register_form)
12301         {
12302             uint32_t Rm = ReadCoreReg (m, &success);
12303             if (!success)
12304                 return false;
12305 
12306             operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success);
12307             if (!success)
12308                 return false;
12309         }
12310         else
12311         {
12312             operand2 = imm32;
12313         }
12314 
12315         uint32_t Rn = ReadCoreReg (n, &success);
12316         if (!success)
12317             return false;
12318 
12319         AddWithCarryResult result;
12320 
12321         // case opcode of
12322         switch (code)
12323         {
12324             case 0: // when '0000'
12325                 // result = R[n] AND operand2; // AND
12326                 result.result = Rn & operand2;
12327                 break;
12328 
12329             case 1: // when '0001'
12330                 // result = R[n] EOR operand2; // EOR
12331                 result.result = Rn ^ operand2;
12332                 break;
12333 
12334             case 2: // when '0010'
12335                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12336                 result = AddWithCarry (Rn, ~(operand2), 1);
12337                 break;
12338 
12339             case 3: // when '0011'
12340                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12341                 result = AddWithCarry (~(Rn), operand2, 1);
12342                 break;
12343 
12344             case 4: // when '0100'
12345                 // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12346                 result = AddWithCarry (Rn, operand2, 0);
12347                 break;
12348 
12349             case 5: // when '0101'
12350                 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12351                 result = AddWithCarry (Rn, operand2, APSR_C);
12352                 break;
12353 
12354             case 6: // when '0110'
12355                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12356                 result = AddWithCarry (Rn, ~(operand2), APSR_C);
12357                 break;
12358 
12359             case 7: // when '0111'
12360                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12361                 result = AddWithCarry (~(Rn), operand2, APSR_C);
12362                 break;
12363 
12364             case 10: // when '1100'
12365                 // result = R[n] OR operand2; // ORR
12366                 result.result = Rn | operand2;
12367                 break;
12368 
12369             case 11: // when '1101'
12370                 // result = operand2; // MOV
12371                 result.result = operand2;
12372                 break;
12373 
12374             case 12: // when '1110'
12375                 // result = R[n] AND NOT(operand2); // BIC
12376                 result.result = Rn & ~(operand2);
12377                 break;
12378 
12379             case 15: // when '1111'
12380                 // result = NOT(operand2); // MVN
12381                 result.result = ~(operand2);
12382                 break;
12383 
12384             default:
12385                 return false;
12386         }
12387         // CPSRWriteByInstr(SPSR[], '1111', TRUE);
12388 
12389         // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for
12390         // the best.
12391         uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12392         if (!success)
12393             return false;
12394 
12395         CPSRWriteByInstr (spsr, 15, true);
12396 
12397         // BranchWritePC(result);
12398         EmulateInstruction::Context context;
12399         context.type = eContextAdjustPC;
12400         context.SetImmediate (result.result);
12401 
12402         BranchWritePC (context, result.result);
12403     }
12404     return true;
12405 }
12406 
12407 EmulateInstructionARM::ARMOpcode*
12408 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12409 {
12410     static ARMOpcode
12411     g_arm_opcodes[] =
12412     {
12413         //----------------------------------------------------------------------
12414         // Prologue instructions
12415         //----------------------------------------------------------------------
12416 
12417         // push register(s)
12418         { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12419         { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
12420 
12421         // set r7 to point to a stack offset
12422         { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
12423         { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12424         // copy the stack pointer to ip
12425         { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
12426         { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
12427         { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12428 
12429         // adjust the stack pointer
12430         { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12431         { 0x0fef0010, 0x004d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12432 
12433         // push one register
12434         // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12435         { 0x0e5f0000, 0x040d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
12436 
12437         // vector push consecutive extension register(s)
12438         { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12439         { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12440 
12441         //----------------------------------------------------------------------
12442         // Epilogue instructions
12443         //----------------------------------------------------------------------
12444 
12445         { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12446         { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12447         { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12448         { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12449 
12450         //----------------------------------------------------------------------
12451         // Supervisor Call (previously Software Interrupt)
12452         //----------------------------------------------------------------------
12453         { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12454 
12455         //----------------------------------------------------------------------
12456         // Branch instructions
12457         //----------------------------------------------------------------------
12458         // To resolve ambiguity, "blx <label>" should come before "b #imm24" and "bl <label>".
12459         { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12460         { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
12461         { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12462         { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12463         // for example, "bx lr"
12464         { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12465         // bxj
12466         { 0x0ffffff0, 0x012fff20, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12467 
12468         //----------------------------------------------------------------------
12469         // Data-processing instructions
12470         //----------------------------------------------------------------------
12471         // adc (immediate)
12472         { 0x0fe00000, 0x02a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12473         // adc (register)
12474         { 0x0fe00010, 0x00a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12475         // add (immediate)
12476         { 0x0fe00000, 0x02800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
12477         // add (register)
12478         { 0x0fe00010, 0x00800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12479         // add (register-shifted register)
12480         { 0x0fe00090, 0x00800010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12481         // adr
12482         { 0x0fff0000, 0x028f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12483         { 0x0fff0000, 0x024f0000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12484         // and (immediate)
12485         { 0x0fe00000, 0x02000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12486         // and (register)
12487         { 0x0fe00010, 0x00000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12488         // bic (immediate)
12489         { 0x0fe00000, 0x03c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12490         // bic (register)
12491         { 0x0fe00010, 0x01c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12492         // eor (immediate)
12493         { 0x0fe00000, 0x02200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12494         // eor (register)
12495         { 0x0fe00010, 0x00200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12496         // orr (immediate)
12497         { 0x0fe00000, 0x03800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12498         // orr (register)
12499         { 0x0fe00010, 0x01800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12500         // rsb (immediate)
12501         { 0x0fe00000, 0x02600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12502         // rsb (register)
12503         { 0x0fe00010, 0x00600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12504         // rsc (immediate)
12505         { 0x0fe00000, 0x02e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12506         // rsc (register)
12507         { 0x0fe00010, 0x00e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12508         // sbc (immediate)
12509         { 0x0fe00000, 0x02c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12510         // sbc (register)
12511         { 0x0fe00010, 0x00c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12512         // sub (immediate, ARM)
12513         { 0x0fe00000, 0x02400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
12514         // sub (sp minus immediate)
12515         { 0x0fef0000, 0x024d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12516         // sub (register)
12517         { 0x0fe00010, 0x00400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12518         // teq (immediate)
12519         { 0x0ff0f000, 0x03300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12520         // teq (register)
12521         { 0x0ff0f010, 0x01300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12522         // tst (immediate)
12523         { 0x0ff0f000, 0x03100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12524         // tst (register)
12525         { 0x0ff0f010, 0x01100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12526 
12527         // mov (immediate)
12528         { 0x0fef0000, 0x03a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12529         { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
12530         // mov (register)
12531         { 0x0fef0ff0, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12532         // mvn (immediate)
12533         { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12534         // mvn (register)
12535         { 0x0fef0010, 0x01e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12536         // cmn (immediate)
12537         { 0x0ff0f000, 0x03700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12538         // cmn (register)
12539         { 0x0ff0f010, 0x01700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12540         // cmp (immediate)
12541         { 0x0ff0f000, 0x03500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
12542         // cmp (register)
12543         { 0x0ff0f010, 0x01500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
12544         // asr (immediate)
12545         { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
12546         // asr (register)
12547         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
12548         // lsl (immediate)
12549         { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
12550         // lsl (register)
12551         { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
12552         // lsr (immediate)
12553         { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
12554         // lsr (register)
12555         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
12556         // rrx is a special case encoding of ror (immediate)
12557         { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
12558         // ror (immediate)
12559         { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
12560         // ror (register)
12561         { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
12562         // mul
12563         { 0x0fe000f0, 0x00000090, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
12564 
12565         // subs pc, lr and related instructions
12566         { 0x0e10f000, 0x0210f000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" },
12567         { 0x0e10f010, 0x0010f000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" },
12568 
12569         //----------------------------------------------------------------------
12570         // Load instructions
12571         //----------------------------------------------------------------------
12572         { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12573         { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
12574         { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12575         { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
12576         { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
12577         { 0x0e500010, 0x06100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
12578         { 0x0e5f0000, 0x045f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
12579         { 0xfe500010, 0x06500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
12580         { 0x0e5f00f0, 0x005f00b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12581         { 0x0e5000f0, 0x001000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"  },
12582         { 0x0e5000f0, 0x005000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
12583         { 0x0e5f00f0, 0x005f00d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
12584         { 0x0e5000f0, 0x001000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12585         { 0x0e5000f0, 0x005000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
12586         { 0x0e5f00f0, 0x005f00f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12587         { 0x0e5000f0, 0x001000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12588         { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
12589         { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12590         { 0x0e100f00, 0x0c100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12591         { 0x0e100f00, 0x0c100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12592         { 0x0f300f00, 0x0d100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12593         { 0x0f300f00, 0x0d100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12594         { 0xffb00000, 0xf4200000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12595         { 0xffb00300, 0xf4a00000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12596         { 0xffb00f00, 0xf4a00c00, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12597 
12598         //----------------------------------------------------------------------
12599         // Store instructions
12600         //----------------------------------------------------------------------
12601         { 0x0fd00000, 0x08800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12602         { 0x0fd00000, 0x08000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
12603         { 0x0fd00000, 0x09000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12604         { 0x0fd00000, 0x09800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
12605         { 0x0e500010, 0x06000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
12606         { 0x0e5000f0, 0x000000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
12607         { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
12608         { 0x0e500000, 0x04400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12609         { 0x0e500000, 0x04000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12610         { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
12611         { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12612         { 0x0e100f00, 0x0c000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12613         { 0x0e100f00, 0x0c000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12614         { 0x0f300f00, 0x0d000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
12615         { 0x0f300f00, 0x0d000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
12616         { 0xffb00000, 0xf4000000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12617         { 0xffb00300, 0xf4800000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12618 
12619         //----------------------------------------------------------------------
12620         // Other instructions
12621         //----------------------------------------------------------------------
12622         { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
12623         { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
12624         { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
12625         { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
12626         { 0xfe500000, 0xf8100000, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
12627 
12628     };
12629     static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes);
12630 
12631     for (size_t i=0; i<k_num_arm_opcodes; ++i)
12632     {
12633         if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
12634             (g_arm_opcodes[i].variants & arm_isa) != 0)
12635             return &g_arm_opcodes[i];
12636     }
12637     return NULL;
12638 }
12639 
12640 
12641 EmulateInstructionARM::ARMOpcode*
12642 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12643 {
12644 
12645     static ARMOpcode
12646     g_thumb_opcodes[] =
12647     {
12648         //----------------------------------------------------------------------
12649         // Prologue instructions
12650         //----------------------------------------------------------------------
12651 
12652         // push register(s)
12653         { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12654         { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
12655         { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
12656 
12657         // set r7 to point to a stack offset
12658         { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
12659         // copy the stack pointer to r7
12660         { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
12661         // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
12662         { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
12663 
12664         // PC-relative load into register (see also EmulateADDSPRm)
12665         { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
12666 
12667         // adjust the stack pointer
12668         { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
12669         { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
12670         { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
12671         { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
12672         { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12673 
12674         // vector push consecutive extension register(s)
12675         { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12676         { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12677 
12678         //----------------------------------------------------------------------
12679         // Epilogue instructions
12680         //----------------------------------------------------------------------
12681 
12682         { 0xfffff800, 0x0000a800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
12683         { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
12684         { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12685         { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
12686         { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
12687         { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12688         { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12689 
12690         //----------------------------------------------------------------------
12691         // Supervisor Call (previously Software Interrupt)
12692         //----------------------------------------------------------------------
12693         { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
12694 
12695         //----------------------------------------------------------------------
12696         // If Then makes up to four following instructions conditional.
12697         //----------------------------------------------------------------------
12698         // The next 5 opcode _must_ come before the if then instruction
12699         { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"},
12700         { 0xffffffff, 0x0000bf10, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
12701         { 0xffffffff, 0x0000bf20, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
12702         { 0xffffffff, 0x0000bf30, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
12703         { 0xffffffff, 0x0000bf40, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
12704         { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
12705 
12706         //----------------------------------------------------------------------
12707         // Branch instructions
12708         //----------------------------------------------------------------------
12709         // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
12710         { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
12711         { 0xfffff800, 0x0000e000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
12712         { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
12713         { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
12714         // J1 == J2 == 1
12715         { 0xf800d000, 0xf000d000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12716         // J1 == J2 == 1
12717         { 0xf800d001, 0xf000c000, ARMV5_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12718         { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12719         // for example, "bx lr"
12720         { 0xffffff87, 0x00004700, ARMvAll,       eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12721         // bxj
12722         { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12723         // compare and branch
12724         { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
12725         // table branch byte
12726         { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
12727         // table branch halfword
12728         { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
12729 
12730         //----------------------------------------------------------------------
12731         // Data-processing instructions
12732         //----------------------------------------------------------------------
12733         // adc (immediate)
12734         { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
12735         // adc (register)
12736         { 0xffffffc0, 0x00004140, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
12737         { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12738         // add (register)
12739         { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
12740         // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
12741         { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
12742         // adr
12743         { 0xfffff800, 0x0000a000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12744         { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12745         { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12746         // and (immediate)
12747         { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
12748         // and (register)
12749         { 0xffffffc0, 0x00004000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
12750         { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12751         // bic (immediate)
12752         { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
12753         // bic (register)
12754         { 0xffffffc0, 0x00004380, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
12755         { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12756         // eor (immediate)
12757         { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
12758         // eor (register)
12759         { 0xffffffc0, 0x00004040, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
12760         { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12761         // orr (immediate)
12762         { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
12763         // orr (register)
12764         { 0xffffffc0, 0x00004300, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
12765         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12766         // rsb (immediate)
12767         { 0xffffffc0, 0x00004240, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
12768         { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
12769         // rsb (register)
12770         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12771         // sbc (immediate)
12772         { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12773         // sbc (register)
12774         { 0xffffffc0, 0x00004180, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
12775         { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12776         // add (immediate, Thumb)
12777         { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
12778         { 0xfffff800, 0x00003000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
12779         { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
12780         { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
12781         // sub (immediate, Thumb)
12782         { 0xfffffe00, 0x00001e00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
12783         { 0xfffff800, 0x00003800, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
12784         { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
12785         { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
12786         // sub (sp minus immediate)
12787         { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
12788         { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
12789         // sub (register)
12790         { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
12791         { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
12792         // teq (immediate)
12793         { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
12794         // teq (register)
12795         { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12796         // tst (immediate)
12797         { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
12798         // tst (register)
12799         { 0xffffffc0, 0x00004200, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
12800         { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
12801 
12802 
12803         // move from high register to high register
12804         { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
12805         // move from low register to low register
12806         { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
12807         // mov{s}<c>.w <Rd>, <Rm>
12808         { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
12809         // move immediate
12810         { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
12811         { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
12812         { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
12813         // mvn (immediate)
12814         { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
12815         // mvn (register)
12816         { 0xffffffc0, 0x000043c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
12817         { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
12818         // cmn (immediate)
12819         { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12820         // cmn (register)
12821         { 0xffffffc0, 0x000042c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
12822         { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12823         // cmp (immediate)
12824         { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
12825         { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
12826         // cmp (register) (Rn and Rm both from r0-r7)
12827         { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12828         // cmp (register) (Rn and Rm not both from r0-r7)
12829         { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12830         { 0xfff08f00, 0xebb00f00, ARMvAll,       eEncodingT3, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c>.w <Rn>, <Rm> {, <shift>}"},
12831         // asr (immediate)
12832         { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
12833         { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
12834         // asr (register)
12835         { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
12836         { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12837         // lsl (immediate)
12838         { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
12839         { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
12840         // lsl (register)
12841         { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
12842         { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
12843         // lsr (immediate)
12844         { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
12845         { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
12846         // lsr (register)
12847         { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
12848         { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12849         // rrx is a special case encoding of ror (immediate)
12850         { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
12851         // ror (immediate)
12852         { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
12853         // ror (register)
12854         { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
12855         { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
12856         // mul
12857         { 0xffffffc0, 0x00004340, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
12858         // mul
12859         { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
12860 
12861         // subs pc, lr and related instructions
12862         { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" },
12863 
12864         //----------------------------------------------------------------------
12865         // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table;
12866         // otherwise the wrong instructions will be selected.
12867         //----------------------------------------------------------------------
12868 
12869         { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
12870         { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
12871 
12872         //----------------------------------------------------------------------
12873         // Load instructions
12874         //----------------------------------------------------------------------
12875         { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12876         { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
12877         { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12878         { 0xfffff800, 0x00006800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
12879         { 0xfffff800, 0x00009800, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
12880         { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
12881         { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
12882                   // Thumb2 PC-relative load into register
12883         { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
12884         { 0xfffffe00, 0x00005800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
12885         { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
12886         { 0xfffff800, 0x00007800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
12887         { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12888         { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" },
12889         { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
12890         { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
12891         { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
12892         { 0xfffff800, 0x00008800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"  },
12893         { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12894         { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"  },
12895         { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12896         { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
12897         { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12898         { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
12899         { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12900         { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
12901         { 0xfffffe00, 0x00005600, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
12902         { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"  },
12903         { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
12904         { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12905         { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12906         { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
12907         { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12908         { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
12909         { 0xfe100f00, 0xec100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12910         { 0xfe100f00, 0xec100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
12911         { 0xffe00f00, 0xed100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12912         { 0xff300f00, 0xed100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
12913         { 0xffb00000, 0xf9200000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12914         { 0xffb00300, 0xf9a00000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12915         { 0xffb00f00, 0xf9a00c00, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12916 
12917         //----------------------------------------------------------------------
12918         // Store instructions
12919         //----------------------------------------------------------------------
12920         { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12921         { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
12922         { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12923         { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
12924         { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
12925         { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
12926         { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
12927         { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
12928         { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
12929         { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
12930         { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
12931         { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
12932         { 0xfffffe00, 0x00005200, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
12933         { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12934         { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
12935         { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
12936         { 0xfe100f00, 0xec000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12937         { 0xfea00f00, 0xec000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12938         { 0xff300f00, 0xed000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12939         { 0xff300f00, 0xed000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12940         { 0xffb00000, 0xf9000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12941         { 0xffb00300, 0xf9800000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12942 
12943         //----------------------------------------------------------------------
12944         // Other instructions
12945         //----------------------------------------------------------------------
12946         { 0xffffffc0, 0x0000b240, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
12947         { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12948         { 0xffffffc0, 0x0000b200, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
12949         { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12950         { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
12951         { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12952         { 0xffffffc0, 0x0000b280, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
12953         { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12954     };
12955 
12956     const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes);
12957     for (size_t i=0; i<k_num_thumb_opcodes; ++i)
12958     {
12959         if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
12960             (g_thumb_opcodes[i].variants & arm_isa) != 0)
12961             return &g_thumb_opcodes[i];
12962     }
12963     return NULL;
12964 }
12965 
12966 bool
12967 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
12968 {
12969     m_arch = arch;
12970     m_arm_isa = 0;
12971     const char *arch_cstr = arch.GetArchitectureName ();
12972     if (arch_cstr)
12973     {
12974         if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
12975         else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
12976         else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
12977         else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
12978         else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
12979         else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
12980         else if (0 == ::strcasecmp(arch_cstr, "armv7s"))    m_arm_isa = ARMv7S;
12981         else if (0 == ::strcasecmp(arch_cstr, "arm"))       m_arm_isa = ARMvAll;
12982         else if (0 == ::strcasecmp(arch_cstr, "thumb"))     m_arm_isa = ARMvAll;
12983         else if (0 == ::strncasecmp(arch_cstr,"armv4", 5))  m_arm_isa = ARMv4;
12984         else if (0 == ::strncasecmp(arch_cstr,"armv6", 5))  m_arm_isa = ARMv6;
12985         else if (0 == ::strncasecmp(arch_cstr,"armv7", 5))  m_arm_isa = ARMv7;
12986         else if (0 == ::strncasecmp(arch_cstr,"armv8", 5))  m_arm_isa = ARMv8;
12987     }
12988     return m_arm_isa != 0;
12989 }
12990 
12991 bool
12992 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
12993 {
12994     if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
12995     {
12996         if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
12997             m_opcode_mode = eModeThumb;
12998         else
12999         {
13000             AddressClass addr_class = inst_addr.GetAddressClass();
13001 
13002             if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
13003                 m_opcode_mode = eModeARM;
13004             else if (addr_class == eAddressClassCodeAlternateISA)
13005                 m_opcode_mode = eModeThumb;
13006             else
13007                 return false;
13008         }
13009         if (m_opcode_mode == eModeThumb)
13010             m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
13011         else
13012             m_opcode_cpsr = CPSR_MODE_USR;
13013         return true;
13014     }
13015     return false;
13016 }
13017 
13018 bool
13019 EmulateInstructionARM::ReadInstruction ()
13020 {
13021     bool success = false;
13022     m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
13023     if (success)
13024     {
13025         addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
13026         if (success)
13027         {
13028             Context read_inst_context;
13029             read_inst_context.type = eContextReadOpcode;
13030             read_inst_context.SetNoArgs ();
13031 
13032             if (m_opcode_cpsr & MASK_CPSR_T)
13033             {
13034                 m_opcode_mode = eModeThumb;
13035                 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
13036 
13037                 if (success)
13038                 {
13039                     if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
13040                     {
13041                         m_opcode.SetOpcode16 (thumb_opcode, GetByteOrder());
13042                     }
13043                     else
13044                     {
13045                         m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success), GetByteOrder());
13046                     }
13047                 }
13048             }
13049             else
13050             {
13051                 m_opcode_mode = eModeARM;
13052                 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success), GetByteOrder());
13053             }
13054         }
13055     }
13056     if (!success)
13057     {
13058         m_opcode_mode = eModeInvalid;
13059         m_addr = LLDB_INVALID_ADDRESS;
13060     }
13061     return success;
13062 }
13063 
13064 uint32_t
13065 EmulateInstructionARM::ArchVersion ()
13066 {
13067     return m_arm_isa;
13068 }
13069 
13070 bool
13071 EmulateInstructionARM::ConditionPassed (const uint32_t opcode)
13072 {
13073    // If we are ignoring conditions, then always return true.
13074    // this allows us to iterate over disassembly code and still
13075    // emulate an instruction even if we don't have all the right
13076    // bits set in the CPSR register...
13077     if (m_ignore_conditions)
13078         return true;
13079 
13080     const uint32_t cond = CurrentCond (opcode);
13081     if (cond == UINT32_MAX)
13082         return false;
13083 
13084     bool result = false;
13085     switch (UnsignedBits(cond, 3, 1))
13086     {
13087     case 0:
13088 		if (m_opcode_cpsr == 0)
13089 			result = true;
13090         else
13091             result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
13092 		break;
13093     case 1:
13094         if (m_opcode_cpsr == 0)
13095             result = true;
13096         else
13097             result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
13098 		break;
13099     case 2:
13100         if (m_opcode_cpsr == 0)
13101             result = true;
13102         else
13103             result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
13104 		break;
13105     case 3:
13106         if (m_opcode_cpsr == 0)
13107             result = true;
13108         else
13109             result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
13110 		break;
13111     case 4:
13112         if (m_opcode_cpsr == 0)
13113             result = true;
13114         else
13115             result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13116 		break;
13117     case 5:
13118         if (m_opcode_cpsr == 0)
13119             result = true;
13120         else
13121 		{
13122             bool n = (m_opcode_cpsr & MASK_CPSR_N);
13123             bool v = (m_opcode_cpsr & MASK_CPSR_V);
13124             result = n == v;
13125         }
13126         break;
13127     case 6:
13128         if (m_opcode_cpsr == 0)
13129             result = true;
13130         else
13131 		{
13132             bool n = (m_opcode_cpsr & MASK_CPSR_N);
13133             bool v = (m_opcode_cpsr & MASK_CPSR_V);
13134             result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13135         }
13136         break;
13137     case 7:
13138         // Always execute (cond == 0b1110, or the special 0b1111 which gives
13139         // opcodes different meanings, but always means execution happens.
13140         return true;
13141     }
13142 
13143     if (cond & 1)
13144         result = !result;
13145     return result;
13146 }
13147 
13148 uint32_t
13149 EmulateInstructionARM::CurrentCond (const uint32_t opcode)
13150 {
13151     switch (m_opcode_mode)
13152     {
13153     case eModeInvalid:
13154         break;
13155 
13156     case eModeARM:
13157         return UnsignedBits(opcode, 31, 28);
13158 
13159     case eModeThumb:
13160         // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
13161         // 'cond' field of the encoding.
13162         {
13163             const uint32_t byte_size = m_opcode.GetByteSize();
13164             if (byte_size == 2)
13165             {
13166                 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f)
13167                     return Bits32(opcode, 11, 8);
13168             }
13169             else if (byte_size == 4)
13170             {
13171                 if (Bits32(opcode, 31, 27) == 0x1e &&
13172                     Bits32(opcode, 15, 14) == 0x02 &&
13173                     Bits32(opcode, 12, 12) == 0x00 &&
13174                     Bits32(opcode, 25, 22) <= 0x0d)
13175                 {
13176                     return Bits32(opcode, 25, 22);
13177                 }
13178             }
13179             else
13180                 // We have an invalid thumb instruction, let's bail out.
13181                 break;
13182 
13183             return m_it_session.GetCond();
13184         }
13185     }
13186     return UINT32_MAX;  // Return invalid value
13187 }
13188 
13189 bool
13190 EmulateInstructionARM::InITBlock()
13191 {
13192     return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13193 }
13194 
13195 bool
13196 EmulateInstructionARM::LastInITBlock()
13197 {
13198     return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13199 }
13200 
13201 bool
13202 EmulateInstructionARM::BadMode (uint32_t mode)
13203 {
13204 
13205     switch (mode)
13206     {
13207         case 16: return false; // '10000'
13208         case 17: return false; // '10001'
13209         case 18: return false; // '10010'
13210         case 19: return false; // '10011'
13211         case 22: return false; // '10110'
13212         case 23: return false; // '10111'
13213         case 27: return false; // '11011'
13214         case 31: return false; // '11111'
13215         default: return true;
13216     }
13217     return true;
13218 }
13219 
13220 bool
13221 EmulateInstructionARM::CurrentModeIsPrivileged ()
13222 {
13223     uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
13224 
13225     if (BadMode (mode))
13226         return false;
13227 
13228     if (mode == 16)
13229         return false;
13230 
13231     return true;
13232 }
13233 
13234 void
13235 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
13236 {
13237     bool privileged = CurrentModeIsPrivileged();
13238 
13239     uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20;
13240 
13241     if (BitIsSet (bytemask, 3))
13242     {
13243         tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
13244         if (affect_execstate)
13245             tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
13246     }
13247 
13248     if (BitIsSet (bytemask, 2))
13249     {
13250         tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
13251     }
13252 
13253     if (BitIsSet (bytemask, 1))
13254     {
13255         if (affect_execstate)
13256             tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
13257         tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
13258         if (privileged)
13259             tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
13260     }
13261 
13262     if (BitIsSet (bytemask, 0))
13263     {
13264         if (privileged)
13265             tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
13266         if (affect_execstate)
13267             tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
13268         if (privileged)
13269             tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
13270     }
13271 
13272     m_opcode_cpsr = tmp_cpsr;
13273 }
13274 
13275 
13276 bool
13277 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
13278 {
13279     addr_t target;
13280 
13281     // Check the current instruction set.
13282     if (CurrentInstrSet() == eModeARM)
13283         target = addr & 0xfffffffc;
13284     else
13285         target = addr & 0xfffffffe;
13286 
13287     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13288         return false;
13289 
13290     return true;
13291 }
13292 
13293 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
13294 bool
13295 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
13296 {
13297     addr_t target;
13298     // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
13299     // we want to record it and issue a WriteRegister callback so the clients
13300     // can track the mode changes accordingly.
13301     bool cpsr_changed = false;
13302 
13303     if (BitIsSet(addr, 0))
13304     {
13305         if (CurrentInstrSet() != eModeThumb)
13306         {
13307             SelectInstrSet(eModeThumb);
13308             cpsr_changed = true;
13309         }
13310         target = addr & 0xfffffffe;
13311         context.SetISA (eModeThumb);
13312     }
13313     else if (BitIsClear(addr, 1))
13314     {
13315         if (CurrentInstrSet() != eModeARM)
13316         {
13317             SelectInstrSet(eModeARM);
13318             cpsr_changed = true;
13319         }
13320         target = addr & 0xfffffffc;
13321         context.SetISA (eModeARM);
13322     }
13323     else
13324         return false; // address<1:0> == '10' => UNPREDICTABLE
13325 
13326     if (cpsr_changed)
13327     {
13328         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13329             return false;
13330     }
13331     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13332         return false;
13333 
13334     return true;
13335 }
13336 
13337 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
13338 bool
13339 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
13340 {
13341     if (ArchVersion() >= ARMv5T)
13342         return BXWritePC(context, addr);
13343     else
13344         return BranchWritePC((const Context)context, addr);
13345 }
13346 
13347 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
13348 bool
13349 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
13350 {
13351     if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
13352         return BXWritePC(context, addr);
13353     else
13354         return BranchWritePC((const Context)context, addr);
13355 }
13356 
13357 EmulateInstructionARM::Mode
13358 EmulateInstructionARM::CurrentInstrSet ()
13359 {
13360     return m_opcode_mode;
13361 }
13362 
13363 // Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
13364 // ReadInstruction() is performed.  This function has a side effect of updating
13365 // the m_new_inst_cpsr member variable if necessary.
13366 bool
13367 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
13368 {
13369     m_new_inst_cpsr = m_opcode_cpsr;
13370     switch (arm_or_thumb)
13371     {
13372     default:
13373         return false;
13374     case eModeARM:
13375         // Clear the T bit.
13376         m_new_inst_cpsr &= ~MASK_CPSR_T;
13377         break;
13378     case eModeThumb:
13379         // Set the T bit.
13380         m_new_inst_cpsr |= MASK_CPSR_T;
13381         break;
13382     }
13383     return true;
13384 }
13385 
13386 // This function returns TRUE if the processor currently provides support for
13387 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
13388 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
13389 bool
13390 EmulateInstructionARM::UnalignedSupport()
13391 {
13392     return (ArchVersion() >= ARMv7);
13393 }
13394 
13395 // The main addition and subtraction instructions can produce status information
13396 // about both unsigned carry and signed overflow conditions.  This status
13397 // information can be used to synthesize multi-word additions and subtractions.
13398 EmulateInstructionARM::AddWithCarryResult
13399 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
13400 {
13401     uint32_t result;
13402     uint8_t carry_out;
13403     uint8_t overflow;
13404 
13405     uint64_t unsigned_sum = x + y + carry_in;
13406     int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
13407 
13408     result = UnsignedBits(unsigned_sum, 31, 0);
13409 //    carry_out = (result == unsigned_sum ? 0 : 1);
13410     overflow = ((int32_t)result == signed_sum ? 0 : 1);
13411 
13412     if (carry_in)
13413         carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0;
13414     else
13415         carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0;
13416 
13417     AddWithCarryResult res = { result, carry_out, overflow };
13418     return res;
13419 }
13420 
13421 uint32_t
13422 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
13423 {
13424     lldb::RegisterKind reg_kind;
13425     uint32_t reg_num;
13426     switch (num)
13427     {
13428     case SP_REG:
13429         reg_kind = eRegisterKindGeneric;
13430         reg_num  = LLDB_REGNUM_GENERIC_SP;
13431         break;
13432     case LR_REG:
13433         reg_kind = eRegisterKindGeneric;
13434         reg_num  = LLDB_REGNUM_GENERIC_RA;
13435         break;
13436     case PC_REG:
13437         reg_kind = eRegisterKindGeneric;
13438         reg_num  = LLDB_REGNUM_GENERIC_PC;
13439         break;
13440     default:
13441         if (num < SP_REG)
13442         {
13443             reg_kind = eRegisterKindDWARF;
13444             reg_num  = dwarf_r0 + num;
13445         }
13446         else
13447         {
13448             //assert(0 && "Invalid register number");
13449             *success = false;
13450             return UINT32_MAX;
13451         }
13452         break;
13453     }
13454 
13455     // Read our register.
13456     uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
13457 
13458     // When executing an ARM instruction , PC reads as the address of the current
13459     // instruction plus 8.
13460     // When executing a Thumb instruction , PC reads as the address of the current
13461     // instruction plus 4.
13462     if (num == 15)
13463     {
13464         if (CurrentInstrSet() == eModeARM)
13465             val += 8;
13466         else
13467             val += 4;
13468     }
13469 
13470     return val;
13471 }
13472 
13473 // Write the result to the ARM core register Rd, and optionally update the
13474 // condition flags based on the result.
13475 //
13476 // This helper method tries to encapsulate the following pseudocode from the
13477 // ARM Architecture Reference Manual:
13478 //
13479 // if d == 15 then         // Can only occur for encoding A1
13480 //     ALUWritePC(result); // setflags is always FALSE here
13481 // else
13482 //     R[d] = result;
13483 //     if setflags then
13484 //         APSR.N = result<31>;
13485 //         APSR.Z = IsZeroBit(result);
13486 //         APSR.C = carry;
13487 //         // APSR.V unchanged
13488 //
13489 // In the above case, the API client does not pass in the overflow arg, which
13490 // defaults to ~0u.
13491 bool
13492 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
13493                                                   const uint32_t result,
13494                                                   const uint32_t Rd,
13495                                                   bool setflags,
13496                                                   const uint32_t carry,
13497                                                   const uint32_t overflow)
13498 {
13499     if (Rd == 15)
13500     {
13501         if (!ALUWritePC (context, result))
13502             return false;
13503     }
13504     else
13505     {
13506         lldb::RegisterKind reg_kind;
13507         uint32_t reg_num;
13508         switch (Rd)
13509         {
13510         case SP_REG:
13511             reg_kind = eRegisterKindGeneric;
13512             reg_num  = LLDB_REGNUM_GENERIC_SP;
13513             break;
13514         case LR_REG:
13515             reg_kind = eRegisterKindGeneric;
13516             reg_num  = LLDB_REGNUM_GENERIC_RA;
13517             break;
13518         default:
13519             reg_kind = eRegisterKindDWARF;
13520             reg_num  = dwarf_r0 + Rd;
13521         }
13522         if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
13523             return false;
13524         if (setflags)
13525             return WriteFlags (context, result, carry, overflow);
13526     }
13527     return true;
13528 }
13529 
13530 // This helper method tries to encapsulate the following pseudocode from the
13531 // ARM Architecture Reference Manual:
13532 //
13533 // APSR.N = result<31>;
13534 // APSR.Z = IsZeroBit(result);
13535 // APSR.C = carry;
13536 // APSR.V = overflow
13537 //
13538 // Default arguments can be specified for carry and overflow parameters, which means
13539 // not to update the respective flags.
13540 bool
13541 EmulateInstructionARM::WriteFlags (Context &context,
13542                                    const uint32_t result,
13543                                    const uint32_t carry,
13544                                    const uint32_t overflow)
13545 {
13546     m_new_inst_cpsr = m_opcode_cpsr;
13547     SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
13548     SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
13549     if (carry != ~0u)
13550         SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
13551     if (overflow != ~0u)
13552         SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
13553     if (m_new_inst_cpsr != m_opcode_cpsr)
13554     {
13555         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13556             return false;
13557     }
13558     return true;
13559 }
13560 
13561 bool
13562 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
13563 {
13564     // Advance the ITSTATE bits to their values for the next instruction.
13565     if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
13566         m_it_session.ITAdvance();
13567 
13568     ARMOpcode *opcode_data = NULL;
13569 
13570     if (m_opcode_mode == eModeThumb)
13571         opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13572     else if (m_opcode_mode == eModeARM)
13573         opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13574 
13575     if (opcode_data == NULL)
13576         return false;
13577 
13578     const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
13579     m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
13580 
13581     bool success = false;
13582     if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
13583     {
13584         m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF,
13585                                                 dwarf_cpsr,
13586                                                 0,
13587                                                 &success);
13588     }
13589 
13590     // Only return false if we are unable to read the CPSR if we care about conditions
13591     if (success == false && m_ignore_conditions == false)
13592         return false;
13593 
13594     uint32_t orig_pc_value = 0;
13595     if (auto_advance_pc)
13596     {
13597         orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13598         if (!success)
13599             return false;
13600     }
13601 
13602     // Call the Emulate... function.
13603     success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
13604     if (!success)
13605         return false;
13606 
13607     if (auto_advance_pc)
13608     {
13609         uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13610         if (!success)
13611             return false;
13612 
13613         if (auto_advance_pc && (after_pc_value == orig_pc_value))
13614         {
13615             if (opcode_data->size == eSize32)
13616                 after_pc_value += 4;
13617             else if (opcode_data->size == eSize16)
13618                 after_pc_value += 2;
13619 
13620             EmulateInstruction::Context context;
13621             context.type = eContextAdvancePC;
13622             context.SetNoArgs();
13623             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
13624                 return false;
13625 
13626         }
13627     }
13628     return true;
13629 }
13630 
13631 bool
13632 EmulateInstructionARM::IsInstructionConditional()
13633 {
13634     const uint32_t cond = CurrentCond (m_opcode.GetOpcode32());
13635     return cond != 0xe && cond != 0xf && cond != UINT32_MAX;
13636 }
13637 
13638 bool
13639 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data)
13640 {
13641     if (!test_data)
13642     {
13643         out_stream->Printf ("TestEmulation: Missing test data.\n");
13644         return false;
13645     }
13646 
13647     static ConstString opcode_key ("opcode");
13648     static ConstString before_key ("before_state");
13649     static ConstString after_key ("after_state");
13650 
13651     OptionValueSP value_sp = test_data->GetValueForKey (opcode_key);
13652 
13653     uint32_t test_opcode;
13654     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64))
13655     {
13656         out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n");
13657         return false;
13658     }
13659     test_opcode = value_sp->GetUInt64Value ();
13660 
13661     if (arch.GetTriple().getArch() == llvm::Triple::arm)
13662     {
13663         m_opcode_mode = eModeARM;
13664         m_opcode.SetOpcode32 (test_opcode, GetByteOrder());
13665     }
13666     else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
13667     {
13668         m_opcode_mode = eModeThumb;
13669         if (test_opcode < 0x10000)
13670             m_opcode.SetOpcode16 (test_opcode, GetByteOrder());
13671         else
13672             m_opcode.SetOpcode32 (test_opcode, GetByteOrder());
13673 
13674     }
13675     else
13676     {
13677         out_stream->Printf ("TestEmulation:  Invalid arch.\n");
13678         return false;
13679     }
13680 
13681     EmulationStateARM before_state;
13682     EmulationStateARM after_state;
13683 
13684     value_sp = test_data->GetValueForKey (before_key);
13685     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13686     {
13687         out_stream->Printf ("TestEmulation:  Failed to find 'before' state.\n");
13688         return false;
13689     }
13690 
13691     OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary ();
13692     if (!before_state.LoadStateFromDictionary (state_dictionary))
13693     {
13694         out_stream->Printf ("TestEmulation:  Failed loading 'before' state.\n");
13695         return false;
13696     }
13697 
13698     value_sp = test_data->GetValueForKey (after_key);
13699     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13700     {
13701         out_stream->Printf ("TestEmulation:  Failed to find 'after' state.\n");
13702         return false;
13703     }
13704 
13705     state_dictionary = value_sp->GetAsDictionary ();
13706     if (!after_state.LoadStateFromDictionary (state_dictionary))
13707     {
13708         out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n");
13709         return false;
13710     }
13711 
13712     SetBaton ((void *) &before_state);
13713     SetCallbacks (&EmulationStateARM::ReadPseudoMemory,
13714                   &EmulationStateARM::WritePseudoMemory,
13715                   &EmulationStateARM::ReadPseudoRegister,
13716                   &EmulationStateARM::WritePseudoRegister);
13717 
13718     bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC);
13719     if (!success)
13720     {
13721         out_stream->Printf ("TestEmulation:  EvaluateInstruction() failed.\n");
13722         return false;
13723     }
13724 
13725     success = before_state.CompareState (after_state);
13726     if (!success)
13727         out_stream->Printf ("TestEmulation:  'before' and 'after' states do not match.\n");
13728 
13729     return success;
13730 }
13731 //
13732 //
13733 //const char *
13734 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
13735 //{
13736 //    if (reg_kind == eRegisterKindGeneric)
13737 //    {
13738 //        switch (reg_num)
13739 //        {
13740 //        case LLDB_REGNUM_GENERIC_PC:    return "pc";
13741 //        case LLDB_REGNUM_GENERIC_SP:    return "sp";
13742 //        case LLDB_REGNUM_GENERIC_FP:    return "fp";
13743 //        case LLDB_REGNUM_GENERIC_RA:    return "lr";
13744 //        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
13745 //        default: return NULL;
13746 //        }
13747 //    }
13748 //    else if (reg_kind == eRegisterKindDWARF)
13749 //    {
13750 //        return GetARMDWARFRegisterName (reg_num);
13751 //    }
13752 //    return NULL;
13753 //}
13754 //
13755 bool
13756 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
13757 {
13758     unwind_plan.Clear();
13759     unwind_plan.SetRegisterKind (eRegisterKindDWARF);
13760 
13761     UnwindPlan::RowSP row(new UnwindPlan::Row);
13762 
13763     // Our previous Call Frame Address is the stack pointer
13764     row->GetCFAValue().SetIsRegisterPlusOffset (dwarf_sp, 0);
13765 
13766     unwind_plan.AppendRow (row);
13767     unwind_plan.SetSourceName ("EmulateInstructionARM");
13768     unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
13769     unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
13770     unwind_plan.SetReturnAddressRegister (dwarf_lr);
13771     return true;
13772 }
13773