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().getEnvironment() == llvm::Triple::Android)
294         return LLDB_INVALID_REGNUM; // Don't use frame pointer on android
295 
296     bool is_apple = false;
297     if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
298         is_apple = true;
299     switch (m_arch.GetTriple().getOS())
300     {
301             case llvm::Triple::Darwin:
302             case llvm::Triple::MacOSX:
303             case llvm::Triple::IOS:
304                 is_apple = true;
305                 break;
306             default:
307                 break;
308     }
309 
310     /* On Apple iOS et al, the frame pointer register is always r7.
311      * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
312      */
313 
314     uint32_t fp_regnum = 11;
315 
316     if (is_apple)
317         fp_regnum = 7;
318 
319     if (m_opcode_mode == eModeThumb)
320         fp_regnum = 7;
321 
322     return fp_regnum;
323 }
324 
325 uint32_t
326 EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const
327 {
328     bool is_apple = false;
329     if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
330         is_apple = true;
331     switch (m_arch.GetTriple().getOS())
332     {
333             case llvm::Triple::Darwin:
334             case llvm::Triple::MacOSX:
335             case llvm::Triple::IOS:
336                 is_apple = true;
337                 break;
338             default:
339                 break;
340     }
341 
342     /* On Apple iOS et al, the frame pointer register is always r7.
343      * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
344      */
345 
346     uint32_t fp_regnum = dwarf_r11;
347 
348     if (is_apple)
349         fp_regnum = dwarf_r7;
350 
351     if (m_opcode_mode == eModeThumb)
352         fp_regnum = dwarf_r7;
353 
354     return fp_regnum;
355 }
356 
357 // Push Multiple Registers stores multiple registers to the stack, storing to
358 // consecutive memory locations ending just below the address in SP, and updates
359 // SP to point to the start of the stored data.
360 bool
361 EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding)
362 {
363 #if 0
364     // ARM pseudo code...
365     if (ConditionPassed())
366     {
367         EncodingSpecificOperations();
368         NullCheckIfThumbEE(13);
369         address = SP - 4*BitCount(registers);
370 
371         for (i = 0 to 14)
372         {
373             if (registers<i> == '1')
374             {
375                 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
376                     MemA[address,4] = bits(32) UNKNOWN;
377                 else
378                     MemA[address,4] = R[i];
379                 address = address + 4;
380             }
381         }
382 
383         if (registers<15> == '1') // Only possible for encoding A1 or A2
384             MemA[address,4] = PCStoreValue();
385 
386         SP = SP - 4*BitCount(registers);
387     }
388 #endif
389 
390     bool conditional = false;
391     bool success = false;
392     if (ConditionPassed(opcode, &conditional))
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         if (conditional)
446             context.type = EmulateInstruction::eContextRegisterStore;
447         else
448             context.type = EmulateInstruction::eContextPushRegisterOnStack;
449         RegisterInfo reg_info;
450         RegisterInfo sp_reg;
451         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
452         for (i=0; i<15; ++i)
453         {
454             if (BitIsSet (registers, i))
455             {
456                 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info);
457                 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
458                 uint32_t reg_value = ReadCoreReg(i, &success);
459                 if (!success)
460                     return false;
461                 if (!MemAWrite (context, addr, reg_value, addr_byte_size))
462                     return false;
463                 addr += addr_byte_size;
464             }
465         }
466 
467         if (BitIsSet (registers, 15))
468         {
469             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info);
470             context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
471             const uint32_t pc = ReadCoreReg(PC_REG, &success);
472             if (!success)
473                 return false;
474             if (!MemAWrite (context, addr, pc, addr_byte_size))
475                 return false;
476         }
477 
478         context.type = EmulateInstruction::eContextAdjustStackPointer;
479         context.SetImmediateSigned (-sp_offset);
480 
481         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
482             return false;
483     }
484     return true;
485 }
486 
487 // Pop Multiple Registers loads multiple registers from the stack, loading from
488 // consecutive memory locations staring at the address in SP, and updates
489 // SP to point just above the loaded data.
490 bool
491 EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding)
492 {
493 #if 0
494     // ARM pseudo code...
495     if (ConditionPassed())
496     {
497         EncodingSpecificOperations(); NullCheckIfThumbEE(13);
498         address = SP;
499         for i = 0 to 14
500             if registers<i> == '1' then
501                 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
502         if registers<15> == '1' then
503             if UnalignedAllowed then
504                 LoadWritePC(MemU[address,4]);
505             else
506                 LoadWritePC(MemA[address,4]);
507         if registers<13> == '0' then SP = SP + 4*BitCount(registers);
508         if registers<13> == '1' then SP = bits(32) UNKNOWN;
509     }
510 #endif
511 
512     bool success = false;
513 
514     bool conditional = false;
515     if (ConditionPassed(opcode, &conditional))
516     {
517         const uint32_t addr_byte_size = GetAddressByteSize();
518         const addr_t sp = ReadCoreReg (SP_REG, &success);
519         if (!success)
520             return false;
521         uint32_t registers = 0;
522         uint32_t Rt; // the destination register
523         switch (encoding) {
524         case eEncodingT1:
525             registers = Bits32(opcode, 7, 0);
526             // The P bit represents PC.
527             if (Bit32(opcode, 8))
528                 registers |= (1u << 15);
529             // if BitCount(registers) < 1 then UNPREDICTABLE;
530             if (BitCount(registers) < 1)
531                 return false;
532             break;
533         case eEncodingT2:
534             // Ignore bit 13.
535             registers = Bits32(opcode, 15, 0) & ~0x2000;
536             // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
537             if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
538                 return false;
539             // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
540             if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
541                 return false;
542             break;
543         case eEncodingT3:
544             Rt = Bits32(opcode, 15, 12);
545             // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
546             if (Rt == 13)
547                 return false;
548             if (Rt == 15 && InITBlock() && !LastInITBlock())
549                 return false;
550             registers = (1u << Rt);
551             break;
552         case eEncodingA1:
553             registers = Bits32(opcode, 15, 0);
554             // Instead of return false, let's handle the following case as well,
555             // which amounts to popping one reg from the full descending stacks.
556             // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
557 
558             // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
559             if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
560                 return false;
561             break;
562         case eEncodingA2:
563             Rt = Bits32(opcode, 15, 12);
564             // if t == 13 then UNPREDICTABLE;
565             if (Rt == dwarf_sp)
566                 return false;
567             registers = (1u << Rt);
568             break;
569         default:
570             return false;
571         }
572         addr_t sp_offset = addr_byte_size * BitCount (registers);
573         addr_t addr = sp;
574         uint32_t i, data;
575 
576         EmulateInstruction::Context context;
577         if (conditional)
578             context.type = EmulateInstruction::eContextRegisterLoad;
579         else
580             context.type = EmulateInstruction::eContextPopRegisterOffStack;
581 
582         RegisterInfo sp_reg;
583         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
584 
585         for (i=0; i<15; ++i)
586         {
587             if (BitIsSet (registers, i))
588             {
589                 context.SetRegisterPlusOffset (sp_reg, addr - sp);
590                 data = MemARead(context, addr, 4, 0, &success);
591                 if (!success)
592                     return false;
593                 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data))
594                     return false;
595                 addr += addr_byte_size;
596             }
597         }
598 
599         if (BitIsSet (registers, 15))
600         {
601             context.SetRegisterPlusOffset (sp_reg, addr - sp);
602             data = MemARead(context, addr, 4, 0, &success);
603             if (!success)
604                 return false;
605             // In ARMv5T and above, this is an interworking branch.
606             if (!LoadWritePC(context, data))
607                 return false;
608             //addr += addr_byte_size;
609         }
610 
611         context.type = EmulateInstruction::eContextAdjustStackPointer;
612         context.SetImmediateSigned (sp_offset);
613 
614         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
615             return false;
616     }
617     return true;
618 }
619 
620 // Set r7 or ip to point to saved value residing within the stack.
621 // ADD (SP plus immediate)
622 bool
623 EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding)
624 {
625 #if 0
626     // ARM pseudo code...
627     if (ConditionPassed())
628     {
629         EncodingSpecificOperations();
630         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
631         if d == 15 then
632            ALUWritePC(result); // setflags is always FALSE here
633         else
634             R[d] = result;
635             if setflags then
636                 APSR.N = result<31>;
637                 APSR.Z = IsZeroBit(result);
638                 APSR.C = carry;
639                 APSR.V = overflow;
640     }
641 #endif
642 
643     bool success = false;
644 
645     if (ConditionPassed(opcode))
646     {
647         const addr_t sp = ReadCoreReg (SP_REG, &success);
648         if (!success)
649             return false;
650         uint32_t Rd; // the destination register
651         uint32_t imm32;
652         switch (encoding) {
653         case eEncodingT1:
654             Rd = 7;
655             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
656             break;
657         case eEncodingA1:
658             Rd = Bits32(opcode, 15, 12);
659             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
660             break;
661         default:
662             return false;
663         }
664         addr_t sp_offset = imm32;
665         addr_t addr = sp + sp_offset; // a pointer to the stack area
666 
667         EmulateInstruction::Context context;
668         if (Rd == GetFramePointerRegisterNumber())
669             context.type = eContextSetFramePointer;
670         else
671             context.type = EmulateInstruction::eContextRegisterPlusOffset;
672         RegisterInfo sp_reg;
673         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
674         context.SetRegisterPlusOffset (sp_reg, sp_offset);
675 
676         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
677             return false;
678     }
679     return true;
680 }
681 
682 // Set r7 or ip to the current stack pointer.
683 // MOV (register)
684 bool
685 EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding)
686 {
687 #if 0
688     // ARM pseudo code...
689     if (ConditionPassed())
690     {
691         EncodingSpecificOperations();
692         result = R[m];
693         if d == 15 then
694             ALUWritePC(result); // setflags is always FALSE here
695         else
696             R[d] = result;
697             if setflags then
698                 APSR.N = result<31>;
699                 APSR.Z = IsZeroBit(result);
700                 // APSR.C unchanged
701                 // APSR.V unchanged
702     }
703 #endif
704 
705     bool success = false;
706 
707     if (ConditionPassed(opcode))
708     {
709         const addr_t sp = ReadCoreReg (SP_REG, &success);
710         if (!success)
711             return false;
712         uint32_t Rd; // the destination register
713         switch (encoding) {
714         case eEncodingT1:
715             Rd = 7;
716             break;
717         case eEncodingA1:
718             Rd = 12;
719             break;
720         default:
721             return false;
722         }
723 
724         EmulateInstruction::Context context;
725         if (Rd == GetFramePointerRegisterNumber())
726             context.type = EmulateInstruction::eContextSetFramePointer;
727         else
728             context.type = EmulateInstruction::eContextRegisterPlusOffset;
729         RegisterInfo sp_reg;
730         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
731         context.SetRegisterPlusOffset (sp_reg, 0);
732 
733         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
734             return false;
735     }
736     return true;
737 }
738 
739 // Move from high register (r8-r15) to low register (r0-r7).
740 // MOV (register)
741 bool
742 EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding)
743 {
744     return EmulateMOVRdRm (opcode, encoding);
745 }
746 
747 // Move from register to register.
748 // MOV (register)
749 bool
750 EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding)
751 {
752 #if 0
753     // ARM pseudo code...
754     if (ConditionPassed())
755     {
756         EncodingSpecificOperations();
757         result = R[m];
758         if d == 15 then
759             ALUWritePC(result); // setflags is always FALSE here
760         else
761             R[d] = result;
762             if setflags then
763                 APSR.N = result<31>;
764                 APSR.Z = IsZeroBit(result);
765                 // APSR.C unchanged
766                 // APSR.V unchanged
767     }
768 #endif
769 
770     bool success = false;
771 
772     if (ConditionPassed(opcode))
773     {
774         uint32_t Rm; // the source register
775         uint32_t Rd; // the destination register
776         bool setflags;
777         switch (encoding) {
778         case eEncodingT1:
779             Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
780             Rm = Bits32(opcode, 6, 3);
781             setflags = false;
782             if (Rd == 15 && InITBlock() && !LastInITBlock())
783                 return false;
784             break;
785         case eEncodingT2:
786             Rd = Bits32(opcode, 2, 0);
787             Rm = Bits32(opcode, 5, 3);
788             setflags = true;
789             if (InITBlock())
790                 return false;
791             break;
792         case eEncodingT3:
793             Rd = Bits32(opcode, 11, 8);
794             Rm = Bits32(opcode, 3, 0);
795             setflags = BitIsSet(opcode, 20);
796             // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
797             if (setflags && (BadReg(Rd) || BadReg(Rm)))
798                 return false;
799             // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE;
800             if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
801                 return false;
802             break;
803         case eEncodingA1:
804             Rd = Bits32(opcode, 15, 12);
805             Rm = Bits32(opcode, 3, 0);
806             setflags = BitIsSet(opcode, 20);
807 
808             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
809             if (Rd == 15 && setflags)
810                 return EmulateSUBSPcLrEtc (opcode, encoding);
811             break;
812         default:
813             return false;
814         }
815         uint32_t result = ReadCoreReg(Rm, &success);
816         if (!success)
817             return false;
818 
819         // The context specifies that Rm is to be moved into Rd.
820         EmulateInstruction::Context context;
821         if (Rd == 13)
822             context.type = EmulateInstruction::eContextAdjustStackPointer;
823         else
824             context.type = EmulateInstruction::eContextRegisterPlusOffset;
825         RegisterInfo dwarf_reg;
826         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
827         context.SetRegisterPlusOffset (dwarf_reg, 0);
828 
829         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
830             return false;
831     }
832     return true;
833 }
834 
835 // Move (immediate) writes an immediate value to the destination register.  It
836 // can optionally update the condition flags based on the value.
837 // MOV (immediate)
838 bool
839 EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding)
840 {
841 #if 0
842     // ARM pseudo code...
843     if (ConditionPassed())
844     {
845         EncodingSpecificOperations();
846         result = imm32;
847         if d == 15 then         // Can only occur for ARM encoding
848             ALUWritePC(result); // setflags is always FALSE here
849         else
850             R[d] = result;
851             if setflags then
852                 APSR.N = result<31>;
853                 APSR.Z = IsZeroBit(result);
854                 APSR.C = carry;
855                 // APSR.V unchanged
856     }
857 #endif
858 
859     if (ConditionPassed(opcode))
860     {
861         uint32_t Rd; // the destination register
862         uint32_t imm32; // the immediate value to be written to Rd
863         uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
864                             // for setflags == false, this value is a don't care
865                             // initialized to 0 to silence the static analyzer
866         bool setflags;
867         switch (encoding) {
868             case eEncodingT1:
869                 Rd = Bits32(opcode, 10, 8);
870                 setflags = !InITBlock();
871                 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
872                 carry = APSR_C;
873 
874                 break;
875 
876             case eEncodingT2:
877                 Rd = Bits32(opcode, 11, 8);
878                 setflags = BitIsSet(opcode, 20);
879                 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
880                 if (BadReg(Rd))
881                   return false;
882 
883                 break;
884 
885             case eEncodingT3:
886             {
887                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32);
888                 Rd = Bits32 (opcode, 11, 8);
889                 setflags = false;
890                 uint32_t imm4 = Bits32 (opcode, 19, 16);
891                 uint32_t imm3 = Bits32 (opcode, 14, 12);
892                 uint32_t i = Bit32 (opcode, 26);
893                 uint32_t imm8 = Bits32 (opcode, 7, 0);
894                 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
895 
896                 // if BadReg(d) then UNPREDICTABLE;
897                 if (BadReg (Rd))
898                     return false;
899             }
900                 break;
901 
902             case eEncodingA1:
903                 // d = UInt(Rd); setflags = (S == �1�); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C);
904                 Rd = Bits32 (opcode, 15, 12);
905                 setflags = BitIsSet (opcode, 20);
906                 imm32 = ARMExpandImm_C (opcode, APSR_C, carry);
907 
908                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
909                 if ((Rd == 15) && setflags)
910                     return EmulateSUBSPcLrEtc (opcode, encoding);
911 
912                 break;
913 
914             case eEncodingA2:
915             {
916                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
917                 Rd = Bits32 (opcode, 15, 12);
918                 setflags = false;
919                 uint32_t imm4 = Bits32 (opcode, 19, 16);
920                 uint32_t imm12 = Bits32 (opcode, 11, 0);
921                 imm32 = (imm4 << 12) | imm12;
922 
923                 // if d == 15 then UNPREDICTABLE;
924                 if (Rd == 15)
925                     return false;
926             }
927                 break;
928 
929             default:
930                 return false;
931         }
932         uint32_t result = imm32;
933 
934         // The context specifies that an immediate is to be moved into Rd.
935         EmulateInstruction::Context context;
936         context.type = EmulateInstruction::eContextImmediate;
937         context.SetNoArgs ();
938 
939         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
940             return false;
941     }
942     return true;
943 }
944 
945 // MUL multiplies two register values.  The least significant 32 bits of the result are written to the destination
946 // register.  These 32 bits do not depend on whether the source register values are considered to be signed values or
947 // unsigned values.
948 //
949 // Optionally, it can update the condition flags based on the result.  In the Thumb instruction set, this option is
950 // limited to only a few forms of the instruction.
951 bool
952 EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding)
953 {
954 #if 0
955     if ConditionPassed() then
956         EncodingSpecificOperations();
957         operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
958         operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
959         result = operand1 * operand2;
960         R[d] = result<31:0>;
961         if setflags then
962             APSR.N = result<31>;
963             APSR.Z = IsZeroBit(result);
964             if ArchVersion() == 4 then
965                 APSR.C = bit UNKNOWN;
966             // else APSR.C unchanged
967             // APSR.V always unchanged
968 #endif
969 
970     if (ConditionPassed(opcode))
971     {
972         uint32_t d;
973         uint32_t n;
974         uint32_t m;
975         bool setflags;
976 
977         // EncodingSpecificOperations();
978         switch (encoding)
979         {
980             case eEncodingT1:
981                 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
982                 d = Bits32 (opcode, 2, 0);
983                 n = Bits32 (opcode, 5, 3);
984                 m = Bits32 (opcode, 2, 0);
985                 setflags = !InITBlock();
986 
987                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
988                 if ((ArchVersion() < ARMv6) && (d == n))
989                     return false;
990 
991                 break;
992 
993             case eEncodingT2:
994                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
995                 d = Bits32 (opcode, 11, 8);
996                 n = Bits32 (opcode, 19, 16);
997                 m = Bits32 (opcode, 3, 0);
998                 setflags = false;
999 
1000                 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
1001                 if (BadReg (d) || BadReg (n) || BadReg (m))
1002                     return false;
1003 
1004                 break;
1005 
1006             case eEncodingA1:
1007                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
1008                 d = Bits32 (opcode, 19, 16);
1009                 n = Bits32 (opcode, 3, 0);
1010                 m = Bits32 (opcode, 11, 8);
1011                 setflags = BitIsSet (opcode, 20);
1012 
1013                 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
1014                 if ((d == 15) ||  (n == 15) || (m == 15))
1015                     return false;
1016 
1017                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1018                 if ((ArchVersion() < ARMv6) && (d == n))
1019                     return false;
1020 
1021                 break;
1022 
1023             default:
1024                 return false;
1025         }
1026 
1027         bool success = false;
1028 
1029         // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
1030         uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
1031         if (!success)
1032             return false;
1033 
1034         // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
1035         uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
1036         if (!success)
1037             return false;
1038 
1039         // result = operand1 * operand2;
1040         uint64_t result = operand1 * operand2;
1041 
1042         // R[d] = result<31:0>;
1043         RegisterInfo op1_reg;
1044         RegisterInfo op2_reg;
1045         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
1046         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
1047 
1048         EmulateInstruction::Context context;
1049         context.type = eContextArithmetic;
1050         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
1051 
1052         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result)))
1053             return false;
1054 
1055         // if setflags then
1056         if (setflags)
1057         {
1058             // APSR.N = result<31>;
1059             // APSR.Z = IsZeroBit(result);
1060             m_new_inst_cpsr = m_opcode_cpsr;
1061             SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31));
1062             SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1063             if (m_new_inst_cpsr != m_opcode_cpsr)
1064             {
1065                 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1066                     return false;
1067             }
1068 
1069             // if ArchVersion() == 4 then
1070                 // APSR.C = bit UNKNOWN;
1071         }
1072     }
1073     return true;
1074 }
1075 
1076 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register.
1077 // It can optionally update the condition flags based on the value.
1078 bool
1079 EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding)
1080 {
1081 #if 0
1082     // ARM pseudo code...
1083     if (ConditionPassed())
1084     {
1085         EncodingSpecificOperations();
1086         result = NOT(imm32);
1087         if d == 15 then         // Can only occur for ARM encoding
1088             ALUWritePC(result); // setflags is always FALSE here
1089         else
1090             R[d] = result;
1091             if setflags then
1092                 APSR.N = result<31>;
1093                 APSR.Z = IsZeroBit(result);
1094                 APSR.C = carry;
1095                 // APSR.V unchanged
1096     }
1097 #endif
1098 
1099     if (ConditionPassed(opcode))
1100     {
1101         uint32_t Rd; // the destination register
1102         uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1103         uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1104         bool setflags;
1105         switch (encoding) {
1106         case eEncodingT1:
1107             Rd = Bits32(opcode, 11, 8);
1108             setflags = BitIsSet(opcode, 20);
1109             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1110             break;
1111         case eEncodingA1:
1112             Rd = Bits32(opcode, 15, 12);
1113             setflags = BitIsSet(opcode, 20);
1114             imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1115 
1116             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1117             if (Rd == 15 && setflags)
1118                 return EmulateSUBSPcLrEtc (opcode, encoding);
1119             break;
1120         default:
1121             return false;
1122         }
1123         uint32_t result = ~imm32;
1124 
1125         // The context specifies that an immediate is to be moved into Rd.
1126         EmulateInstruction::Context context;
1127         context.type = EmulateInstruction::eContextImmediate;
1128         context.SetNoArgs ();
1129 
1130         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1131             return false;
1132     }
1133     return true;
1134 }
1135 
1136 // Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register.
1137 // It can optionally update the condition flags based on the result.
1138 bool
1139 EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding)
1140 {
1141 #if 0
1142     // ARM pseudo code...
1143     if (ConditionPassed())
1144     {
1145         EncodingSpecificOperations();
1146         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1147         result = NOT(shifted);
1148         if d == 15 then         // Can only occur for ARM encoding
1149             ALUWritePC(result); // setflags is always FALSE here
1150         else
1151             R[d] = result;
1152             if setflags then
1153                 APSR.N = result<31>;
1154                 APSR.Z = IsZeroBit(result);
1155                 APSR.C = carry;
1156                 // APSR.V unchanged
1157     }
1158 #endif
1159 
1160     if (ConditionPassed(opcode))
1161     {
1162         uint32_t Rm; // the source register
1163         uint32_t Rd; // the destination register
1164         ARM_ShifterType shift_t;
1165         uint32_t shift_n; // the shift applied to the value read from Rm
1166         bool setflags;
1167         uint32_t carry; // the carry bit after the shift operation
1168         switch (encoding) {
1169         case eEncodingT1:
1170             Rd = Bits32(opcode, 2, 0);
1171             Rm = Bits32(opcode, 5, 3);
1172             setflags = !InITBlock();
1173             shift_t = SRType_LSL;
1174             shift_n = 0;
1175             if (InITBlock())
1176                 return false;
1177             break;
1178         case eEncodingT2:
1179             Rd = Bits32(opcode, 11, 8);
1180             Rm = Bits32(opcode, 3, 0);
1181             setflags = BitIsSet(opcode, 20);
1182             shift_n = DecodeImmShiftThumb(opcode, shift_t);
1183             // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1184             if (BadReg(Rd) || BadReg(Rm))
1185                 return false;
1186             break;
1187         case eEncodingA1:
1188             Rd = Bits32(opcode, 15, 12);
1189             Rm = Bits32(opcode, 3, 0);
1190             setflags = BitIsSet(opcode, 20);
1191             shift_n = DecodeImmShiftARM(opcode, shift_t);
1192             break;
1193         default:
1194             return false;
1195         }
1196         bool success = false;
1197         uint32_t value = ReadCoreReg(Rm, &success);
1198         if (!success)
1199             return false;
1200 
1201         uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1202         if (!success)
1203             return false;
1204         uint32_t result = ~shifted;
1205 
1206         // The context specifies that an immediate is to be moved into Rd.
1207         EmulateInstruction::Context context;
1208         context.type = EmulateInstruction::eContextImmediate;
1209         context.SetNoArgs ();
1210 
1211         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1212             return false;
1213     }
1214     return true;
1215 }
1216 
1217 // PC relative immediate load into register, possibly followed by ADD (SP plus register).
1218 // LDR (literal)
1219 bool
1220 EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding)
1221 {
1222 #if 0
1223     // ARM pseudo code...
1224     if (ConditionPassed())
1225     {
1226         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1227         base = Align(PC,4);
1228         address = if add then (base + imm32) else (base - imm32);
1229         data = MemU[address,4];
1230         if t == 15 then
1231             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1232         elsif UnalignedSupport() || address<1:0> = '00' then
1233             R[t] = data;
1234         else // Can only apply before ARMv7
1235             if CurrentInstrSet() == InstrSet_ARM then
1236                 R[t] = ROR(data, 8*UInt(address<1:0>));
1237             else
1238                 R[t] = bits(32) UNKNOWN;
1239     }
1240 #endif
1241 
1242     if (ConditionPassed(opcode))
1243     {
1244         bool success = false;
1245         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1246         if (!success)
1247             return false;
1248 
1249         // PC relative immediate load context
1250         EmulateInstruction::Context context;
1251         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1252         RegisterInfo pc_reg;
1253         GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
1254         context.SetRegisterPlusOffset (pc_reg, 0);
1255 
1256         uint32_t Rt;    // the destination register
1257         uint32_t imm32; // immediate offset from the PC
1258         bool add;       // +imm32 or -imm32?
1259         addr_t base;    // the base address
1260         addr_t address; // the PC relative address
1261         uint32_t data;  // the literal data value from the PC relative load
1262         switch (encoding) {
1263         case eEncodingT1:
1264             Rt = Bits32(opcode, 10, 8);
1265             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1266             add = true;
1267             break;
1268         case eEncodingT2:
1269             Rt = Bits32(opcode, 15, 12);
1270             imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1271             add = BitIsSet(opcode, 23);
1272             if (Rt == 15 && InITBlock() && !LastInITBlock())
1273                 return false;
1274             break;
1275         default:
1276             return false;
1277         }
1278 
1279         base = Align(pc, 4);
1280         if (add)
1281             address = base + imm32;
1282         else
1283             address = base - imm32;
1284 
1285         context.SetRegisterPlusOffset(pc_reg, address - base);
1286         data = MemURead(context, address, 4, 0, &success);
1287         if (!success)
1288             return false;
1289 
1290         if (Rt == 15)
1291         {
1292             if (Bits32(address, 1, 0) == 0)
1293             {
1294                 // In ARMv5T and above, this is an interworking branch.
1295                 if (!LoadWritePC(context, data))
1296                     return false;
1297             }
1298             else
1299                 return false;
1300         }
1301         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
1302         {
1303             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
1304                 return false;
1305         }
1306         else // We don't handle ARM for now.
1307             return false;
1308 
1309     }
1310     return true;
1311 }
1312 
1313 // An add operation to adjust the SP.
1314 // ADD (SP plus immediate)
1315 bool
1316 EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding)
1317 {
1318 #if 0
1319     // ARM pseudo code...
1320     if (ConditionPassed())
1321     {
1322         EncodingSpecificOperations();
1323         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1324         if d == 15 then // Can only occur for ARM encoding
1325             ALUWritePC(result); // setflags is always FALSE here
1326         else
1327             R[d] = result;
1328             if setflags then
1329                 APSR.N = result<31>;
1330                 APSR.Z = IsZeroBit(result);
1331                 APSR.C = carry;
1332                 APSR.V = overflow;
1333     }
1334 #endif
1335 
1336     bool success = false;
1337 
1338     if (ConditionPassed(opcode))
1339     {
1340         const addr_t sp = ReadCoreReg (SP_REG, &success);
1341         if (!success)
1342             return false;
1343         uint32_t imm32; // the immediate operand
1344         uint32_t d;
1345         bool setflags;
1346         switch (encoding)
1347         {
1348             case eEncodingT1:
1349                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1350                 d = Bits32 (opcode, 10, 8);
1351                 imm32 = (Bits32 (opcode, 7, 0) << 2);
1352                 setflags = false;
1353                 break;
1354 
1355             case eEncodingT2:
1356                 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1357                 d = 13;
1358                 imm32 = ThumbImm7Scaled (opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1359                 setflags = false;
1360                 break;
1361 
1362             case eEncodingT3:
1363                 // d = UInt(Rd); setflags = (S == "1"); imm32 = ThumbExpandImm(i:imm3:imm8);
1364                 d = Bits32 (opcode, 11, 8);
1365                 imm32 = ThumbExpandImm (opcode);
1366                 setflags = Bit32 (opcode, 20);
1367 
1368                 // if Rd == "1111" && S == "1" then SEE CMN (immediate);
1369                 if (d == 15 && setflags == 1)
1370                     return false; // CMN (immediate) not yet supported
1371 
1372                 // if d == 15 && S == "0" then UNPREDICTABLE;
1373                 if (d == 15 && setflags == 0)
1374                     return false;
1375                 break;
1376 
1377             case eEncodingT4:
1378                 {
1379                     // if Rn == '1111' then SEE ADR;
1380                     // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
1381                     d = Bits32 (opcode, 11, 8);
1382                     setflags = false;
1383                     uint32_t i = Bit32 (opcode, 26);
1384                     uint32_t imm3 = Bits32 (opcode, 14, 12);
1385                     uint32_t imm8 = Bits32 (opcode, 7, 0);
1386                     imm32 = (i << 11) | (imm3 << 8) | imm8;
1387 
1388                     // if d == 15 then UNPREDICTABLE;
1389                     if (d == 15)
1390                         return false;
1391                 }
1392                 break;
1393 
1394             default:
1395                 return false;
1396         }
1397         // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
1398         AddWithCarryResult res = AddWithCarry (sp, imm32, 0);
1399 
1400         EmulateInstruction::Context context;
1401         if (d == 13)
1402             context.type = EmulateInstruction::eContextAdjustStackPointer;
1403         else
1404             context.type = EmulateInstruction::eContextRegisterPlusOffset;
1405 
1406         RegisterInfo sp_reg;
1407         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1408         context.SetRegisterPlusOffset (sp_reg, res.result - sp);
1409 
1410         if (d == 15)
1411         {
1412             if (!ALUWritePC (context, res.result))
1413                 return false;
1414         }
1415         else
1416         {
1417             // R[d] = result;
1418             // if setflags then
1419             //     APSR.N = result<31>;
1420             //     APSR.Z = IsZeroBit(result);
1421             //     APSR.C = carry;
1422             //     APSR.V = overflow;
1423             if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
1424                 return false;
1425         }
1426     }
1427     return true;
1428 }
1429 
1430 // An add operation to adjust the SP.
1431 // ADD (SP plus register)
1432 bool
1433 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding)
1434 {
1435 #if 0
1436     // ARM pseudo code...
1437     if (ConditionPassed())
1438     {
1439         EncodingSpecificOperations();
1440         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1441         (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1442         if d == 15 then
1443             ALUWritePC(result); // setflags is always FALSE here
1444         else
1445             R[d] = result;
1446             if setflags then
1447                 APSR.N = result<31>;
1448                 APSR.Z = IsZeroBit(result);
1449                 APSR.C = carry;
1450                 APSR.V = overflow;
1451     }
1452 #endif
1453 
1454     bool success = false;
1455 
1456     if (ConditionPassed(opcode))
1457     {
1458         const addr_t sp = ReadCoreReg (SP_REG, &success);
1459         if (!success)
1460             return false;
1461         uint32_t Rm; // the second operand
1462         switch (encoding) {
1463         case eEncodingT2:
1464             Rm = Bits32(opcode, 6, 3);
1465             break;
1466         default:
1467             return false;
1468         }
1469         int32_t reg_value = ReadCoreReg(Rm, &success);
1470         if (!success)
1471             return false;
1472 
1473         addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1474 
1475         EmulateInstruction::Context context;
1476         context.type = eContextArithmetic;
1477         RegisterInfo sp_reg;
1478         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1479 
1480         RegisterInfo other_reg;
1481         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1482         context.SetRegisterRegisterOperands (sp_reg, other_reg);
1483 
1484         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
1485             return false;
1486     }
1487     return true;
1488 }
1489 
1490 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
1491 // at a PC-relative address, and changes instruction set from ARM to Thumb, or
1492 // from Thumb to ARM.
1493 // BLX (immediate)
1494 bool
1495 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding)
1496 {
1497 #if 0
1498     // ARM pseudo code...
1499     if (ConditionPassed())
1500     {
1501         EncodingSpecificOperations();
1502         if CurrentInstrSet() == InstrSet_ARM then
1503             LR = PC - 4;
1504         else
1505             LR = PC<31:1> : '1';
1506         if targetInstrSet == InstrSet_ARM then
1507             targetAddress = Align(PC,4) + imm32;
1508         else
1509             targetAddress = PC + imm32;
1510         SelectInstrSet(targetInstrSet);
1511         BranchWritePC(targetAddress);
1512     }
1513 #endif
1514 
1515     bool success = true;
1516 
1517     if (ConditionPassed(opcode))
1518     {
1519         EmulateInstruction::Context context;
1520         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1521         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1522         if (!success)
1523             return false;
1524         addr_t lr; // next instruction address
1525         addr_t target; // target address
1526         int32_t imm32; // PC-relative offset
1527         switch (encoding) {
1528         case eEncodingT1:
1529             {
1530             lr = pc | 1u; // return address
1531             uint32_t S = Bit32(opcode, 26);
1532             uint32_t imm10 = Bits32(opcode, 25, 16);
1533             uint32_t J1 = Bit32(opcode, 13);
1534             uint32_t J2 = Bit32(opcode, 11);
1535             uint32_t imm11 = Bits32(opcode, 10, 0);
1536             uint32_t I1 = !(J1 ^ S);
1537             uint32_t I2 = !(J2 ^ S);
1538             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1539             imm32 = llvm::SignExtend32<25>(imm25);
1540             target = pc + imm32;
1541             SelectInstrSet (eModeThumb);
1542             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
1543             if (InITBlock() && !LastInITBlock())
1544                 return false;
1545             break;
1546             }
1547         case eEncodingT2:
1548             {
1549             lr = pc | 1u; // return address
1550             uint32_t S = Bit32(opcode, 26);
1551             uint32_t imm10H = Bits32(opcode, 25, 16);
1552             uint32_t J1 = Bit32(opcode, 13);
1553             uint32_t J2 = Bit32(opcode, 11);
1554             uint32_t imm10L = Bits32(opcode, 10, 1);
1555             uint32_t I1 = !(J1 ^ S);
1556             uint32_t I2 = !(J2 ^ S);
1557             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
1558             imm32 = llvm::SignExtend32<25>(imm25);
1559             target = Align(pc, 4) + imm32;
1560             SelectInstrSet (eModeARM);
1561             context.SetISAAndImmediateSigned (eModeARM, 4 + imm32);
1562             if (InITBlock() && !LastInITBlock())
1563                 return false;
1564             break;
1565             }
1566         case eEncodingA1:
1567             lr = pc - 4; // return address
1568             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1569             target = Align(pc, 4) + imm32;
1570             SelectInstrSet (eModeARM);
1571             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
1572             break;
1573         case eEncodingA2:
1574             lr = pc - 4; // return address
1575             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
1576             target = pc + imm32;
1577             SelectInstrSet (eModeThumb);
1578             context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32);
1579             break;
1580         default:
1581             return false;
1582         }
1583         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1584             return false;
1585         if (!BranchWritePC(context, target))
1586             return false;
1587         if (m_opcode_cpsr != m_new_inst_cpsr)
1588             if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1589                 return false;
1590     }
1591     return true;
1592 }
1593 
1594 // Branch with Link and Exchange (register) calls a subroutine at an address and
1595 // instruction set specified by a register.
1596 // BLX (register)
1597 bool
1598 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding)
1599 {
1600 #if 0
1601     // ARM pseudo code...
1602     if (ConditionPassed())
1603     {
1604         EncodingSpecificOperations();
1605         target = R[m];
1606         if CurrentInstrSet() == InstrSet_ARM then
1607             next_instr_addr = PC - 4;
1608             LR = next_instr_addr;
1609         else
1610             next_instr_addr = PC - 2;
1611             LR = next_instr_addr<31:1> : '1';
1612         BXWritePC(target);
1613     }
1614 #endif
1615 
1616     bool success = false;
1617 
1618     if (ConditionPassed(opcode))
1619     {
1620         EmulateInstruction::Context context;
1621         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1622         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1623         addr_t lr; // next instruction address
1624         if (!success)
1625             return false;
1626         uint32_t Rm; // the register with the target address
1627         switch (encoding) {
1628         case eEncodingT1:
1629             lr = (pc - 2) | 1u; // return address
1630             Rm = Bits32(opcode, 6, 3);
1631             // if m == 15 then UNPREDICTABLE;
1632             if (Rm == 15)
1633                 return false;
1634             if (InITBlock() && !LastInITBlock())
1635                 return false;
1636             break;
1637         case eEncodingA1:
1638             lr = pc - 4; // return address
1639             Rm = Bits32(opcode, 3, 0);
1640             // if m == 15 then UNPREDICTABLE;
1641             if (Rm == 15)
1642                 return false;
1643             break;
1644         default:
1645             return false;
1646         }
1647         addr_t target = ReadCoreReg (Rm, &success);
1648         if (!success)
1649             return false;
1650         RegisterInfo dwarf_reg;
1651         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1652         context.SetRegister (dwarf_reg);
1653         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1654             return false;
1655         if (!BXWritePC(context, target))
1656             return false;
1657     }
1658     return true;
1659 }
1660 
1661 // Branch and Exchange causes a branch to an address and instruction set specified by a register.
1662 bool
1663 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding)
1664 {
1665 #if 0
1666     // ARM pseudo code...
1667     if (ConditionPassed())
1668     {
1669         EncodingSpecificOperations();
1670         BXWritePC(R[m]);
1671     }
1672 #endif
1673 
1674     if (ConditionPassed(opcode))
1675     {
1676         EmulateInstruction::Context context;
1677         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1678         uint32_t Rm; // the register with the target address
1679         switch (encoding) {
1680         case eEncodingT1:
1681             Rm = Bits32(opcode, 6, 3);
1682             if (InITBlock() && !LastInITBlock())
1683                 return false;
1684             break;
1685         case eEncodingA1:
1686             Rm = Bits32(opcode, 3, 0);
1687             break;
1688         default:
1689             return false;
1690         }
1691         bool success = false;
1692         addr_t target = ReadCoreReg (Rm, &success);
1693         if (!success)
1694             return false;
1695 
1696         RegisterInfo dwarf_reg;
1697         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1698         context.SetRegister (dwarf_reg);
1699         if (!BXWritePC(context, target))
1700             return false;
1701     }
1702     return true;
1703 }
1704 
1705 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an
1706 // address and instruction set specified by a register as though it were a BX instruction.
1707 //
1708 // TODO: Emulate Jazelle architecture?
1709 //       We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation.
1710 bool
1711 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding)
1712 {
1713 #if 0
1714     // ARM pseudo code...
1715     if (ConditionPassed())
1716     {
1717         EncodingSpecificOperations();
1718         if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
1719             BXWritePC(R[m]);
1720         else
1721             if JazelleAcceptsExecution() then
1722                 SwitchToJazelleExecution();
1723             else
1724                 SUBARCHITECTURE_DEFINED handler call;
1725     }
1726 #endif
1727 
1728     if (ConditionPassed(opcode))
1729     {
1730         EmulateInstruction::Context context;
1731         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1732         uint32_t Rm; // the register with the target address
1733         switch (encoding) {
1734         case eEncodingT1:
1735             Rm = Bits32(opcode, 19, 16);
1736             if (BadReg(Rm))
1737                 return false;
1738             if (InITBlock() && !LastInITBlock())
1739                 return false;
1740             break;
1741         case eEncodingA1:
1742             Rm = Bits32(opcode, 3, 0);
1743             if (Rm == 15)
1744                 return false;
1745             break;
1746         default:
1747             return false;
1748         }
1749         bool success = false;
1750         addr_t target = ReadCoreReg (Rm, &success);
1751         if (!success)
1752             return false;
1753 
1754         RegisterInfo dwarf_reg;
1755         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1756         context.SetRegister (dwarf_reg);
1757         if (!BXWritePC(context, target))
1758             return false;
1759     }
1760     return true;
1761 }
1762 
1763 // Set r7 to point to some ip offset.
1764 // SUB (immediate)
1765 bool
1766 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding)
1767 {
1768 #if 0
1769     // ARM pseudo code...
1770     if (ConditionPassed())
1771     {
1772         EncodingSpecificOperations();
1773         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1774         if d == 15 then // Can only occur for ARM encoding
1775            ALUWritePC(result); // setflags is always FALSE here
1776         else
1777             R[d] = result;
1778             if setflags then
1779                 APSR.N = result<31>;
1780                 APSR.Z = IsZeroBit(result);
1781                 APSR.C = carry;
1782                 APSR.V = overflow;
1783     }
1784 #endif
1785 
1786     if (ConditionPassed(opcode))
1787     {
1788         bool success = false;
1789         const addr_t ip = ReadCoreReg (12, &success);
1790         if (!success)
1791             return false;
1792         uint32_t imm32;
1793         switch (encoding) {
1794         case eEncodingA1:
1795             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1796             break;
1797         default:
1798             return false;
1799         }
1800         addr_t ip_offset = imm32;
1801         addr_t addr = ip - ip_offset; // the adjusted ip value
1802 
1803         EmulateInstruction::Context context;
1804         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1805         RegisterInfo dwarf_reg;
1806         GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg);
1807         context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
1808 
1809         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
1810             return false;
1811     }
1812     return true;
1813 }
1814 
1815 // Set ip to point to some stack offset.
1816 // SUB (SP minus immediate)
1817 bool
1818 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding)
1819 {
1820 #if 0
1821     // ARM pseudo code...
1822     if (ConditionPassed())
1823     {
1824         EncodingSpecificOperations();
1825         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1826         if d == 15 then // Can only occur for ARM encoding
1827            ALUWritePC(result); // setflags is always FALSE here
1828         else
1829             R[d] = result;
1830             if setflags then
1831                 APSR.N = result<31>;
1832                 APSR.Z = IsZeroBit(result);
1833                 APSR.C = carry;
1834                 APSR.V = overflow;
1835     }
1836 #endif
1837 
1838     if (ConditionPassed(opcode))
1839     {
1840         bool success = false;
1841         const addr_t sp = ReadCoreReg (SP_REG, &success);
1842         if (!success)
1843             return false;
1844         uint32_t imm32;
1845         switch (encoding) {
1846         case eEncodingA1:
1847             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1848             break;
1849         default:
1850             return false;
1851         }
1852         addr_t sp_offset = imm32;
1853         addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1854 
1855         EmulateInstruction::Context context;
1856         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1857         RegisterInfo dwarf_reg;
1858         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
1859         context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
1860 
1861         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
1862             return false;
1863     }
1864     return true;
1865 }
1866 
1867 // This instruction subtracts an immediate value from the SP value, and writes
1868 // the result to the destination register.
1869 //
1870 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage.
1871 bool
1872 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding)
1873 {
1874 #if 0
1875     // ARM pseudo code...
1876     if (ConditionPassed())
1877     {
1878         EncodingSpecificOperations();
1879         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1880         if d == 15 then        // Can only occur for ARM encoding
1881            ALUWritePC(result); // setflags is always FALSE here
1882         else
1883             R[d] = result;
1884             if setflags then
1885                 APSR.N = result<31>;
1886                 APSR.Z = IsZeroBit(result);
1887                 APSR.C = carry;
1888                 APSR.V = overflow;
1889     }
1890 #endif
1891 
1892     bool success = false;
1893     if (ConditionPassed(opcode))
1894     {
1895         const addr_t sp = ReadCoreReg (SP_REG, &success);
1896         if (!success)
1897             return false;
1898 
1899         uint32_t Rd;
1900         bool setflags;
1901         uint32_t imm32;
1902         switch (encoding) {
1903         case eEncodingT1:
1904             Rd = 13;
1905             setflags = false;
1906             imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1907             break;
1908         case eEncodingT2:
1909             Rd = Bits32(opcode, 11, 8);
1910             setflags = BitIsSet(opcode, 20);
1911             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1912             if (Rd == 15 && setflags)
1913                 return EmulateCMPImm(opcode, eEncodingT2);
1914             if (Rd == 15 && !setflags)
1915                 return false;
1916             break;
1917         case eEncodingT3:
1918             Rd = Bits32(opcode, 11, 8);
1919             setflags = false;
1920             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
1921             if (Rd == 15)
1922                 return false;
1923             break;
1924         case eEncodingA1:
1925             Rd = Bits32(opcode, 15, 12);
1926             setflags = BitIsSet(opcode, 20);
1927             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1928 
1929             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1930             if (Rd == 15 && setflags)
1931                 return EmulateSUBSPcLrEtc (opcode, encoding);
1932             break;
1933         default:
1934             return false;
1935         }
1936         AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
1937 
1938         EmulateInstruction::Context context;
1939         if (Rd == 13)
1940         {
1941             uint64_t imm64 = imm32;  // Need to expand it to 64 bits before attempting to negate it, or the wrong
1942                                      // value gets passed down to context.SetImmediateSigned.
1943             context.type = EmulateInstruction::eContextAdjustStackPointer;
1944             context.SetImmediateSigned (-imm64); // the stack pointer offset
1945         }
1946         else
1947         {
1948             context.type = EmulateInstruction::eContextImmediate;
1949             context.SetNoArgs ();
1950         }
1951 
1952         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
1953             return false;
1954     }
1955     return true;
1956 }
1957 
1958 // A store operation to the stack that also updates the SP.
1959 bool
1960 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding)
1961 {
1962 #if 0
1963     // ARM pseudo code...
1964     if (ConditionPassed())
1965     {
1966         EncodingSpecificOperations();
1967         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1968         address = if index then offset_addr else R[n];
1969         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1970         if wback then R[n] = offset_addr;
1971     }
1972 #endif
1973 
1974     bool conditional = false;
1975     bool success = false;
1976     if (ConditionPassed(opcode, &conditional))
1977     {
1978         const uint32_t addr_byte_size = GetAddressByteSize();
1979         const addr_t sp = ReadCoreReg (SP_REG, &success);
1980         if (!success)
1981             return false;
1982         uint32_t Rt; // the source register
1983         uint32_t imm12;
1984         uint32_t Rn;  // This function assumes Rn is the SP, but we should verify that.
1985 
1986         bool index;
1987         bool add;
1988         bool wback;
1989         switch (encoding) {
1990         case eEncodingA1:
1991             Rt = Bits32(opcode, 15, 12);
1992             imm12 = Bits32(opcode, 11, 0);
1993             Rn = Bits32 (opcode, 19, 16);
1994 
1995             if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
1996                 return false;
1997 
1998             index = BitIsSet (opcode, 24);
1999             add = BitIsSet (opcode, 23);
2000             wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
2001 
2002             if (wback && ((Rn == 15) || (Rn == Rt)))
2003                 return false;
2004             break;
2005         default:
2006             return false;
2007         }
2008         addr_t offset_addr;
2009         if (add)
2010             offset_addr = sp + imm12;
2011         else
2012             offset_addr = sp - imm12;
2013 
2014         addr_t addr;
2015         if (index)
2016             addr = offset_addr;
2017         else
2018             addr = sp;
2019 
2020         EmulateInstruction::Context context;
2021         if (conditional)
2022             context.type = EmulateInstruction::eContextRegisterStore;
2023         else
2024             context.type = EmulateInstruction::eContextPushRegisterOnStack;
2025         RegisterInfo sp_reg;
2026         RegisterInfo dwarf_reg;
2027 
2028         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2029         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
2030         context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
2031         if (Rt != 15)
2032         {
2033             uint32_t reg_value = ReadCoreReg(Rt, &success);
2034             if (!success)
2035                 return false;
2036             if (!MemUWrite (context, addr, reg_value, addr_byte_size))
2037                 return false;
2038         }
2039         else
2040         {
2041             const uint32_t pc = ReadCoreReg(PC_REG, &success);
2042             if (!success)
2043                 return false;
2044             if (!MemUWrite (context, addr, pc, addr_byte_size))
2045                 return false;
2046         }
2047 
2048 
2049         if (wback)
2050         {
2051             context.type = EmulateInstruction::eContextAdjustStackPointer;
2052             context.SetImmediateSigned (addr - sp);
2053             if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr))
2054                 return false;
2055         }
2056     }
2057     return true;
2058 }
2059 
2060 // Vector Push stores multiple extension registers to the stack.
2061 // It also updates SP to point to the start of the stored data.
2062 bool
2063 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding)
2064 {
2065 #if 0
2066     // ARM pseudo code...
2067     if (ConditionPassed())
2068     {
2069         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2070         address = SP - imm32;
2071         SP = SP - imm32;
2072         if single_regs then
2073             for r = 0 to regs-1
2074                 MemA[address,4] = S[d+r]; address = address+4;
2075         else
2076             for r = 0 to regs-1
2077                 // Store as two word-aligned words in the correct order for current endianness.
2078                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
2079                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
2080                 address = address+8;
2081     }
2082 #endif
2083 
2084     bool success = false;
2085     bool conditional = false;
2086     if (ConditionPassed(opcode, &conditional))
2087     {
2088         const uint32_t addr_byte_size = GetAddressByteSize();
2089         const addr_t sp = ReadCoreReg (SP_REG, &success);
2090         if (!success)
2091             return false;
2092         bool single_regs;
2093         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2094         uint32_t imm32; // stack offset
2095         uint32_t regs;  // number of registers
2096         switch (encoding) {
2097         case eEncodingT1:
2098         case eEncodingA1:
2099             single_regs = false;
2100             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2101             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2102             // If UInt(imm8) is odd, see "FSTMX".
2103             regs = Bits32(opcode, 7, 0) / 2;
2104             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2105             if (regs == 0 || regs > 16 || (d + regs) > 32)
2106                 return false;
2107             break;
2108         case eEncodingT2:
2109         case eEncodingA2:
2110             single_regs = true;
2111             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2112             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2113             regs = Bits32(opcode, 7, 0);
2114             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2115             if (regs == 0 || regs > 16 || (d + regs) > 32)
2116                 return false;
2117             break;
2118         default:
2119             return false;
2120         }
2121         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2122         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2123         addr_t sp_offset = imm32;
2124         addr_t addr = sp - sp_offset;
2125         uint32_t i;
2126 
2127         EmulateInstruction::Context context;
2128         if (conditional)
2129             context.type = EmulateInstruction::eContextRegisterStore;
2130         else
2131             context.type = EmulateInstruction::eContextPushRegisterOnStack;
2132         RegisterInfo dwarf_reg;
2133         RegisterInfo sp_reg;
2134         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2135         for (i=0; i<regs; ++i)
2136         {
2137             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2138             context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
2139             // uint64_t to accommodate 64-bit registers.
2140             uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success);
2141             if (!success)
2142                 return false;
2143             if (!MemAWrite (context, addr, reg_value, reg_byte_size))
2144                 return false;
2145             addr += reg_byte_size;
2146         }
2147 
2148         context.type = EmulateInstruction::eContextAdjustStackPointer;
2149         context.SetImmediateSigned (-sp_offset);
2150 
2151         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2152             return false;
2153     }
2154     return true;
2155 }
2156 
2157 // Vector Pop loads multiple extension registers from the stack.
2158 // It also updates SP to point just above the loaded data.
2159 bool
2160 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding)
2161 {
2162 #if 0
2163     // ARM pseudo code...
2164     if (ConditionPassed())
2165     {
2166         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2167         address = SP;
2168         SP = SP + imm32;
2169         if single_regs then
2170             for r = 0 to regs-1
2171                 S[d+r] = MemA[address,4]; address = address+4;
2172         else
2173             for r = 0 to regs-1
2174                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2175                 // Combine the word-aligned words in the correct order for current endianness.
2176                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2177     }
2178 #endif
2179 
2180     bool success = false;
2181     bool conditional = false;
2182     if (ConditionPassed(opcode, &conditional))
2183     {
2184         const uint32_t addr_byte_size = GetAddressByteSize();
2185         const addr_t sp = ReadCoreReg (SP_REG, &success);
2186         if (!success)
2187             return false;
2188         bool single_regs;
2189         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2190         uint32_t imm32; // stack offset
2191         uint32_t regs;  // number of registers
2192         switch (encoding) {
2193         case eEncodingT1:
2194         case eEncodingA1:
2195             single_regs = false;
2196             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2197             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2198             // If UInt(imm8) is odd, see "FLDMX".
2199             regs = Bits32(opcode, 7, 0) / 2;
2200             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2201             if (regs == 0 || regs > 16 || (d + regs) > 32)
2202                 return false;
2203             break;
2204         case eEncodingT2:
2205         case eEncodingA2:
2206             single_regs = true;
2207             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2208             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2209             regs = Bits32(opcode, 7, 0);
2210             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2211             if (regs == 0 || regs > 16 || (d + regs) > 32)
2212                 return false;
2213             break;
2214         default:
2215             return false;
2216         }
2217         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2218         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2219         addr_t sp_offset = imm32;
2220         addr_t addr = sp;
2221         uint32_t i;
2222         uint64_t data; // uint64_t to accommodate 64-bit registers.
2223 
2224         EmulateInstruction::Context context;
2225         if (conditional)
2226             context.type = EmulateInstruction::eContextRegisterLoad;
2227         else
2228             context.type = EmulateInstruction::eContextPopRegisterOffStack;
2229         RegisterInfo dwarf_reg;
2230         RegisterInfo sp_reg;
2231         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2232         for (i=0; i<regs; ++i)
2233         {
2234             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2235             context.SetRegisterPlusOffset (sp_reg, addr - sp);
2236             data = MemARead(context, addr, reg_byte_size, 0, &success);
2237             if (!success)
2238                 return false;
2239             if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2240                 return false;
2241             addr += reg_byte_size;
2242         }
2243 
2244         context.type = EmulateInstruction::eContextAdjustStackPointer;
2245         context.SetImmediateSigned (sp_offset);
2246 
2247         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2248             return false;
2249     }
2250     return true;
2251 }
2252 
2253 // SVC (previously SWI)
2254 bool
2255 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding)
2256 {
2257 #if 0
2258     // ARM pseudo code...
2259     if (ConditionPassed())
2260     {
2261         EncodingSpecificOperations();
2262         CallSupervisor();
2263     }
2264 #endif
2265 
2266     bool success = false;
2267 
2268     if (ConditionPassed(opcode))
2269     {
2270         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2271         addr_t lr; // next instruction address
2272         if (!success)
2273             return false;
2274         uint32_t imm32; // the immediate constant
2275         uint32_t mode;  // ARM or Thumb mode
2276         switch (encoding) {
2277         case eEncodingT1:
2278             lr = (pc + 2) | 1u; // return address
2279             imm32 = Bits32(opcode, 7, 0);
2280             mode = eModeThumb;
2281             break;
2282         case eEncodingA1:
2283             lr = pc + 4; // return address
2284             imm32 = Bits32(opcode, 23, 0);
2285             mode = eModeARM;
2286             break;
2287         default:
2288             return false;
2289         }
2290 
2291         EmulateInstruction::Context context;
2292         context.type = EmulateInstruction::eContextSupervisorCall;
2293         context.SetISAAndImmediate (mode, imm32);
2294         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
2295             return false;
2296     }
2297     return true;
2298 }
2299 
2300 // If Then makes up to four following instructions (the IT block) conditional.
2301 bool
2302 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding)
2303 {
2304 #if 0
2305     // ARM pseudo code...
2306     EncodingSpecificOperations();
2307     ITSTATE.IT<7:0> = firstcond:mask;
2308 #endif
2309 
2310     m_it_session.InitIT(Bits32(opcode, 7, 0));
2311     return true;
2312 }
2313 
2314 bool
2315 EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding)
2316 {
2317     // NOP, nothing to do...
2318     return true;
2319 }
2320 
2321 // Branch causes a branch to a target address.
2322 bool
2323 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding)
2324 {
2325 #if 0
2326     // ARM pseudo code...
2327     if (ConditionPassed())
2328     {
2329         EncodingSpecificOperations();
2330         BranchWritePC(PC + imm32);
2331     }
2332 #endif
2333 
2334     bool success = false;
2335 
2336     if (ConditionPassed(opcode))
2337     {
2338         EmulateInstruction::Context context;
2339         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2340         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2341         if (!success)
2342             return false;
2343         addr_t target; // target address
2344         int32_t imm32; // PC-relative offset
2345         switch (encoding) {
2346         case eEncodingT1:
2347             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2348             imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2349             target = pc + imm32;
2350             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2351             break;
2352         case eEncodingT2:
2353             imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1);
2354             target = pc + imm32;
2355             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2356             break;
2357         case eEncodingT3:
2358             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2359             {
2360             if (Bits32(opcode, 25, 23) == 7)
2361                 return false; // See Branches and miscellaneous control on page A6-235.
2362 
2363             uint32_t S = Bit32(opcode, 26);
2364             uint32_t imm6 = Bits32(opcode, 21, 16);
2365             uint32_t J1 = Bit32(opcode, 13);
2366             uint32_t J2 = Bit32(opcode, 11);
2367             uint32_t imm11 = Bits32(opcode, 10, 0);
2368             uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2369             imm32 = llvm::SignExtend32<21>(imm21);
2370             target = pc + imm32;
2371             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2372             break;
2373             }
2374         case eEncodingT4:
2375             {
2376             uint32_t S = Bit32(opcode, 26);
2377             uint32_t imm10 = Bits32(opcode, 25, 16);
2378             uint32_t J1 = Bit32(opcode, 13);
2379             uint32_t J2 = Bit32(opcode, 11);
2380             uint32_t imm11 = Bits32(opcode, 10, 0);
2381             uint32_t I1 = !(J1 ^ S);
2382             uint32_t I2 = !(J2 ^ S);
2383             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2384             imm32 = llvm::SignExtend32<25>(imm25);
2385             target = pc + imm32;
2386             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2387             break;
2388             }
2389         case eEncodingA1:
2390             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2391             target = pc + imm32;
2392             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
2393             break;
2394         default:
2395             return false;
2396         }
2397         if (!BranchWritePC(context, target))
2398             return false;
2399     }
2400     return true;
2401 }
2402 
2403 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
2404 // zero and conditionally branch forward a constant value.  They do not affect the condition flags.
2405 // CBNZ, CBZ
2406 bool
2407 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding)
2408 {
2409 #if 0
2410     // ARM pseudo code...
2411     EncodingSpecificOperations();
2412     if nonzero ^ IsZero(R[n]) then
2413         BranchWritePC(PC + imm32);
2414 #endif
2415 
2416     bool success = false;
2417 
2418     // Read the register value from the operand register Rn.
2419     uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2420     if (!success)
2421         return false;
2422 
2423     EmulateInstruction::Context context;
2424     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2425     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2426     if (!success)
2427         return false;
2428 
2429     addr_t target;  // target address
2430     uint32_t imm32; // PC-relative offset to branch forward
2431     bool nonzero;
2432     switch (encoding) {
2433     case eEncodingT1:
2434         imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2435         nonzero = BitIsSet(opcode, 11);
2436         target = pc + imm32;
2437         context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2438         break;
2439     default:
2440         return false;
2441     }
2442     if (m_ignore_conditions || (nonzero ^ (reg_val == 0)))
2443         if (!BranchWritePC(context, target))
2444             return false;
2445 
2446     return true;
2447 }
2448 
2449 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
2450 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2451 // The branch length is twice the value of the byte returned from the table.
2452 //
2453 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
2454 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2455 // The branch length is twice the value of the halfword returned from the table.
2456 // TBB, TBH
2457 bool
2458 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding)
2459 {
2460 #if 0
2461     // ARM pseudo code...
2462     EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2463     if is_tbh then
2464         halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2465     else
2466         halfwords = UInt(MemU[R[n]+R[m], 1]);
2467     BranchWritePC(PC + 2*halfwords);
2468 #endif
2469 
2470     bool success = false;
2471 
2472     if (ConditionPassed(opcode))
2473     {
2474         uint32_t Rn;     // the base register which contains the address of the table of branch lengths
2475         uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
2476         bool is_tbh;     // true if table branch halfword
2477         switch (encoding) {
2478         case eEncodingT1:
2479             Rn = Bits32(opcode, 19, 16);
2480             Rm = Bits32(opcode, 3, 0);
2481             is_tbh = BitIsSet(opcode, 4);
2482             if (Rn == 13 || BadReg(Rm))
2483                 return false;
2484             if (InITBlock() && !LastInITBlock())
2485                 return false;
2486             break;
2487         default:
2488             return false;
2489         }
2490 
2491         // Read the address of the table from the operand register Rn.
2492         // The PC can be used, in which case the table immediately follows this instruction.
2493         uint32_t base = ReadCoreReg(Rn, &success);
2494         if (!success)
2495             return false;
2496 
2497         // the table index
2498         uint32_t index = ReadCoreReg(Rm, &success);
2499         if (!success)
2500             return false;
2501 
2502         // the offsetted table address
2503         addr_t addr = base + (is_tbh ? index*2 : index);
2504 
2505         // PC-relative offset to branch forward
2506         EmulateInstruction::Context context;
2507         context.type = EmulateInstruction::eContextTableBranchReadMemory;
2508         uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2509         if (!success)
2510             return false;
2511 
2512         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2513         if (!success)
2514             return false;
2515 
2516         // target address
2517         addr_t target = pc + offset;
2518         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2519         context.SetISAAndImmediateSigned (eModeThumb, 4 + offset);
2520 
2521         if (!BranchWritePC(context, target))
2522             return false;
2523     }
2524 
2525     return true;
2526 }
2527 
2528 // This instruction adds an immediate value to a register value, and writes the result to the destination register.
2529 // It can optionally update the condition flags based on the result.
2530 bool
2531 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding)
2532 {
2533 #if 0
2534     if ConditionPassed() then
2535         EncodingSpecificOperations();
2536         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2537         R[d] = result;
2538         if setflags then
2539             APSR.N = result<31>;
2540             APSR.Z = IsZeroBit(result);
2541             APSR.C = carry;
2542             APSR.V = overflow;
2543 #endif
2544 
2545     bool success = false;
2546 
2547     if (ConditionPassed(opcode))
2548     {
2549         uint32_t d;
2550         uint32_t n;
2551         bool setflags;
2552         uint32_t imm32;
2553         uint32_t carry_out;
2554 
2555         //EncodingSpecificOperations();
2556         switch (encoding)
2557         {
2558             case eEncodingT1:
2559                 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32);
2560                 d = Bits32 (opcode, 2, 0);
2561                 n = Bits32 (opcode, 5, 3);
2562                 setflags = !InITBlock();
2563                 imm32 = Bits32 (opcode, 8,6);
2564 
2565                 break;
2566 
2567             case eEncodingT2:
2568                 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32);
2569                 d = Bits32 (opcode, 10, 8);
2570                 n = Bits32 (opcode, 10, 8);
2571                 setflags = !InITBlock();
2572                 imm32 = Bits32 (opcode, 7, 0);
2573 
2574                 break;
2575 
2576             case eEncodingT3:
2577                 // if Rd == '1111' && S == '1' then SEE CMN (immediate);
2578                 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8);
2579                 d = Bits32 (opcode, 11, 8);
2580                 n = Bits32 (opcode, 19, 16);
2581                 setflags = BitIsSet (opcode, 20);
2582                 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out);
2583 
2584                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2585                 if (n == 13)
2586                     return EmulateADDSPImm(opcode, eEncodingT3);
2587 
2588                 // if BadReg(d) || n == 15 then UNPREDICTABLE;
2589                 if (BadReg (d) || (n == 15))
2590                     return false;
2591 
2592                 break;
2593 
2594             case eEncodingT4:
2595             {
2596                 // if Rn == '1111' then SEE ADR;
2597                 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
2598                 d = Bits32 (opcode, 11, 8);
2599                 n = Bits32 (opcode, 19, 16);
2600                 setflags = false;
2601                 uint32_t i = Bit32 (opcode, 26);
2602                 uint32_t imm3 = Bits32 (opcode, 14, 12);
2603                 uint32_t imm8 = Bits32 (opcode, 7, 0);
2604                 imm32 = (i << 11) | (imm3 << 8) | imm8;
2605 
2606                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2607                 if (n == 13)
2608                     return EmulateADDSPImm(opcode, eEncodingT4);
2609 
2610                 // if BadReg(d) then UNPREDICTABLE;
2611                 if (BadReg (d))
2612                     return false;
2613 
2614                 break;
2615             }
2616 
2617             default:
2618                 return false;
2619         }
2620 
2621         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2622         if (!success)
2623             return false;
2624 
2625         //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2626         AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
2627 
2628         RegisterInfo reg_n;
2629         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
2630 
2631         EmulateInstruction::Context context;
2632         context.type = eContextArithmetic;
2633         context.SetRegisterPlusOffset (reg_n, imm32);
2634 
2635         //R[d] = result;
2636         //if setflags then
2637             //APSR.N = result<31>;
2638             //APSR.Z = IsZeroBit(result);
2639             //APSR.C = carry;
2640             //APSR.V = overflow;
2641         if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
2642             return false;
2643 
2644     }
2645     return true;
2646 }
2647 
2648 // This instruction adds an immediate value to a register value, and writes the result to the destination
2649 // register.  It can optionally update the condition flags based on the result.
2650 bool
2651 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding)
2652 {
2653 #if 0
2654     // ARM pseudo code...
2655     if ConditionPassed() then
2656         EncodingSpecificOperations();
2657         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2658         if d == 15 then
2659             ALUWritePC(result); // setflags is always FALSE here
2660         else
2661             R[d] = result;
2662             if setflags then
2663                 APSR.N = result<31>;
2664                 APSR.Z = IsZeroBit(result);
2665                 APSR.C = carry;
2666                 APSR.V = overflow;
2667 #endif
2668 
2669     bool success = false;
2670 
2671     if (ConditionPassed(opcode))
2672     {
2673         uint32_t Rd, Rn;
2674         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
2675         bool setflags;
2676         switch (encoding)
2677         {
2678         case eEncodingA1:
2679             Rd = Bits32(opcode, 15, 12);
2680             Rn = Bits32(opcode, 19, 16);
2681             setflags = BitIsSet(opcode, 20);
2682             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2683             break;
2684         default:
2685             return false;
2686         }
2687 
2688         // Read the first operand.
2689         uint32_t val1 = ReadCoreReg(Rn, &success);
2690         if (!success)
2691             return false;
2692 
2693         AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
2694 
2695         EmulateInstruction::Context context;
2696         if (Rd == 13)
2697             context.type = EmulateInstruction::eContextAdjustStackPointer;
2698         else if (Rd == GetFramePointerRegisterNumber())
2699             context.type = EmulateInstruction::eContextSetFramePointer;
2700         else
2701             context.type = EmulateInstruction::eContextRegisterPlusOffset;
2702 
2703         RegisterInfo dwarf_reg;
2704         GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
2705         context.SetRegisterPlusOffset (dwarf_reg, imm32);
2706 
2707         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2708             return false;
2709     }
2710     return true;
2711 }
2712 
2713 // This instruction adds a register value and an optionally-shifted register value, and writes the result
2714 // to the destination register. It can optionally update the condition flags based on the result.
2715 bool
2716 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding)
2717 {
2718 #if 0
2719     // ARM pseudo code...
2720     if ConditionPassed() then
2721         EncodingSpecificOperations();
2722         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2723         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2724         if d == 15 then
2725             ALUWritePC(result); // setflags is always FALSE here
2726         else
2727             R[d] = result;
2728             if setflags then
2729                 APSR.N = result<31>;
2730                 APSR.Z = IsZeroBit(result);
2731                 APSR.C = carry;
2732                 APSR.V = overflow;
2733 #endif
2734 
2735     bool success = false;
2736 
2737     if (ConditionPassed(opcode))
2738     {
2739         uint32_t Rd, Rn, Rm;
2740         ARM_ShifterType shift_t;
2741         uint32_t shift_n; // the shift applied to the value read from Rm
2742         bool setflags;
2743         switch (encoding)
2744         {
2745         case eEncodingT1:
2746             Rd = Bits32(opcode, 2, 0);
2747             Rn = Bits32(opcode, 5, 3);
2748             Rm = Bits32(opcode, 8, 6);
2749             setflags = !InITBlock();
2750             shift_t = SRType_LSL;
2751             shift_n = 0;
2752             break;
2753         case eEncodingT2:
2754             Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2755             Rm = Bits32(opcode, 6, 3);
2756             setflags = false;
2757             shift_t = SRType_LSL;
2758             shift_n = 0;
2759             if (Rn == 15 && Rm == 15)
2760                 return false;
2761             if (Rd == 15 && InITBlock() && !LastInITBlock())
2762                 return false;
2763             break;
2764         case eEncodingA1:
2765             Rd = Bits32(opcode, 15, 12);
2766             Rn = Bits32(opcode, 19, 16);
2767             Rm = Bits32(opcode, 3, 0);
2768             setflags = BitIsSet(opcode, 20);
2769             shift_n = DecodeImmShiftARM(opcode, shift_t);
2770             break;
2771         default:
2772             return false;
2773         }
2774 
2775         // Read the first operand.
2776         uint32_t val1 = ReadCoreReg(Rn, &success);
2777         if (!success)
2778             return false;
2779 
2780         // Read the second operand.
2781         uint32_t val2 = ReadCoreReg(Rm, &success);
2782         if (!success)
2783             return false;
2784 
2785         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2786         if (!success)
2787             return false;
2788         AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2789 
2790         EmulateInstruction::Context context;
2791         context.type = eContextArithmetic;
2792         RegisterInfo op1_reg;
2793         RegisterInfo op2_reg;
2794         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
2795         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
2796         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
2797 
2798         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2799             return false;
2800     }
2801     return true;
2802 }
2803 
2804 // Compare Negative (immediate) adds a register value and an immediate value.
2805 // It updates the condition flags based on the result, and discards the result.
2806 bool
2807 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding)
2808 {
2809 #if 0
2810     // ARM pseudo code...
2811     if ConditionPassed() then
2812         EncodingSpecificOperations();
2813         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2814         APSR.N = result<31>;
2815         APSR.Z = IsZeroBit(result);
2816         APSR.C = carry;
2817         APSR.V = overflow;
2818 #endif
2819 
2820     bool success = false;
2821 
2822     uint32_t Rn; // the first operand
2823     uint32_t imm32; // the immediate value to be compared with
2824     switch (encoding) {
2825     case eEncodingT1:
2826         Rn = Bits32(opcode, 19, 16);
2827         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2828         if (Rn == 15)
2829             return false;
2830         break;
2831     case eEncodingA1:
2832         Rn = Bits32(opcode, 19, 16);
2833         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2834         break;
2835     default:
2836         return false;
2837     }
2838     // Read the register value from the operand register Rn.
2839     uint32_t reg_val = ReadCoreReg(Rn, &success);
2840     if (!success)
2841         return false;
2842 
2843     AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
2844 
2845     EmulateInstruction::Context context;
2846     context.type = EmulateInstruction::eContextImmediate;
2847     context.SetNoArgs ();
2848     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2849         return false;
2850 
2851     return true;
2852 }
2853 
2854 // Compare Negative (register) adds a register value and an optionally-shifted register value.
2855 // It updates the condition flags based on the result, and discards the result.
2856 bool
2857 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding)
2858 {
2859 #if 0
2860     // ARM pseudo code...
2861     if ConditionPassed() then
2862         EncodingSpecificOperations();
2863         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2864         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2865         APSR.N = result<31>;
2866         APSR.Z = IsZeroBit(result);
2867         APSR.C = carry;
2868         APSR.V = overflow;
2869 #endif
2870 
2871     bool success = false;
2872 
2873     uint32_t Rn; // the first operand
2874     uint32_t Rm; // the second operand
2875     ARM_ShifterType shift_t;
2876     uint32_t shift_n; // the shift applied to the value read from Rm
2877     switch (encoding) {
2878     case eEncodingT1:
2879         Rn = Bits32(opcode, 2, 0);
2880         Rm = Bits32(opcode, 5, 3);
2881         shift_t = SRType_LSL;
2882         shift_n = 0;
2883         break;
2884     case eEncodingT2:
2885         Rn = Bits32(opcode, 19, 16);
2886         Rm = Bits32(opcode, 3, 0);
2887         shift_n = DecodeImmShiftThumb(opcode, shift_t);
2888         // if n == 15 || BadReg(m) then UNPREDICTABLE;
2889         if (Rn == 15 || BadReg(Rm))
2890             return false;
2891         break;
2892     case eEncodingA1:
2893         Rn = Bits32(opcode, 19, 16);
2894         Rm = Bits32(opcode, 3, 0);
2895         shift_n = DecodeImmShiftARM(opcode, shift_t);
2896         break;
2897     default:
2898         return false;
2899     }
2900     // Read the register value from register Rn.
2901     uint32_t val1 = ReadCoreReg(Rn, &success);
2902     if (!success)
2903         return false;
2904 
2905     // Read the register value from register Rm.
2906     uint32_t val2 = ReadCoreReg(Rm, &success);
2907     if (!success)
2908         return false;
2909 
2910     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2911     if (!success)
2912         return false;
2913     AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2914 
2915     EmulateInstruction::Context context;
2916     context.type = EmulateInstruction::eContextImmediate;
2917     context.SetNoArgs();
2918     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2919         return false;
2920 
2921     return true;
2922 }
2923 
2924 // Compare (immediate) subtracts an immediate value from a register value.
2925 // It updates the condition flags based on the result, and discards the result.
2926 bool
2927 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding)
2928 {
2929 #if 0
2930     // ARM pseudo code...
2931     if ConditionPassed() then
2932         EncodingSpecificOperations();
2933         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2934         APSR.N = result<31>;
2935         APSR.Z = IsZeroBit(result);
2936         APSR.C = carry;
2937         APSR.V = overflow;
2938 #endif
2939 
2940     bool success = false;
2941 
2942     uint32_t Rn; // the first operand
2943     uint32_t imm32; // the immediate value to be compared with
2944     switch (encoding) {
2945     case eEncodingT1:
2946         Rn = Bits32(opcode, 10, 8);
2947         imm32 = Bits32(opcode, 7, 0);
2948         break;
2949     case eEncodingT2:
2950         Rn = Bits32(opcode, 19, 16);
2951         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2952         if (Rn == 15)
2953             return false;
2954         break;
2955     case eEncodingA1:
2956         Rn = Bits32(opcode, 19, 16);
2957         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2958         break;
2959     default:
2960         return false;
2961     }
2962     // Read the register value from the operand register Rn.
2963     uint32_t reg_val = ReadCoreReg(Rn, &success);
2964     if (!success)
2965         return false;
2966 
2967     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
2968 
2969     EmulateInstruction::Context context;
2970     context.type = EmulateInstruction::eContextImmediate;
2971     context.SetNoArgs ();
2972     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2973         return false;
2974 
2975     return true;
2976 }
2977 
2978 // Compare (register) subtracts an optionally-shifted register value from a register value.
2979 // It updates the condition flags based on the result, and discards the result.
2980 bool
2981 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding)
2982 {
2983 #if 0
2984     // ARM pseudo code...
2985     if ConditionPassed() then
2986         EncodingSpecificOperations();
2987         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2988         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2989         APSR.N = result<31>;
2990         APSR.Z = IsZeroBit(result);
2991         APSR.C = carry;
2992         APSR.V = overflow;
2993 #endif
2994 
2995     bool success = false;
2996 
2997     uint32_t Rn; // the first operand
2998     uint32_t Rm; // the second operand
2999     ARM_ShifterType shift_t;
3000     uint32_t shift_n; // the shift applied to the value read from Rm
3001     switch (encoding) {
3002     case eEncodingT1:
3003         Rn = Bits32(opcode, 2, 0);
3004         Rm = Bits32(opcode, 5, 3);
3005         shift_t = SRType_LSL;
3006         shift_n = 0;
3007         break;
3008     case eEncodingT2:
3009         Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
3010         Rm = Bits32(opcode, 6, 3);
3011         shift_t = SRType_LSL;
3012         shift_n = 0;
3013         if (Rn < 8 && Rm < 8)
3014             return false;
3015         if (Rn == 15 || Rm == 15)
3016             return false;
3017         break;
3018     case eEncodingT3:
3019         Rn = Bits32(opcode, 19, 16);
3020         Rm = Bits32(opcode, 3, 0);
3021         shift_n = DecodeImmShiftThumb(opcode, shift_t);
3022         if (Rn == 15 || BadReg(Rm))
3023             return false;
3024         break;
3025     case eEncodingA1:
3026         Rn = Bits32(opcode, 19, 16);
3027         Rm = Bits32(opcode, 3, 0);
3028         shift_n = DecodeImmShiftARM(opcode, shift_t);
3029         break;
3030     default:
3031         return false;
3032     }
3033     // Read the register value from register Rn.
3034     uint32_t val1 = ReadCoreReg(Rn, &success);
3035     if (!success)
3036         return false;
3037 
3038     // Read the register value from register Rm.
3039     uint32_t val2 = ReadCoreReg(Rm, &success);
3040     if (!success)
3041         return false;
3042 
3043     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3044     if (!success)
3045         return false;
3046     AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
3047 
3048     EmulateInstruction::Context context;
3049     context.type = EmulateInstruction::eContextImmediate;
3050     context.SetNoArgs();
3051     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
3052         return false;
3053 
3054     return true;
3055 }
3056 
3057 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
3058 // shifting in copies of its sign bit, and writes the result to the destination register.  It can
3059 // optionally update the condition flags based on the result.
3060 bool
3061 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding)
3062 {
3063 #if 0
3064     // ARM pseudo code...
3065     if ConditionPassed() then
3066         EncodingSpecificOperations();
3067         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3068         if d == 15 then         // Can only occur for ARM encoding
3069             ALUWritePC(result); // setflags is always FALSE here
3070         else
3071             R[d] = result;
3072             if setflags then
3073                 APSR.N = result<31>;
3074                 APSR.Z = IsZeroBit(result);
3075                 APSR.C = carry;
3076                 // APSR.V unchanged
3077 #endif
3078 
3079     return EmulateShiftImm (opcode, encoding, SRType_ASR);
3080 }
3081 
3082 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
3083 // shifting in copies of its sign bit, and writes the result to the destination register.
3084 // The variable number of bits is read from the bottom byte of a register. It can optionally update
3085 // the condition flags based on the result.
3086 bool
3087 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding)
3088 {
3089 #if 0
3090     // ARM pseudo code...
3091     if ConditionPassed() then
3092         EncodingSpecificOperations();
3093         shift_n = UInt(R[m]<7:0>);
3094         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3095         R[d] = result;
3096         if setflags then
3097             APSR.N = result<31>;
3098             APSR.Z = IsZeroBit(result);
3099             APSR.C = carry;
3100             // APSR.V unchanged
3101 #endif
3102 
3103     return EmulateShiftReg (opcode, encoding, SRType_ASR);
3104 }
3105 
3106 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
3107 // shifting in zeros, and writes the result to the destination register.  It can optionally
3108 // update the condition flags based on the result.
3109 bool
3110 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding)
3111 {
3112 #if 0
3113     // ARM pseudo code...
3114     if ConditionPassed() then
3115         EncodingSpecificOperations();
3116         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3117         if d == 15 then         // Can only occur for ARM encoding
3118             ALUWritePC(result); // setflags is always FALSE here
3119         else
3120             R[d] = result;
3121             if setflags then
3122                 APSR.N = result<31>;
3123                 APSR.Z = IsZeroBit(result);
3124                 APSR.C = carry;
3125                 // APSR.V unchanged
3126 #endif
3127 
3128     return EmulateShiftImm (opcode, encoding, SRType_LSL);
3129 }
3130 
3131 // Logical Shift Left (register) shifts a register value left by a variable number of bits,
3132 // shifting in zeros, and writes the result to the destination register.  The variable number
3133 // of bits is read from the bottom byte of a register. It can optionally update the condition
3134 // flags based on the result.
3135 bool
3136 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding)
3137 {
3138 #if 0
3139     // ARM pseudo code...
3140     if ConditionPassed() then
3141         EncodingSpecificOperations();
3142         shift_n = UInt(R[m]<7:0>);
3143         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3144         R[d] = result;
3145         if setflags then
3146             APSR.N = result<31>;
3147             APSR.Z = IsZeroBit(result);
3148             APSR.C = carry;
3149             // APSR.V unchanged
3150 #endif
3151 
3152     return EmulateShiftReg (opcode, encoding, SRType_LSL);
3153 }
3154 
3155 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
3156 // shifting in zeros, and writes the result to the destination register.  It can optionally
3157 // update the condition flags based on the result.
3158 bool
3159 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding)
3160 {
3161 #if 0
3162     // ARM pseudo code...
3163     if ConditionPassed() then
3164         EncodingSpecificOperations();
3165         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3166         if d == 15 then         // Can only occur for ARM encoding
3167             ALUWritePC(result); // setflags is always FALSE here
3168         else
3169             R[d] = result;
3170             if setflags then
3171                 APSR.N = result<31>;
3172                 APSR.Z = IsZeroBit(result);
3173                 APSR.C = carry;
3174                 // APSR.V unchanged
3175 #endif
3176 
3177     return EmulateShiftImm (opcode, encoding, SRType_LSR);
3178 }
3179 
3180 // Logical Shift Right (register) shifts a register value right by a variable number of bits,
3181 // shifting in zeros, and writes the result to the destination register.  The variable number
3182 // of bits is read from the bottom byte of a register. It can optionally update the condition
3183 // flags based on the result.
3184 bool
3185 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding)
3186 {
3187 #if 0
3188     // ARM pseudo code...
3189     if ConditionPassed() then
3190         EncodingSpecificOperations();
3191         shift_n = UInt(R[m]<7:0>);
3192         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3193         R[d] = result;
3194         if setflags then
3195             APSR.N = result<31>;
3196             APSR.Z = IsZeroBit(result);
3197             APSR.C = carry;
3198             // APSR.V unchanged
3199 #endif
3200 
3201     return EmulateShiftReg (opcode, encoding, SRType_LSR);
3202 }
3203 
3204 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
3205 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3206 // It can optionally update the condition flags based on the result.
3207 bool
3208 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding)
3209 {
3210 #if 0
3211     // ARM pseudo code...
3212     if ConditionPassed() then
3213         EncodingSpecificOperations();
3214         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3215         if d == 15 then         // Can only occur for ARM encoding
3216             ALUWritePC(result); // setflags is always FALSE here
3217         else
3218             R[d] = result;
3219             if setflags then
3220                 APSR.N = result<31>;
3221                 APSR.Z = IsZeroBit(result);
3222                 APSR.C = carry;
3223                 // APSR.V unchanged
3224 #endif
3225 
3226     return EmulateShiftImm (opcode, encoding, SRType_ROR);
3227 }
3228 
3229 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
3230 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3231 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
3232 // flags based on the result.
3233 bool
3234 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding)
3235 {
3236 #if 0
3237     // ARM pseudo code...
3238     if ConditionPassed() then
3239         EncodingSpecificOperations();
3240         shift_n = UInt(R[m]<7:0>);
3241         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3242         R[d] = result;
3243         if setflags then
3244             APSR.N = result<31>;
3245             APSR.Z = IsZeroBit(result);
3246             APSR.C = carry;
3247             // APSR.V unchanged
3248 #endif
3249 
3250     return EmulateShiftReg (opcode, encoding, SRType_ROR);
3251 }
3252 
3253 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
3254 // with the carry flag shifted into bit [31].
3255 //
3256 // RRX can optionally update the condition flags based on the result.
3257 // In that case, bit [0] is shifted into the carry flag.
3258 bool
3259 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding)
3260 {
3261 #if 0
3262     // ARM pseudo code...
3263     if ConditionPassed() then
3264         EncodingSpecificOperations();
3265         (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3266         if d == 15 then         // Can only occur for ARM encoding
3267             ALUWritePC(result); // setflags is always FALSE here
3268         else
3269             R[d] = result;
3270             if setflags then
3271                 APSR.N = result<31>;
3272                 APSR.Z = IsZeroBit(result);
3273                 APSR.C = carry;
3274                 // APSR.V unchanged
3275 #endif
3276 
3277     return EmulateShiftImm (opcode, encoding, SRType_RRX);
3278 }
3279 
3280 bool
3281 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3282 {
3283 //    assert(shift_type == SRType_ASR
3284 //           || shift_type == SRType_LSL
3285 //           || shift_type == SRType_LSR
3286 //           || shift_type == SRType_ROR
3287 //           || shift_type == SRType_RRX);
3288 
3289     bool success = false;
3290 
3291     if (ConditionPassed(opcode))
3292     {
3293         uint32_t Rd;    // the destination register
3294         uint32_t Rm;    // the first operand register
3295         uint32_t imm5;  // encoding for the shift amount
3296         uint32_t carry; // the carry bit after the shift operation
3297         bool setflags;
3298 
3299         // Special case handling!
3300         // A8.6.139 ROR (immediate) -- Encoding T1
3301         ARMEncoding use_encoding = encoding;
3302         if (shift_type == SRType_ROR && use_encoding == eEncodingT1)
3303         {
3304             // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
3305             // have the same decoding of bit fields as the other Thumb2 shift operations.
3306             use_encoding = eEncodingT2;
3307         }
3308 
3309         switch (use_encoding) {
3310         case eEncodingT1:
3311             // Due to the above special case handling!
3312             if (shift_type == SRType_ROR)
3313                 return false;
3314 
3315             Rd = Bits32(opcode, 2, 0);
3316             Rm = Bits32(opcode, 5, 3);
3317             setflags = !InITBlock();
3318             imm5 = Bits32(opcode, 10, 6);
3319             break;
3320         case eEncodingT2:
3321             // A8.6.141 RRX
3322             // There's no imm form of RRX instructions.
3323             if (shift_type == SRType_RRX)
3324                 return false;
3325 
3326             Rd = Bits32(opcode, 11, 8);
3327             Rm = Bits32(opcode, 3, 0);
3328             setflags = BitIsSet(opcode, 20);
3329             imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3330             if (BadReg(Rd) || BadReg(Rm))
3331                 return false;
3332             break;
3333         case eEncodingA1:
3334             Rd = Bits32(opcode, 15, 12);
3335             Rm = Bits32(opcode, 3, 0);
3336             setflags = BitIsSet(opcode, 20);
3337             imm5 = Bits32(opcode, 11, 7);
3338             break;
3339         default:
3340             return false;
3341         }
3342 
3343         // A8.6.139 ROR (immediate)
3344         if (shift_type == SRType_ROR && imm5 == 0)
3345             shift_type = SRType_RRX;
3346 
3347         // Get the first operand.
3348         uint32_t value = ReadCoreReg (Rm, &success);
3349         if (!success)
3350             return false;
3351 
3352         // Decode the shift amount if not RRX.
3353         uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3354 
3355         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3356         if (!success)
3357             return false;
3358 
3359         // The context specifies that an immediate is to be moved into Rd.
3360         EmulateInstruction::Context context;
3361         context.type = EmulateInstruction::eContextImmediate;
3362         context.SetNoArgs ();
3363 
3364         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3365             return false;
3366     }
3367     return true;
3368 }
3369 
3370 bool
3371 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3372 {
3373     // assert(shift_type == SRType_ASR
3374     //        || shift_type == SRType_LSL
3375     //        || shift_type == SRType_LSR
3376     //        || shift_type == SRType_ROR);
3377 
3378     bool success = false;
3379 
3380     if (ConditionPassed(opcode))
3381     {
3382         uint32_t Rd;    // the destination register
3383         uint32_t Rn;    // the first operand register
3384         uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
3385         uint32_t carry; // the carry bit after the shift operation
3386         bool setflags;
3387         switch (encoding) {
3388         case eEncodingT1:
3389             Rd = Bits32(opcode, 2, 0);
3390             Rn = Rd;
3391             Rm = Bits32(opcode, 5, 3);
3392             setflags = !InITBlock();
3393             break;
3394         case eEncodingT2:
3395             Rd = Bits32(opcode, 11, 8);
3396             Rn = Bits32(opcode, 19, 16);
3397             Rm = Bits32(opcode, 3, 0);
3398             setflags = BitIsSet(opcode, 20);
3399             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3400                 return false;
3401             break;
3402         case eEncodingA1:
3403             Rd = Bits32(opcode, 15, 12);
3404             Rn = Bits32(opcode, 3, 0);
3405             Rm = Bits32(opcode, 11, 8);
3406             setflags = BitIsSet(opcode, 20);
3407             if (Rd == 15 || Rn == 15 || Rm == 15)
3408                 return false;
3409             break;
3410         default:
3411             return false;
3412         }
3413 
3414         // Get the first operand.
3415         uint32_t value = ReadCoreReg (Rn, &success);
3416         if (!success)
3417             return false;
3418         // Get the Rm register content.
3419         uint32_t val = ReadCoreReg (Rm, &success);
3420         if (!success)
3421             return false;
3422 
3423         // Get the shift amount.
3424         uint32_t amt = Bits32(val, 7, 0);
3425 
3426         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3427         if (!success)
3428             return false;
3429 
3430         // The context specifies that an immediate is to be moved into Rd.
3431         EmulateInstruction::Context context;
3432         context.type = EmulateInstruction::eContextImmediate;
3433         context.SetNoArgs ();
3434 
3435         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3436             return false;
3437     }
3438     return true;
3439 }
3440 
3441 // LDM loads multiple registers from consecutive memory locations, using an
3442 // address from a base register.  Optionally the address just above the highest of those locations
3443 // can be written back to the base register.
3444 bool
3445 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding)
3446 {
3447 #if 0
3448     // ARM pseudo code...
3449     if ConditionPassed()
3450         EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3451         address = R[n];
3452 
3453         for i = 0 to 14
3454             if registers<i> == '1' then
3455                 R[i] = MemA[address, 4]; address = address + 4;
3456         if registers<15> == '1' then
3457             LoadWritePC (MemA[address, 4]);
3458 
3459         if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3460         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3461 
3462 #endif
3463 
3464     bool success = false;
3465     bool conditional = false;
3466     if (ConditionPassed(opcode, &conditional))
3467     {
3468         uint32_t n;
3469         uint32_t registers = 0;
3470         bool wback;
3471         const uint32_t addr_byte_size = GetAddressByteSize();
3472         switch (encoding)
3473         {
3474             case eEncodingT1:
3475                 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0');
3476                 n = Bits32 (opcode, 10, 8);
3477                 registers = Bits32 (opcode, 7, 0);
3478                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3479                 wback = BitIsClear (registers, n);
3480                 // if BitCount(registers) < 1 then UNPREDICTABLE;
3481                 if (BitCount(registers) < 1)
3482                     return false;
3483                 break;
3484             case eEncodingT2:
3485                 // if W == '1' && Rn == '1101' then SEE POP;
3486                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3487                 n = Bits32 (opcode, 19, 16);
3488                 registers = Bits32 (opcode, 15, 0);
3489                 registers = registers & 0xdfff; // Make sure bit 13 is zero.
3490                 wback = BitIsSet (opcode, 21);
3491 
3492                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3493                 if ((n == 15)
3494                     || (BitCount (registers) < 2)
3495                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3496                     return false;
3497 
3498                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3499                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3500                     return false;
3501 
3502                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3503                 if (wback
3504                     && BitIsSet (registers, n))
3505                     return false;
3506                 break;
3507 
3508             case eEncodingA1:
3509                 n = Bits32 (opcode, 19, 16);
3510                 registers = Bits32 (opcode, 15, 0);
3511                 wback = BitIsSet (opcode, 21);
3512                 if ((n == 15)
3513                     || (BitCount (registers) < 1))
3514                     return false;
3515                 break;
3516             default:
3517                 return false;
3518         }
3519 
3520         int32_t offset = 0;
3521         const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3522         if (!success)
3523             return false;
3524 
3525         EmulateInstruction::Context context;
3526         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3527         RegisterInfo dwarf_reg;
3528         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3529         context.SetRegisterPlusOffset (dwarf_reg, offset);
3530 
3531         for (int i = 0; i < 14; ++i)
3532         {
3533             if (BitIsSet (registers, i))
3534             {
3535                 context.type = EmulateInstruction::eContextRegisterPlusOffset;
3536                 context.SetRegisterPlusOffset (dwarf_reg, offset);
3537                 if (wback && (n == 13)) // Pop Instruction
3538                 {
3539                     if (conditional)
3540                         context.type = EmulateInstruction::eContextRegisterLoad;
3541                     else
3542                         context.type = EmulateInstruction::eContextPopRegisterOffStack;
3543                 }
3544 
3545                 // R[i] = MemA [address, 4]; address = address + 4;
3546                 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3547                 if (!success)
3548                     return false;
3549 
3550                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3551                     return false;
3552 
3553                 offset += addr_byte_size;
3554             }
3555         }
3556 
3557         if (BitIsSet (registers, 15))
3558         {
3559             //LoadWritePC (MemA [address, 4]);
3560             context.type = EmulateInstruction::eContextRegisterPlusOffset;
3561             context.SetRegisterPlusOffset (dwarf_reg, offset);
3562             uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3563             if (!success)
3564                 return false;
3565             // In ARMv5T and above, this is an interworking branch.
3566             if (!LoadWritePC(context, data))
3567                 return false;
3568         }
3569 
3570         if (wback && BitIsClear (registers, n))
3571         {
3572             // R[n] = R[n] + 4 * BitCount (registers)
3573             int32_t offset = addr_byte_size * BitCount (registers);
3574             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3575             context.SetRegisterPlusOffset (dwarf_reg, offset);
3576 
3577             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
3578                 return false;
3579         }
3580         if (wback && BitIsSet (registers, n))
3581             // R[n] bits(32) UNKNOWN;
3582             return WriteBits32Unknown (n);
3583     }
3584     return true;
3585 }
3586 
3587 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register.
3588 // The consecutive memory locations end at this address and the address just below the lowest of those locations
3589 // can optionally be written back to the base register.
3590 bool
3591 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding)
3592 {
3593 #if 0
3594     // ARM pseudo code...
3595     if ConditionPassed() then
3596         EncodingSpecificOperations();
3597         address = R[n] - 4*BitCount(registers) + 4;
3598 
3599         for i = 0 to 14
3600             if registers<i> == '1' then
3601                   R[i] = MemA[address,4]; address = address + 4;
3602 
3603         if registers<15> == '1' then
3604             LoadWritePC(MemA[address,4]);
3605 
3606         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3607         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3608 #endif
3609 
3610     bool success = false;
3611 
3612     if (ConditionPassed(opcode))
3613     {
3614         uint32_t n;
3615         uint32_t registers = 0;
3616         bool wback;
3617         const uint32_t addr_byte_size = GetAddressByteSize();
3618 
3619         // EncodingSpecificOperations();
3620         switch (encoding)
3621         {
3622             case eEncodingA1:
3623                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3624                 n = Bits32 (opcode, 19, 16);
3625                 registers = Bits32 (opcode, 15, 0);
3626                 wback = BitIsSet (opcode, 21);
3627 
3628                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3629                 if ((n == 15) || (BitCount (registers) < 1))
3630                     return false;
3631 
3632                 break;
3633 
3634             default:
3635                 return false;
3636         }
3637         // address = R[n] - 4*BitCount(registers) + 4;
3638 
3639         int32_t offset = 0;
3640         addr_t Rn = ReadCoreReg (n, &success);
3641 
3642         if (!success)
3643             return false;
3644 
3645         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size;
3646 
3647         EmulateInstruction::Context context;
3648         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3649         RegisterInfo dwarf_reg;
3650         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3651         context.SetRegisterPlusOffset (dwarf_reg, offset);
3652 
3653         // for i = 0 to 14
3654         for (int i = 0; i < 14; ++i)
3655         {
3656             // if registers<i> == '1' then
3657             if (BitIsSet (registers, i))
3658             {
3659                   // R[i] = MemA[address,4]; address = address + 4;
3660                   context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3661                   uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3662                   if (!success)
3663                       return false;
3664                   if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3665                       return false;
3666                   offset += addr_byte_size;
3667             }
3668         }
3669 
3670         // if registers<15> == '1' then
3671         //     LoadWritePC(MemA[address,4]);
3672         if (BitIsSet (registers, 15))
3673         {
3674             context.SetRegisterPlusOffset (dwarf_reg, offset);
3675             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3676             if (!success)
3677                 return false;
3678             // In ARMv5T and above, this is an interworking branch.
3679             if (!LoadWritePC(context, data))
3680                 return false;
3681         }
3682 
3683         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3684         if (wback && BitIsClear (registers, n))
3685         {
3686             if (!success)
3687                 return false;
3688 
3689             offset = (addr_byte_size * BitCount (registers)) * -1;
3690             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3691             context.SetImmediateSigned (offset);
3692             addr_t addr = Rn + offset;
3693             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3694                 return false;
3695         }
3696 
3697         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3698         if (wback && BitIsSet (registers, n))
3699             return WriteBits32Unknown (n);
3700     }
3701     return true;
3702 }
3703 
3704 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
3705 // consecutive memory locations end just below this address, and the address of the lowest of those locations can
3706 // be optionally written back to the base register.
3707 bool
3708 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding)
3709 {
3710 #if 0
3711     // ARM pseudo code...
3712     if ConditionPassed() then
3713         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3714         address = R[n] - 4*BitCount(registers);
3715 
3716         for i = 0 to 14
3717             if registers<i> == '1' then
3718                   R[i] = MemA[address,4]; address = address + 4;
3719         if registers<15> == '1' then
3720                   LoadWritePC(MemA[address,4]);
3721 
3722         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3723         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3724 #endif
3725 
3726     bool success = false;
3727 
3728     if (ConditionPassed(opcode))
3729     {
3730         uint32_t n;
3731         uint32_t registers = 0;
3732         bool wback;
3733         const uint32_t addr_byte_size = GetAddressByteSize();
3734         switch (encoding)
3735         {
3736             case eEncodingT1:
3737                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3738                 n = Bits32 (opcode, 19, 16);
3739                 registers = Bits32 (opcode, 15, 0);
3740                 registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
3741                 wback = BitIsSet (opcode, 21);
3742 
3743                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3744                 if ((n == 15)
3745                     || (BitCount (registers) < 2)
3746                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3747                     return false;
3748 
3749                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3750                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3751                     return false;
3752 
3753                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3754                 if (wback && BitIsSet (registers, n))
3755                     return false;
3756 
3757                 break;
3758 
3759             case eEncodingA1:
3760                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3761                 n = Bits32 (opcode, 19, 16);
3762                 registers = Bits32 (opcode, 15, 0);
3763                 wback = BitIsSet (opcode, 21);
3764 
3765                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3766                 if ((n == 15) || (BitCount (registers) < 1))
3767                     return false;
3768 
3769                 break;
3770 
3771             default:
3772                 return false;
3773         }
3774 
3775         // address = R[n] - 4*BitCount(registers);
3776 
3777         int32_t offset = 0;
3778         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3779 
3780         if (!success)
3781             return false;
3782 
3783         addr_t address = Rn - (addr_byte_size * BitCount (registers));
3784         EmulateInstruction::Context context;
3785         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3786         RegisterInfo dwarf_reg;
3787         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3788         context.SetRegisterPlusOffset (dwarf_reg, Rn - address);
3789 
3790         for (int i = 0; i < 14; ++i)
3791         {
3792             if (BitIsSet (registers, i))
3793             {
3794                 // R[i] = MemA[address,4]; address = address + 4;
3795                 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3796                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3797                 if (!success)
3798                     return false;
3799 
3800                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3801                     return false;
3802 
3803                 offset += addr_byte_size;
3804             }
3805         }
3806 
3807         // if registers<15> == '1' then
3808         //     LoadWritePC(MemA[address,4]);
3809         if (BitIsSet (registers, 15))
3810         {
3811             context.SetRegisterPlusOffset (dwarf_reg, offset);
3812             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3813             if (!success)
3814                 return false;
3815             // In ARMv5T and above, this is an interworking branch.
3816             if (!LoadWritePC(context, data))
3817                 return false;
3818         }
3819 
3820         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3821         if (wback && BitIsClear (registers, n))
3822         {
3823             if (!success)
3824                 return false;
3825 
3826             offset = (addr_byte_size * BitCount (registers)) * -1;
3827             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3828             context.SetImmediateSigned (offset);
3829             addr_t addr = Rn + offset;
3830             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3831                 return false;
3832         }
3833 
3834         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3835         if (wback && BitIsSet (registers, n))
3836             return WriteBits32Unknown (n);
3837     }
3838     return true;
3839 }
3840 
3841 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
3842 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can
3843 // optinoally be written back to the base register.
3844 bool
3845 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding)
3846 {
3847 #if 0
3848     if ConditionPassed() then
3849         EncodingSpecificOperations();
3850         address = R[n] + 4;
3851 
3852         for i = 0 to 14
3853             if registers<i> == '1' then
3854                   R[i] = MemA[address,4]; address = address + 4;
3855         if registers<15> == '1' then
3856             LoadWritePC(MemA[address,4]);
3857 
3858         if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3859         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3860 #endif
3861 
3862     bool success = false;
3863 
3864     if (ConditionPassed(opcode))
3865     {
3866         uint32_t n;
3867         uint32_t registers = 0;
3868         bool wback;
3869         const uint32_t addr_byte_size = GetAddressByteSize();
3870         switch (encoding)
3871         {
3872             case eEncodingA1:
3873                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3874                 n = Bits32 (opcode, 19, 16);
3875                 registers = Bits32 (opcode, 15, 0);
3876                 wback = BitIsSet (opcode, 21);
3877 
3878                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3879                 if ((n == 15) || (BitCount (registers) < 1))
3880                     return false;
3881 
3882                 break;
3883             default:
3884                 return false;
3885         }
3886         // address = R[n] + 4;
3887 
3888         int32_t offset = 0;
3889         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3890 
3891         if (!success)
3892             return false;
3893 
3894         addr_t address = Rn + addr_byte_size;
3895 
3896         EmulateInstruction::Context context;
3897         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3898         RegisterInfo dwarf_reg;
3899         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3900         context.SetRegisterPlusOffset (dwarf_reg, offset);
3901 
3902         for (int i = 0; i < 14; ++i)
3903         {
3904             if (BitIsSet (registers, i))
3905             {
3906                 // R[i] = MemA[address,4]; address = address + 4;
3907 
3908                 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size);
3909                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3910                 if (!success)
3911                     return false;
3912 
3913                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3914                     return false;
3915 
3916                 offset += addr_byte_size;
3917             }
3918         }
3919 
3920         // if registers<15> == '1' then
3921         //     LoadWritePC(MemA[address,4]);
3922         if (BitIsSet (registers, 15))
3923         {
3924             context.SetRegisterPlusOffset (dwarf_reg, offset);
3925             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3926             if (!success)
3927                 return false;
3928             // In ARMv5T and above, this is an interworking branch.
3929             if (!LoadWritePC(context, data))
3930                 return false;
3931         }
3932 
3933         // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3934         if (wback && BitIsClear (registers, n))
3935         {
3936             if (!success)
3937                 return false;
3938 
3939             offset = addr_byte_size * BitCount (registers);
3940             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3941             context.SetImmediateSigned (offset);
3942             addr_t addr = Rn + offset;
3943             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3944                 return false;
3945         }
3946 
3947         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3948         if (wback && BitIsSet (registers, n))
3949             return WriteBits32Unknown (n);
3950     }
3951     return true;
3952 }
3953 
3954 // Load Register (immediate) calculates an address from a base register value and
3955 // an immediate offset, loads a word from memory, and writes to a register.
3956 // LDR (immediate, Thumb)
3957 bool
3958 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding)
3959 {
3960 #if 0
3961     // ARM pseudo code...
3962     if (ConditionPassed())
3963     {
3964         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3965         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3966         address = if index then offset_addr else R[n];
3967         data = MemU[address,4];
3968         if wback then R[n] = offset_addr;
3969         if t == 15 then
3970             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3971         elsif UnalignedSupport() || address<1:0> = '00' then
3972             R[t] = data;
3973         else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3974     }
3975 #endif
3976 
3977     bool success = false;
3978 
3979     if (ConditionPassed(opcode))
3980     {
3981         uint32_t Rt; // the destination register
3982         uint32_t Rn; // the base register
3983         uint32_t imm32; // the immediate offset used to form the address
3984         addr_t offset_addr; // the offset address
3985         addr_t address; // the calculated address
3986         uint32_t data; // the literal data value from memory load
3987         bool add, index, wback;
3988         switch (encoding) {
3989             case eEncodingT1:
3990                 Rt = Bits32(opcode, 2, 0);
3991                 Rn = Bits32(opcode, 5, 3);
3992                 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3993                 // index = TRUE; add = TRUE; wback = FALSE
3994                 add = true;
3995                 index = true;
3996                 wback = false;
3997 
3998                 break;
3999 
4000             case eEncodingT2:
4001                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4002                 Rt = Bits32 (opcode, 10, 8);
4003                 Rn = 13;
4004                 imm32 = Bits32 (opcode, 7, 0) << 2;
4005 
4006                 // index = TRUE; add = TRUE; wback = FALSE;
4007                 index = true;
4008                 add = true;
4009                 wback = false;
4010 
4011                 break;
4012 
4013             case eEncodingT3:
4014                 // if Rn == '1111' then SEE LDR (literal);
4015                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4016                 Rt = Bits32 (opcode, 15, 12);
4017                 Rn = Bits32 (opcode, 19, 16);
4018                 imm32 = Bits32 (opcode, 11, 0);
4019 
4020                 // index = TRUE; add = TRUE; wback = FALSE;
4021                 index = true;
4022                 add = true;
4023                 wback = false;
4024 
4025                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
4026                 if ((Rt == 15) && InITBlock() && !LastInITBlock())
4027                     return false;
4028 
4029                 break;
4030 
4031             case eEncodingT4:
4032                 // if Rn == '1111' then SEE LDR (literal);
4033                 // if P == '1' && U == '1' && W == '0' then SEE LDRT;
4034                 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
4035                 // if P == '0' && W == '0' then UNDEFINED;
4036                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
4037                     return false;
4038 
4039                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4040                 Rt = Bits32 (opcode, 15, 12);
4041                 Rn = Bits32 (opcode, 19, 16);
4042                 imm32 = Bits32 (opcode, 7, 0);
4043 
4044                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4045                 index = BitIsSet (opcode, 10);
4046                 add = BitIsSet (opcode, 9);
4047                 wback = BitIsSet (opcode, 8);
4048 
4049                 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
4050                 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock()))
4051                     return false;
4052 
4053                 break;
4054 
4055             default:
4056                 return false;
4057         }
4058         uint32_t base = ReadCoreReg (Rn, &success);
4059         if (!success)
4060             return false;
4061         if (add)
4062             offset_addr = base + imm32;
4063         else
4064             offset_addr = base - imm32;
4065 
4066         address = (index ? offset_addr : base);
4067 
4068         RegisterInfo base_reg;
4069         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
4070         if (wback)
4071         {
4072             EmulateInstruction::Context ctx;
4073             if (Rn == 13)
4074             {
4075                 ctx.type = eContextAdjustStackPointer;
4076                 ctx.SetImmediateSigned((int32_t) (offset_addr - base));
4077             }
4078             else if (Rn == GetFramePointerRegisterNumber())
4079             {
4080                 ctx.type = eContextSetFramePointer;
4081                 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
4082             }
4083             else
4084             {
4085                 ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
4086                 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
4087             }
4088 
4089 
4090             if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
4091                 return false;
4092         }
4093 
4094         // Prepare to write to the Rt register.
4095         EmulateInstruction::Context context;
4096         context.type = EmulateInstruction::eContextRegisterLoad;
4097         context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
4098 
4099         // Read memory from the address.
4100         data = MemURead(context, address, 4, 0, &success);
4101         if (!success)
4102             return false;
4103 
4104         if (Rt == 15)
4105         {
4106             if (Bits32(address, 1, 0) == 0)
4107             {
4108                 if (!LoadWritePC(context, data))
4109                     return false;
4110             }
4111             else
4112                 return false;
4113         }
4114         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
4115         {
4116             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
4117                 return false;
4118         }
4119         else
4120             WriteBits32Unknown (Rt);
4121     }
4122     return true;
4123 }
4124 
4125 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
4126 // from a base register.  The consecutive memory locations start at this address, and the address just above the last
4127 // of those locations can optionally be written back to the base register.
4128 bool
4129 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding)
4130 {
4131 #if 0
4132     if ConditionPassed() then
4133         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4134         address = R[n];
4135 
4136         for i = 0 to 14
4137             if registers<i> == '1' then
4138                 if i == n && wback && i != LowestSetBit(registers) then
4139                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4140                 else
4141                     MemA[address,4] = R[i];
4142                 address = address + 4;
4143 
4144         if registers<15> == '1' then // Only possible for encoding A1
4145             MemA[address,4] = PCStoreValue();
4146         if wback then R[n] = R[n] + 4*BitCount(registers);
4147 #endif
4148 
4149     bool success = false;
4150 
4151     if (ConditionPassed(opcode))
4152     {
4153         uint32_t n;
4154         uint32_t registers = 0;
4155         bool wback;
4156         const uint32_t addr_byte_size = GetAddressByteSize();
4157 
4158         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4159         switch (encoding)
4160         {
4161             case eEncodingT1:
4162                 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4163                 n = Bits32 (opcode, 10, 8);
4164                 registers = Bits32 (opcode, 7, 0);
4165                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
4166                 wback = true;
4167 
4168                 // if BitCount(registers) < 1 then UNPREDICTABLE;
4169                 if (BitCount (registers) < 1)
4170                     return false;
4171 
4172                 break;
4173 
4174             case eEncodingT2:
4175                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4176                 n = Bits32 (opcode, 19, 16);
4177                 registers = Bits32 (opcode, 15, 0);
4178                 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4179                 wback = BitIsSet (opcode, 21);
4180 
4181                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4182                 if ((n == 15) || (BitCount (registers) < 2))
4183                     return false;
4184 
4185                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4186                 if (wback && BitIsSet (registers, n))
4187                     return false;
4188 
4189                 break;
4190 
4191             case eEncodingA1:
4192                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4193                 n = Bits32 (opcode, 19, 16);
4194                 registers = Bits32 (opcode, 15, 0);
4195                 wback = BitIsSet (opcode, 21);
4196 
4197                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4198                 if ((n == 15) || (BitCount (registers) < 1))
4199                     return false;
4200 
4201                 break;
4202 
4203             default:
4204                 return false;
4205         }
4206 
4207         // address = R[n];
4208         int32_t offset = 0;
4209         const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4210         if (!success)
4211             return false;
4212 
4213         EmulateInstruction::Context context;
4214         context.type = EmulateInstruction::eContextRegisterStore;
4215         RegisterInfo base_reg;
4216         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4217 
4218         // for i = 0 to 14
4219         uint32_t lowest_set_bit = 14;
4220         for (uint32_t i = 0; i < 14; ++i)
4221         {
4222             // if registers<i> == '1' then
4223             if (BitIsSet (registers, i))
4224             {
4225                   if (i < lowest_set_bit)
4226                       lowest_set_bit = i;
4227                   // if i == n && wback && i != LowestSetBit(registers) then
4228                   if ((i == n) && wback && (i != lowest_set_bit))
4229                       // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4230                       WriteBits32UnknownToMemory (address + offset);
4231                   else
4232                   {
4233                      // MemA[address,4] = R[i];
4234                       uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4235                       if (!success)
4236                           return false;
4237 
4238                       RegisterInfo data_reg;
4239                       GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4240                       context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4241                       if (!MemAWrite (context, address + offset, data, addr_byte_size))
4242                           return false;
4243                   }
4244 
4245                   // address = address + 4;
4246                   offset += addr_byte_size;
4247             }
4248         }
4249 
4250         // if registers<15> == '1' then // Only possible for encoding A1
4251         //     MemA[address,4] = PCStoreValue();
4252         if (BitIsSet (registers, 15))
4253         {
4254             RegisterInfo pc_reg;
4255             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4256             context.SetRegisterPlusOffset (pc_reg, 8);
4257             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4258             if (!success)
4259                 return false;
4260 
4261             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4262                 return false;
4263         }
4264 
4265         // if wback then R[n] = R[n] + 4*BitCount(registers);
4266         if (wback)
4267         {
4268             offset = addr_byte_size * BitCount (registers);
4269             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4270             context.SetImmediateSigned (offset);
4271             addr_t data = address + offset;
4272             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4273                 return false;
4274         }
4275     }
4276     return true;
4277 }
4278 
4279 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
4280 // from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
4281 // of those locations can optionally be written back to the base register.
4282 bool
4283 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding)
4284 {
4285 #if 0
4286     if ConditionPassed() then
4287         EncodingSpecificOperations();
4288         address = R[n] - 4*BitCount(registers) + 4;
4289 
4290         for i = 0 to 14
4291             if registers<i> == '1' then
4292                 if i == n && wback && i != LowestSetBit(registers) then
4293                     MemA[address,4] = bits(32) UNKNOWN;
4294                 else
4295                     MemA[address,4] = R[i];
4296                 address = address + 4;
4297 
4298         if registers<15> == '1' then
4299             MemA[address,4] = PCStoreValue();
4300 
4301         if wback then R[n] = R[n] - 4*BitCount(registers);
4302 #endif
4303 
4304     bool success = false;
4305 
4306     if (ConditionPassed(opcode))
4307     {
4308         uint32_t n;
4309         uint32_t registers = 0;
4310         bool wback;
4311         const uint32_t addr_byte_size = GetAddressByteSize();
4312 
4313         // EncodingSpecificOperations();
4314         switch (encoding)
4315         {
4316             case eEncodingA1:
4317                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4318                 n = Bits32 (opcode, 19, 16);
4319                 registers = Bits32 (opcode, 15, 0);
4320                 wback = BitIsSet (opcode, 21);
4321 
4322                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4323                 if ((n == 15) || (BitCount (registers) < 1))
4324                     return false;
4325                 break;
4326             default:
4327                 return false;
4328         }
4329 
4330         // address = R[n] - 4*BitCount(registers) + 4;
4331         int32_t offset = 0;
4332         addr_t Rn = ReadCoreReg (n, &success);
4333         if (!success)
4334             return false;
4335 
4336         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4;
4337 
4338         EmulateInstruction::Context context;
4339         context.type = EmulateInstruction::eContextRegisterStore;
4340         RegisterInfo base_reg;
4341         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4342 
4343         // for i = 0 to 14
4344         uint32_t lowest_bit_set = 14;
4345         for (uint32_t i = 0; i < 14; ++i)
4346         {
4347             // if registers<i> == '1' then
4348             if (BitIsSet (registers, i))
4349             {
4350                 if (i < lowest_bit_set)
4351                     lowest_bit_set = i;
4352                 //if i == n && wback && i != LowestSetBit(registers) then
4353                 if ((i == n) && wback && (i != lowest_bit_set))
4354                     // MemA[address,4] = bits(32) UNKNOWN;
4355                     WriteBits32UnknownToMemory (address + offset);
4356                 else
4357                 {
4358                     // MemA[address,4] = R[i];
4359                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4360                     if (!success)
4361                         return false;
4362 
4363                     RegisterInfo data_reg;
4364                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4365                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4366                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4367                         return false;
4368                 }
4369 
4370                 // address = address + 4;
4371                 offset += addr_byte_size;
4372             }
4373         }
4374 
4375         // if registers<15> == '1' then
4376         //    MemA[address,4] = PCStoreValue();
4377         if (BitIsSet (registers, 15))
4378         {
4379             RegisterInfo pc_reg;
4380             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4381             context.SetRegisterPlusOffset (pc_reg, 8);
4382             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4383             if (!success)
4384                 return false;
4385 
4386             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4387                 return false;
4388         }
4389 
4390         // if wback then R[n] = R[n] - 4*BitCount(registers);
4391         if (wback)
4392         {
4393             offset = (addr_byte_size * BitCount (registers)) * -1;
4394             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4395             context.SetImmediateSigned (offset);
4396             addr_t data = Rn + offset;
4397             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4398                 return false;
4399         }
4400     }
4401     return true;
4402 }
4403 
4404 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
4405 // from a base register.  The consecutive memory locations end just below this address, and the address of the first of
4406 // those locations can optionally be written back to the base register.
4407 bool
4408 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding)
4409 {
4410 #if 0
4411     if ConditionPassed() then
4412         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4413         address = R[n] - 4*BitCount(registers);
4414 
4415         for i = 0 to 14
4416             if registers<i> == '1' then
4417                 if i == n && wback && i != LowestSetBit(registers) then
4418                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4419                 else
4420                     MemA[address,4] = R[i];
4421                 address = address + 4;
4422 
4423         if registers<15> == '1' then // Only possible for encoding A1
4424             MemA[address,4] = PCStoreValue();
4425 
4426         if wback then R[n] = R[n] - 4*BitCount(registers);
4427 #endif
4428 
4429 
4430     bool success = false;
4431 
4432     if (ConditionPassed(opcode))
4433     {
4434         uint32_t n;
4435         uint32_t registers = 0;
4436         bool wback;
4437         const uint32_t addr_byte_size = GetAddressByteSize();
4438 
4439         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4440         switch (encoding)
4441         {
4442             case eEncodingT1:
4443                 // if W == '1' && Rn == '1101' then SEE PUSH;
4444                 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
4445                 {
4446                     // See PUSH
4447                 }
4448                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4449                 n = Bits32 (opcode, 19, 16);
4450                 registers = Bits32 (opcode, 15, 0);
4451                 registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
4452                 wback = BitIsSet (opcode, 21);
4453                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4454                 if ((n == 15) || BitCount (registers) < 2)
4455                     return false;
4456                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4457                 if (wback && BitIsSet (registers, n))
4458                     return false;
4459                 break;
4460 
4461             case eEncodingA1:
4462                 // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH;
4463                 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
4464                 {
4465                     // See Push
4466                 }
4467                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4468                 n = Bits32 (opcode, 19, 16);
4469                 registers = Bits32 (opcode, 15, 0);
4470                 wback = BitIsSet (opcode, 21);
4471                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4472                 if ((n == 15) || BitCount (registers) < 1)
4473                     return false;
4474                 break;
4475 
4476             default:
4477                 return false;
4478         }
4479 
4480         // address = R[n] - 4*BitCount(registers);
4481 
4482         int32_t offset = 0;
4483         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4484         if (!success)
4485         return false;
4486 
4487         addr_t address = Rn - (addr_byte_size * BitCount (registers));
4488 
4489         EmulateInstruction::Context context;
4490         context.type = EmulateInstruction::eContextRegisterStore;
4491         RegisterInfo base_reg;
4492         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4493 
4494         // for i = 0 to 14
4495         uint32_t lowest_set_bit = 14;
4496         for (uint32_t i = 0; i < 14; ++i)
4497         {
4498             // if registers<i> == '1' then
4499             if (BitIsSet (registers, i))
4500             {
4501                 if (i < lowest_set_bit)
4502                     lowest_set_bit = i;
4503                 // if i == n && wback && i != LowestSetBit(registers) then
4504                 if ((i == n) && wback && (i != lowest_set_bit))
4505                     // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4506                     WriteBits32UnknownToMemory (address + offset);
4507                 else
4508                 {
4509                     // MemA[address,4] = R[i];
4510                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4511                     if (!success)
4512                         return false;
4513 
4514                     RegisterInfo data_reg;
4515                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4516                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4517                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4518                         return false;
4519                 }
4520 
4521                 // address = address + 4;
4522                 offset += addr_byte_size;
4523             }
4524         }
4525 
4526         // if registers<15> == '1' then // Only possible for encoding A1
4527         //     MemA[address,4] = PCStoreValue();
4528         if (BitIsSet (registers, 15))
4529         {
4530             RegisterInfo pc_reg;
4531             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4532             context.SetRegisterPlusOffset (pc_reg, 8);
4533             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4534             if (!success)
4535                 return false;
4536 
4537             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4538                 return false;
4539         }
4540 
4541         // if wback then R[n] = R[n] - 4*BitCount(registers);
4542         if (wback)
4543         {
4544             offset = (addr_byte_size * BitCount (registers)) * -1;
4545             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4546             context.SetImmediateSigned (offset);
4547             addr_t data = Rn + offset;
4548             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4549                 return false;
4550         }
4551     }
4552     return true;
4553 }
4554 
4555 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
4556 // from a base register.  The consecutive memory locations start just above this address, and the address of the last
4557 // of those locations can optionally be written back to the base register.
4558 bool
4559 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding)
4560 {
4561 #if 0
4562     if ConditionPassed() then
4563         EncodingSpecificOperations();
4564         address = R[n] + 4;
4565 
4566         for i = 0 to 14
4567             if registers<i> == '1' then
4568                 if i == n && wback && i != LowestSetBit(registers) then
4569                     MemA[address,4] = bits(32) UNKNOWN;
4570                 else
4571                     MemA[address,4] = R[i];
4572                 address = address + 4;
4573 
4574         if registers<15> == '1' then
4575             MemA[address,4] = PCStoreValue();
4576 
4577         if wback then R[n] = R[n] + 4*BitCount(registers);
4578 #endif
4579 
4580     bool success = false;
4581 
4582     if (ConditionPassed(opcode))
4583     {
4584         uint32_t n;
4585         uint32_t registers = 0;
4586         bool wback;
4587         const uint32_t addr_byte_size = GetAddressByteSize();
4588 
4589         // EncodingSpecificOperations();
4590         switch (encoding)
4591         {
4592             case eEncodingA1:
4593                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4594                 n = Bits32 (opcode, 19, 16);
4595                 registers = Bits32 (opcode, 15, 0);
4596                 wback = BitIsSet (opcode, 21);
4597 
4598                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4599                 if ((n == 15) && (BitCount (registers) < 1))
4600                     return false;
4601                 break;
4602             default:
4603                 return false;
4604         }
4605         // address = R[n] + 4;
4606 
4607         int32_t offset = 0;
4608         addr_t Rn = ReadCoreReg (n, &success);
4609         if (!success)
4610             return false;
4611 
4612         addr_t address = Rn + addr_byte_size;
4613 
4614         EmulateInstruction::Context context;
4615         context.type = EmulateInstruction::eContextRegisterStore;
4616         RegisterInfo base_reg;
4617         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4618 
4619         uint32_t lowest_set_bit = 14;
4620         // for i = 0 to 14
4621         for (uint32_t i = 0; i < 14; ++i)
4622         {
4623             // if registers<i> == '1' then
4624             if (BitIsSet (registers, i))
4625             {
4626                 if (i < lowest_set_bit)
4627                     lowest_set_bit = i;
4628                 // if i == n && wback && i != LowestSetBit(registers) then
4629                 if ((i == n) && wback && (i != lowest_set_bit))
4630                     // MemA[address,4] = bits(32) UNKNOWN;
4631                     WriteBits32UnknownToMemory (address + offset);
4632                 // else
4633                 else
4634                 {
4635                     // MemA[address,4] = R[i];
4636                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4637                     if (!success)
4638                         return false;
4639 
4640                     RegisterInfo data_reg;
4641                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4642                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size);
4643                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4644                         return false;
4645                 }
4646 
4647                 // address = address + 4;
4648                 offset += addr_byte_size;
4649             }
4650         }
4651 
4652         // if registers<15> == '1' then
4653             // MemA[address,4] = PCStoreValue();
4654         if (BitIsSet (registers, 15))
4655         {
4656             RegisterInfo pc_reg;
4657             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4658             context.SetRegisterPlusOffset (pc_reg, 8);
4659             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4660             if (!success)
4661             return false;
4662 
4663             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4664                 return false;
4665         }
4666 
4667         // if wback then R[n] = R[n] + 4*BitCount(registers);
4668         if (wback)
4669         {
4670             offset = addr_byte_size * BitCount (registers);
4671             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4672             context.SetImmediateSigned (offset);
4673             addr_t data = Rn + offset;
4674             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4675                 return false;
4676         }
4677     }
4678     return true;
4679 }
4680 
4681 // STR (store immediate) calculates an address from a base register value and an immediate offset, and stores a word
4682 // from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
4683 bool
4684 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding)
4685 {
4686 #if 0
4687     if ConditionPassed() then
4688         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4689         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4690         address = if index then offset_addr else R[n];
4691         if UnalignedSupport() || address<1:0> == '00' then
4692             MemU[address,4] = R[t];
4693         else // Can only occur before ARMv7
4694             MemU[address,4] = bits(32) UNKNOWN;
4695         if wback then R[n] = offset_addr;
4696 #endif
4697 
4698     bool success = false;
4699 
4700     if (ConditionPassed(opcode))
4701     {
4702         const uint32_t addr_byte_size = GetAddressByteSize();
4703 
4704         uint32_t t;
4705         uint32_t n;
4706         uint32_t imm32;
4707         bool index;
4708         bool add;
4709         bool wback;
4710         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4711         switch (encoding)
4712         {
4713             case eEncodingT1:
4714                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
4715                 t = Bits32 (opcode, 2, 0);
4716                 n = Bits32 (opcode, 5, 3);
4717                 imm32 = Bits32 (opcode, 10, 6) << 2;
4718 
4719                 // index = TRUE; add = TRUE; wback = FALSE;
4720                 index = true;
4721                 add = false;
4722                 wback = false;
4723                 break;
4724 
4725             case eEncodingT2:
4726                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4727                 t = Bits32 (opcode, 10, 8);
4728                 n = 13;
4729                 imm32 = Bits32 (opcode, 7, 0) << 2;
4730 
4731                 // index = TRUE; add = TRUE; wback = FALSE;
4732                 index = true;
4733                 add = true;
4734                 wback = false;
4735                 break;
4736 
4737             case eEncodingT3:
4738                 // if Rn == '1111' then UNDEFINED;
4739                 if (Bits32 (opcode, 19, 16) == 15)
4740                     return false;
4741 
4742                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4743                 t = Bits32 (opcode, 15, 12);
4744                 n = Bits32 (opcode, 19, 16);
4745                 imm32 = Bits32 (opcode, 11, 0);
4746 
4747                 // index = TRUE; add = TRUE; wback = FALSE;
4748                 index = true;
4749                 add = true;
4750                 wback = false;
4751 
4752                 // if t == 15 then UNPREDICTABLE;
4753                 if (t == 15)
4754                     return false;
4755                 break;
4756 
4757             case eEncodingT4:
4758                 // if P == '1' && U == '1' && W == '0' then SEE STRT;
4759                 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH;
4760                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4761                 if ((Bits32 (opcode, 19, 16) == 15)
4762                       || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
4763                     return false;
4764 
4765                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4766                 t = Bits32 (opcode, 15, 12);
4767                 n = Bits32 (opcode, 19, 16);
4768                 imm32 = Bits32 (opcode, 7, 0);
4769 
4770                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4771                 index = BitIsSet (opcode, 10);
4772                 add = BitIsSet (opcode, 9);
4773                 wback = BitIsSet (opcode, 8);
4774 
4775                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
4776                 if ((t == 15) || (wback && (n == t)))
4777                     return false;
4778                 break;
4779 
4780             default:
4781                 return false;
4782         }
4783 
4784         addr_t offset_addr;
4785         addr_t address;
4786 
4787         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4788         uint32_t base_address = ReadCoreReg (n, &success);
4789         if (!success)
4790             return false;
4791 
4792         if (add)
4793             offset_addr = base_address + imm32;
4794         else
4795             offset_addr = base_address - imm32;
4796 
4797         // address = if index then offset_addr else R[n];
4798         if (index)
4799             address = offset_addr;
4800         else
4801             address = base_address;
4802 
4803         EmulateInstruction::Context context;
4804         context.type = eContextRegisterStore;
4805         RegisterInfo base_reg;
4806         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4807 
4808         // if UnalignedSupport() || address<1:0> == '00' then
4809         if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
4810         {
4811             // MemU[address,4] = R[t];
4812             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4813             if (!success)
4814                 return false;
4815 
4816             RegisterInfo data_reg;
4817             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4818             int32_t offset = address - base_address;
4819             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4820             if (!MemUWrite (context, address, data, addr_byte_size))
4821                 return false;
4822         }
4823         else
4824         {
4825             // MemU[address,4] = bits(32) UNKNOWN;
4826             WriteBits32UnknownToMemory (address);
4827         }
4828 
4829         // if wback then R[n] = offset_addr;
4830         if (wback)
4831         {
4832             context.type = eContextRegisterLoad;
4833             context.SetAddress (offset_addr);
4834             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4835                 return false;
4836         }
4837     }
4838     return true;
4839 }
4840 
4841 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a
4842 // word from a register to memory.   The offset register value can optionally be shifted.
4843 bool
4844 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding)
4845 {
4846 #if 0
4847     if ConditionPassed() then
4848         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4849         offset = Shift(R[m], shift_t, shift_n, APSR.C);
4850         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4851         address = if index then offset_addr else R[n];
4852         if t == 15 then // Only possible for encoding A1
4853             data = PCStoreValue();
4854         else
4855             data = R[t];
4856         if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4857             MemU[address,4] = data;
4858         else // Can only occur before ARMv7
4859             MemU[address,4] = bits(32) UNKNOWN;
4860         if wback then R[n] = offset_addr;
4861 #endif
4862 
4863     bool success = false;
4864 
4865     if (ConditionPassed(opcode))
4866     {
4867         const uint32_t addr_byte_size = GetAddressByteSize();
4868 
4869         uint32_t t;
4870         uint32_t n;
4871         uint32_t m;
4872         ARM_ShifterType shift_t;
4873         uint32_t shift_n;
4874         bool index;
4875         bool add;
4876         bool wback;
4877 
4878         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4879         switch (encoding)
4880         {
4881             case eEncodingT1:
4882                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4883                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4884                 t = Bits32 (opcode, 2, 0);
4885                 n = Bits32 (opcode, 5, 3);
4886                 m = Bits32 (opcode, 8, 6);
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, 0);
4894                 shift_t = SRType_LSL;
4895                 shift_n = 0;
4896                 break;
4897 
4898             case eEncodingT2:
4899                 // if Rn == '1111' then UNDEFINED;
4900                 if (Bits32 (opcode, 19, 16) == 15)
4901                     return false;
4902 
4903                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4904                 t = Bits32 (opcode, 15, 12);
4905                 n = Bits32 (opcode, 19, 16);
4906                 m = Bits32 (opcode, 3, 0);
4907 
4908                 // index = TRUE; add = TRUE; wback = FALSE;
4909                 index = true;
4910                 add = true;
4911                 wback = false;
4912 
4913                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4914                 shift_t = SRType_LSL;
4915                 shift_n = Bits32 (opcode, 5, 4);
4916 
4917                 // if t == 15 || BadReg(m) then UNPREDICTABLE;
4918                 if ((t == 15) || (BadReg (m)))
4919                     return false;
4920                 break;
4921 
4922             case eEncodingA1:
4923             {
4924                 // if P == '0' && W == '1' then SEE STRT;
4925                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4926                 t = Bits32 (opcode, 15, 12);
4927                 n = Bits32 (opcode, 19, 16);
4928                 m = Bits32 (opcode, 3, 0);
4929 
4930                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
4931                 index = BitIsSet (opcode, 24);
4932                 add = BitIsSet (opcode, 23);
4933                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
4934 
4935                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
4936                 uint32_t typ = Bits32 (opcode, 6, 5);
4937                 uint32_t imm5 = Bits32 (opcode, 11, 7);
4938                 shift_n = DecodeImmShift(typ, imm5, shift_t);
4939 
4940                 // if m == 15 then UNPREDICTABLE;
4941                 if (m == 15)
4942                     return false;
4943 
4944                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
4945                 if (wback && ((n == 15) || (n == t)))
4946                     return false;
4947 
4948                 break;
4949             }
4950             default:
4951                 return false;
4952         }
4953 
4954         addr_t offset_addr;
4955         addr_t address;
4956         int32_t offset = 0;
4957 
4958         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4959         if (!success)
4960             return false;
4961 
4962         uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
4963         if (!success)
4964             return false;
4965 
4966         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4967         offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success);
4968         if (!success)
4969             return false;
4970 
4971         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4972         if (add)
4973             offset_addr = base_address + offset;
4974         else
4975             offset_addr = base_address - offset;
4976 
4977         // address = if index then offset_addr else R[n];
4978         if (index)
4979             address = offset_addr;
4980         else
4981             address = base_address;
4982 
4983         uint32_t data;
4984         // if t == 15 then // Only possible for encoding A1
4985         if (t == 15)
4986             // data = PCStoreValue();
4987             data = ReadCoreReg (PC_REG, &success);
4988         else
4989             // data = R[t];
4990             data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4991 
4992         if (!success)
4993             return false;
4994 
4995         EmulateInstruction::Context context;
4996         context.type = eContextRegisterStore;
4997 
4998         // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4999         if (UnalignedSupport ()
5000             || (BitIsClear (address, 1) && BitIsClear (address, 0))
5001             || CurrentInstrSet() == eModeARM)
5002         {
5003             // MemU[address,4] = data;
5004 
5005             RegisterInfo base_reg;
5006             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 +  n, base_reg);
5007 
5008             RegisterInfo data_reg;
5009             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5010 
5011             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
5012             if (!MemUWrite (context, address, data, addr_byte_size))
5013                 return false;
5014 
5015         }
5016         else
5017             // MemU[address,4] = bits(32) UNKNOWN;
5018             WriteBits32UnknownToMemory (address);
5019 
5020         // if wback then R[n] = offset_addr;
5021         if (wback)
5022         {
5023             context.type = eContextRegisterLoad;
5024             context.SetAddress (offset_addr);
5025             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5026                 return false;
5027         }
5028 
5029     }
5030     return true;
5031 }
5032 
5033 bool
5034 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding)
5035 {
5036 #if 0
5037     if ConditionPassed() then
5038         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5039         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5040         address = if index then offset_addr else R[n];
5041         MemU[address,1] = R[t]<7:0>;
5042         if wback then R[n] = offset_addr;
5043 #endif
5044 
5045 
5046     bool success = false;
5047 
5048     if (ConditionPassed(opcode))
5049     {
5050         uint32_t t;
5051         uint32_t n;
5052         uint32_t imm32;
5053         bool index;
5054         bool add;
5055         bool wback;
5056         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5057         switch (encoding)
5058         {
5059             case eEncodingT1:
5060                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
5061                 t = Bits32 (opcode, 2, 0);
5062                 n = Bits32 (opcode, 5, 3);
5063                 imm32 = Bits32 (opcode, 10, 6);
5064 
5065                 // index = TRUE; add = TRUE; wback = FALSE;
5066                 index = true;
5067                 add = true;
5068                 wback = false;
5069                 break;
5070 
5071             case eEncodingT2:
5072                 // if Rn == '1111' then UNDEFINED;
5073                 if (Bits32 (opcode, 19, 16) == 15)
5074                     return false;
5075 
5076                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5077                 t = Bits32 (opcode, 15, 12);
5078                 n = Bits32 (opcode, 19, 16);
5079                 imm32 = Bits32 (opcode, 11, 0);
5080 
5081                 // index = TRUE; add = TRUE; wback = FALSE;
5082                 index = true;
5083                 add = true;
5084                 wback = false;
5085 
5086                 // if BadReg(t) then UNPREDICTABLE;
5087                 if (BadReg (t))
5088                     return false;
5089                 break;
5090 
5091             case eEncodingT3:
5092                 // if P == '1' && U == '1' && W == '0' then SEE STRBT;
5093                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5094                 if (Bits32 (opcode, 19, 16) == 15)
5095                     return false;
5096 
5097                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5098                 t = Bits32 (opcode, 15, 12);
5099                 n = Bits32 (opcode, 19, 16);
5100                 imm32 = Bits32 (opcode, 7, 0);
5101 
5102                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5103                 index = BitIsSet (opcode, 10);
5104                 add = BitIsSet (opcode, 9);
5105                 wback = BitIsSet (opcode, 8);
5106 
5107                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
5108                 if ((BadReg (t)) || (wback && (n == t)))
5109                     return false;
5110                 break;
5111 
5112             default:
5113                 return false;
5114         }
5115 
5116         addr_t offset_addr;
5117         addr_t address;
5118         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5119         if (!success)
5120             return false;
5121 
5122         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5123         if (add)
5124             offset_addr = base_address + imm32;
5125         else
5126             offset_addr = base_address - imm32;
5127 
5128         // address = if index then offset_addr else R[n];
5129         if (index)
5130             address = offset_addr;
5131         else
5132             address = base_address;
5133 
5134         // MemU[address,1] = R[t]<7:0>
5135         RegisterInfo base_reg;
5136         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5137 
5138         RegisterInfo data_reg;
5139         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5140 
5141         EmulateInstruction::Context context;
5142         context.type = eContextRegisterStore;
5143         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
5144 
5145         uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5146         if (!success)
5147             return false;
5148 
5149         data = Bits32 (data, 7, 0);
5150 
5151         if (!MemUWrite (context, address, data, 1))
5152             return false;
5153 
5154         // if wback then R[n] = offset_addr;
5155         if (wback)
5156         {
5157             context.type = eContextRegisterLoad;
5158             context.SetAddress (offset_addr);
5159             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5160                 return false;
5161         }
5162 
5163     }
5164 
5165     return true;
5166 }
5167 
5168 // STRH (register) calculates an address from a base register value and an offset register value, and stores a
5169 // halfword from a register to memory.  The offset register value can be shifted left by 0, 1, 2, or 3 bits.
5170 bool
5171 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding)
5172 {
5173 #if 0
5174     if ConditionPassed() then
5175         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5176         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5177         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5178         address = if index then offset_addr else R[n];
5179         if UnalignedSupport() || address<0> == '0' then
5180             MemU[address,2] = R[t]<15:0>;
5181         else // Can only occur before ARMv7
5182             MemU[address,2] = bits(16) UNKNOWN;
5183         if wback then R[n] = offset_addr;
5184 #endif
5185 
5186     bool success = false;
5187 
5188     if (ConditionPassed(opcode))
5189     {
5190         uint32_t t;
5191         uint32_t n;
5192         uint32_t m;
5193         bool index;
5194         bool add;
5195         bool wback;
5196         ARM_ShifterType shift_t;
5197         uint32_t shift_n;
5198 
5199         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5200         switch (encoding)
5201         {
5202             case eEncodingT1:
5203                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5204                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5205                 t = Bits32 (opcode, 2, 0);
5206                 n = Bits32 (opcode, 5, 3);
5207                 m = Bits32 (opcode, 8, 6);
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, 0);
5215                 shift_t = SRType_LSL;
5216                 shift_n = 0;
5217 
5218                 break;
5219 
5220             case eEncodingT2:
5221                 // if Rn == '1111' then UNDEFINED;
5222                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5223                 t = Bits32 (opcode, 15, 12);
5224                 n = Bits32 (opcode, 19, 16);
5225                 m = Bits32 (opcode, 3, 0);
5226                 if (n == 15)
5227                     return false;
5228 
5229                 // index = TRUE; add = TRUE; wback = FALSE;
5230                 index = true;
5231                 add = true;
5232                 wback = false;
5233 
5234                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5235                 shift_t = SRType_LSL;
5236                 shift_n = Bits32 (opcode, 5, 4);
5237 
5238                 // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5239                 if (BadReg (t) || BadReg (m))
5240                     return false;
5241 
5242                 break;
5243 
5244             case eEncodingA1:
5245                 // if P == '0' && W == '1' then SEE STRHT;
5246                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5247                 t = Bits32 (opcode, 15, 12);
5248                 n = Bits32 (opcode, 19, 16);
5249                 m = Bits32 (opcode, 3, 0);
5250 
5251                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5252                 index = BitIsSet (opcode, 24);
5253                 add = BitIsSet (opcode, 23);
5254                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5255 
5256                 // (shift_t, shift_n) = (SRType_LSL, 0);
5257                 shift_t = SRType_LSL;
5258                 shift_n = 0;
5259 
5260                 // if t == 15 || m == 15 then UNPREDICTABLE;
5261                 if ((t == 15) || (m == 15))
5262                     return false;
5263 
5264                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5265                 if (wback && ((n == 15) || (n == t)))
5266                     return false;
5267 
5268                 break;
5269 
5270             default:
5271                 return false;
5272         }
5273 
5274         uint32_t Rm = ReadCoreReg (m, &success);
5275         if (!success)
5276             return false;
5277 
5278         uint32_t Rn = ReadCoreReg (n, &success);
5279         if (!success)
5280             return false;
5281 
5282         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5283         uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
5284         if (!success)
5285             return false;
5286 
5287         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5288         addr_t offset_addr;
5289         if (add)
5290             offset_addr = Rn + offset;
5291         else
5292             offset_addr = Rn - offset;
5293 
5294         // address = if index then offset_addr else R[n];
5295         addr_t address;
5296         if (index)
5297             address = offset_addr;
5298         else
5299             address = Rn;
5300 
5301         EmulateInstruction::Context context;
5302         context.type = eContextRegisterStore;
5303         RegisterInfo base_reg;
5304         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5305         RegisterInfo offset_reg;
5306         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5307 
5308         // if UnalignedSupport() || address<0> == '0' then
5309         if (UnalignedSupport() || BitIsClear (address, 0))
5310         {
5311             // MemU[address,2] = R[t]<15:0>;
5312             uint32_t Rt = ReadCoreReg (t, &success);
5313             if (!success)
5314                 return false;
5315 
5316             EmulateInstruction::Context context;
5317             context.type = eContextRegisterStore;
5318             RegisterInfo base_reg;
5319             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5320             RegisterInfo offset_reg;
5321             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5322             RegisterInfo data_reg;
5323             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5324             context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
5325 
5326             if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2))
5327                 return false;
5328         }
5329         else // Can only occur before ARMv7
5330         {
5331             // MemU[address,2] = bits(16) UNKNOWN;
5332         }
5333 
5334         // if wback then R[n] = offset_addr;
5335         if (wback)
5336         {
5337             context.type = eContextAdjustBaseRegister;
5338             context.SetAddress (offset_addr);
5339             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5340                 return false;
5341         }
5342     }
5343 
5344     return true;
5345 }
5346 
5347 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value,
5348 // and writes the result to the destination register.  It can optionally update the condition flags
5349 // based on the result.
5350 bool
5351 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding)
5352 {
5353 #if 0
5354     // ARM pseudo code...
5355     if ConditionPassed() then
5356         EncodingSpecificOperations();
5357         (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5358         if d == 15 then         // Can only occur for ARM encoding
5359             ALUWritePC(result); // setflags is always FALSE here
5360         else
5361             R[d] = result;
5362             if setflags then
5363                 APSR.N = result<31>;
5364                 APSR.Z = IsZeroBit(result);
5365                 APSR.C = carry;
5366                 APSR.V = overflow;
5367 #endif
5368 
5369     bool success = false;
5370 
5371     if (ConditionPassed(opcode))
5372     {
5373         uint32_t Rd, Rn;
5374         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
5375         bool setflags;
5376         switch (encoding)
5377         {
5378         case eEncodingT1:
5379             Rd = Bits32(opcode, 11, 8);
5380             Rn = Bits32(opcode, 19, 16);
5381             setflags = BitIsSet(opcode, 20);
5382             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5383             if (BadReg(Rd) || BadReg(Rn))
5384                 return false;
5385             break;
5386         case eEncodingA1:
5387             Rd = Bits32(opcode, 15, 12);
5388             Rn = Bits32(opcode, 19, 16);
5389             setflags = BitIsSet(opcode, 20);
5390             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5391 
5392             if (Rd == 15 && setflags)
5393                 return EmulateSUBSPcLrEtc (opcode, encoding);
5394             break;
5395         default:
5396             return false;
5397         }
5398 
5399         // Read the first operand.
5400         int32_t val1 = ReadCoreReg(Rn, &success);
5401         if (!success)
5402             return false;
5403 
5404         AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5405 
5406         EmulateInstruction::Context context;
5407         context.type = EmulateInstruction::eContextImmediate;
5408         context.SetNoArgs ();
5409 
5410         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5411             return false;
5412     }
5413     return true;
5414 }
5415 
5416 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted
5417 // register value, and writes the result to the destination register.  It can optionally update the
5418 // condition flags based on the result.
5419 bool
5420 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding)
5421 {
5422 #if 0
5423     // ARM pseudo code...
5424     if ConditionPassed() then
5425         EncodingSpecificOperations();
5426         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5427         (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5428         if d == 15 then         // Can only occur for ARM encoding
5429             ALUWritePC(result); // setflags is always FALSE here
5430         else
5431             R[d] = result;
5432             if setflags then
5433                 APSR.N = result<31>;
5434                 APSR.Z = IsZeroBit(result);
5435                 APSR.C = carry;
5436                 APSR.V = overflow;
5437 #endif
5438 
5439     bool success = false;
5440 
5441     if (ConditionPassed(opcode))
5442     {
5443         uint32_t Rd, Rn, Rm;
5444         ARM_ShifterType shift_t;
5445         uint32_t shift_n; // the shift applied to the value read from Rm
5446         bool setflags;
5447         switch (encoding)
5448         {
5449         case eEncodingT1:
5450             Rd = Rn = Bits32(opcode, 2, 0);
5451             Rm = Bits32(opcode, 5, 3);
5452             setflags = !InITBlock();
5453             shift_t = SRType_LSL;
5454             shift_n = 0;
5455             break;
5456         case eEncodingT2:
5457             Rd = Bits32(opcode, 11, 8);
5458             Rn = Bits32(opcode, 19, 16);
5459             Rm = Bits32(opcode, 3, 0);
5460             setflags = BitIsSet(opcode, 20);
5461             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5462             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5463                 return false;
5464             break;
5465         case eEncodingA1:
5466             Rd = Bits32(opcode, 15, 12);
5467             Rn = Bits32(opcode, 19, 16);
5468             Rm = Bits32(opcode, 3, 0);
5469             setflags = BitIsSet(opcode, 20);
5470             shift_n = DecodeImmShiftARM(opcode, shift_t);
5471 
5472             if (Rd == 15 && setflags)
5473                 return EmulateSUBSPcLrEtc (opcode, encoding);
5474             break;
5475         default:
5476             return false;
5477         }
5478 
5479         // Read the first operand.
5480         int32_t val1 = ReadCoreReg(Rn, &success);
5481         if (!success)
5482             return false;
5483 
5484         // Read the second operand.
5485         int32_t val2 = ReadCoreReg(Rm, &success);
5486         if (!success)
5487             return false;
5488 
5489         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5490         if (!success)
5491             return false;
5492         AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5493 
5494         EmulateInstruction::Context context;
5495         context.type = EmulateInstruction::eContextImmediate;
5496         context.SetNoArgs ();
5497 
5498         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5499             return false;
5500     }
5501     return true;
5502 }
5503 
5504 // This instruction adds an immediate value to the PC value to form a PC-relative address,
5505 // and writes the result to the destination register.
5506 bool
5507 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding)
5508 {
5509 #if 0
5510     // ARM pseudo code...
5511     if ConditionPassed() then
5512         EncodingSpecificOperations();
5513         result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5514         if d == 15 then         // Can only occur for ARM encodings
5515             ALUWritePC(result);
5516         else
5517             R[d] = result;
5518 #endif
5519 
5520     bool success = false;
5521 
5522     if (ConditionPassed(opcode))
5523     {
5524         uint32_t Rd;
5525         uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5526         bool add;
5527         switch (encoding)
5528         {
5529         case eEncodingT1:
5530             Rd = Bits32(opcode, 10, 8);
5531             imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5532             add = true;
5533             break;
5534         case eEncodingT2:
5535         case eEncodingT3:
5536             Rd = Bits32(opcode, 11, 8);
5537             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5538             add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5539             if (BadReg(Rd))
5540                 return false;
5541             break;
5542         case eEncodingA1:
5543         case eEncodingA2:
5544             Rd = Bits32(opcode, 15, 12);
5545             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5546             add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5547             break;
5548         default:
5549             return false;
5550         }
5551 
5552         // Read the PC value.
5553         uint32_t pc = ReadCoreReg(PC_REG, &success);
5554         if (!success)
5555             return false;
5556 
5557         uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5558 
5559         EmulateInstruction::Context context;
5560         context.type = EmulateInstruction::eContextImmediate;
5561         context.SetNoArgs ();
5562 
5563         if (!WriteCoreReg(context, result, Rd))
5564             return false;
5565     }
5566     return true;
5567 }
5568 
5569 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result
5570 // to the destination register.  It can optionally update the condition flags based on the result.
5571 bool
5572 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding)
5573 {
5574 #if 0
5575     // ARM pseudo code...
5576     if ConditionPassed() then
5577         EncodingSpecificOperations();
5578         result = R[n] AND imm32;
5579         if d == 15 then         // Can only occur for ARM encoding
5580             ALUWritePC(result); // setflags is always FALSE here
5581         else
5582             R[d] = result;
5583             if setflags then
5584                 APSR.N = result<31>;
5585                 APSR.Z = IsZeroBit(result);
5586                 APSR.C = carry;
5587                 // APSR.V unchanged
5588 #endif
5589 
5590     bool success = false;
5591 
5592     if (ConditionPassed(opcode))
5593     {
5594         uint32_t Rd, Rn;
5595         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
5596         bool setflags;
5597         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5598         switch (encoding)
5599         {
5600         case eEncodingT1:
5601             Rd = Bits32(opcode, 11, 8);
5602             Rn = Bits32(opcode, 19, 16);
5603             setflags = BitIsSet(opcode, 20);
5604             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5605             // if Rd == '1111' && S == '1' then SEE TST (immediate);
5606             if (Rd == 15 && setflags)
5607                 return EmulateTSTImm(opcode, eEncodingT1);
5608             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
5609                 return false;
5610             break;
5611         case eEncodingA1:
5612             Rd = Bits32(opcode, 15, 12);
5613             Rn = Bits32(opcode, 19, 16);
5614             setflags = BitIsSet(opcode, 20);
5615             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5616 
5617             if (Rd == 15 && setflags)
5618                 return EmulateSUBSPcLrEtc (opcode, encoding);
5619             break;
5620         default:
5621             return false;
5622         }
5623 
5624         // Read the first operand.
5625         uint32_t val1 = ReadCoreReg(Rn, &success);
5626         if (!success)
5627             return false;
5628 
5629         uint32_t result = val1 & imm32;
5630 
5631         EmulateInstruction::Context context;
5632         context.type = EmulateInstruction::eContextImmediate;
5633         context.SetNoArgs ();
5634 
5635         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5636             return false;
5637     }
5638     return true;
5639 }
5640 
5641 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value,
5642 // and writes the result to the destination register.  It can optionally update the condition flags
5643 // based on the result.
5644 bool
5645 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding)
5646 {
5647 #if 0
5648     // ARM pseudo code...
5649     if ConditionPassed() then
5650         EncodingSpecificOperations();
5651         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5652         result = R[n] AND shifted;
5653         if d == 15 then         // Can only occur for ARM encoding
5654             ALUWritePC(result); // setflags is always FALSE here
5655         else
5656             R[d] = result;
5657             if setflags then
5658                 APSR.N = result<31>;
5659                 APSR.Z = IsZeroBit(result);
5660                 APSR.C = carry;
5661                 // APSR.V unchanged
5662 #endif
5663 
5664     bool success = false;
5665 
5666     if (ConditionPassed(opcode))
5667     {
5668         uint32_t Rd, Rn, Rm;
5669         ARM_ShifterType shift_t;
5670         uint32_t shift_n; // the shift applied to the value read from Rm
5671         bool setflags;
5672         uint32_t carry;
5673         switch (encoding)
5674         {
5675         case eEncodingT1:
5676             Rd = Rn = Bits32(opcode, 2, 0);
5677             Rm = Bits32(opcode, 5, 3);
5678             setflags = !InITBlock();
5679             shift_t = SRType_LSL;
5680             shift_n = 0;
5681             break;
5682         case eEncodingT2:
5683             Rd = Bits32(opcode, 11, 8);
5684             Rn = Bits32(opcode, 19, 16);
5685             Rm = Bits32(opcode, 3, 0);
5686             setflags = BitIsSet(opcode, 20);
5687             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5688             // if Rd == '1111' && S == '1' then SEE TST (register);
5689             if (Rd == 15 && setflags)
5690                 return EmulateTSTReg(opcode, eEncodingT2);
5691             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
5692                 return false;
5693             break;
5694         case eEncodingA1:
5695             Rd = Bits32(opcode, 15, 12);
5696             Rn = Bits32(opcode, 19, 16);
5697             Rm = Bits32(opcode, 3, 0);
5698             setflags = BitIsSet(opcode, 20);
5699             shift_n = DecodeImmShiftARM(opcode, shift_t);
5700 
5701             if (Rd == 15 && setflags)
5702                 return EmulateSUBSPcLrEtc (opcode, encoding);
5703             break;
5704         default:
5705             return false;
5706         }
5707 
5708         // Read the first operand.
5709         uint32_t val1 = ReadCoreReg(Rn, &success);
5710         if (!success)
5711             return false;
5712 
5713         // Read the second operand.
5714         uint32_t val2 = ReadCoreReg(Rm, &success);
5715         if (!success)
5716             return false;
5717 
5718         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5719         if (!success)
5720             return false;
5721         uint32_t result = val1 & shifted;
5722 
5723         EmulateInstruction::Context context;
5724         context.type = EmulateInstruction::eContextImmediate;
5725         context.SetNoArgs ();
5726 
5727         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5728             return false;
5729     }
5730     return true;
5731 }
5732 
5733 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an
5734 // immediate value, and writes the result to the destination register.  It can optionally update the
5735 // condition flags based on the result.
5736 bool
5737 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding)
5738 {
5739 #if 0
5740     // ARM pseudo code...
5741     if ConditionPassed() then
5742         EncodingSpecificOperations();
5743         result = R[n] AND NOT(imm32);
5744         if d == 15 then         // Can only occur for ARM encoding
5745             ALUWritePC(result); // setflags is always FALSE here
5746         else
5747             R[d] = result;
5748             if setflags then
5749                 APSR.N = result<31>;
5750                 APSR.Z = IsZeroBit(result);
5751                 APSR.C = carry;
5752                 // APSR.V unchanged
5753 #endif
5754 
5755     bool success = false;
5756 
5757     if (ConditionPassed(opcode))
5758     {
5759         uint32_t Rd, Rn;
5760         uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn
5761         bool setflags;
5762         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5763         switch (encoding)
5764         {
5765         case eEncodingT1:
5766             Rd = Bits32(opcode, 11, 8);
5767             Rn = Bits32(opcode, 19, 16);
5768             setflags = BitIsSet(opcode, 20);
5769             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5770             if (BadReg(Rd) || BadReg(Rn))
5771                 return false;
5772             break;
5773         case eEncodingA1:
5774             Rd = Bits32(opcode, 15, 12);
5775             Rn = Bits32(opcode, 19, 16);
5776             setflags = BitIsSet(opcode, 20);
5777             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5778 
5779             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5780             if (Rd == 15 && setflags)
5781                 return EmulateSUBSPcLrEtc (opcode, encoding);
5782             break;
5783         default:
5784             return false;
5785         }
5786 
5787         // Read the first operand.
5788         uint32_t val1 = ReadCoreReg(Rn, &success);
5789         if (!success)
5790             return false;
5791 
5792         uint32_t result = val1 & ~imm32;
5793 
5794         EmulateInstruction::Context context;
5795         context.type = EmulateInstruction::eContextImmediate;
5796         context.SetNoArgs ();
5797 
5798         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5799             return false;
5800     }
5801     return true;
5802 }
5803 
5804 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an
5805 // optionally-shifted register value, and writes the result to the destination register.
5806 // It can optionally update the condition flags based on the result.
5807 bool
5808 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding)
5809 {
5810 #if 0
5811     // ARM pseudo code...
5812     if ConditionPassed() then
5813         EncodingSpecificOperations();
5814         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5815         result = R[n] AND NOT(shifted);
5816         if d == 15 then         // Can only occur for ARM encoding
5817             ALUWritePC(result); // setflags is always FALSE here
5818         else
5819             R[d] = result;
5820             if setflags then
5821                 APSR.N = result<31>;
5822                 APSR.Z = IsZeroBit(result);
5823                 APSR.C = carry;
5824                 // APSR.V unchanged
5825 #endif
5826 
5827     bool success = false;
5828 
5829     if (ConditionPassed(opcode))
5830     {
5831         uint32_t Rd, Rn, Rm;
5832         ARM_ShifterType shift_t;
5833         uint32_t shift_n; // the shift applied to the value read from Rm
5834         bool setflags;
5835         uint32_t carry;
5836         switch (encoding)
5837         {
5838         case eEncodingT1:
5839             Rd = Rn = Bits32(opcode, 2, 0);
5840             Rm = Bits32(opcode, 5, 3);
5841             setflags = !InITBlock();
5842             shift_t = SRType_LSL;
5843             shift_n = 0;
5844             break;
5845         case eEncodingT2:
5846             Rd = Bits32(opcode, 11, 8);
5847             Rn = Bits32(opcode, 19, 16);
5848             Rm = Bits32(opcode, 3, 0);
5849             setflags = BitIsSet(opcode, 20);
5850             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5851             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5852                 return false;
5853             break;
5854         case eEncodingA1:
5855             Rd = Bits32(opcode, 15, 12);
5856             Rn = Bits32(opcode, 19, 16);
5857             Rm = Bits32(opcode, 3, 0);
5858             setflags = BitIsSet(opcode, 20);
5859             shift_n = DecodeImmShiftARM(opcode, shift_t);
5860 
5861             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5862             if (Rd == 15 && setflags)
5863                 return EmulateSUBSPcLrEtc (opcode, encoding);
5864             break;
5865         default:
5866             return false;
5867         }
5868 
5869         // Read the first operand.
5870         uint32_t val1 = ReadCoreReg(Rn, &success);
5871         if (!success)
5872             return false;
5873 
5874         // Read the second operand.
5875         uint32_t val2 = ReadCoreReg(Rm, &success);
5876         if (!success)
5877             return false;
5878 
5879         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5880         if (!success)
5881             return false;
5882         uint32_t result = val1 & ~shifted;
5883 
5884         EmulateInstruction::Context context;
5885         context.type = EmulateInstruction::eContextImmediate;
5886         context.SetNoArgs ();
5887 
5888         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5889             return false;
5890     }
5891     return true;
5892 }
5893 
5894 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
5895 // from memory, and writes it to a register.  It can use offset, post-indexed, or pre-indexed addressing.
5896 bool
5897 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding)
5898 {
5899 #if 0
5900     if ConditionPassed() then
5901         EncodingSpecificOperations();
5902         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5903         address = if index then offset_addr else R[n];
5904         data = MemU[address,4];
5905         if wback then R[n] = offset_addr;
5906         if t == 15 then
5907             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5908         elsif UnalignedSupport() || address<1:0> = '00' then
5909             R[t] = data;
5910         else // Can only apply before ARMv7
5911             R[t] = ROR(data, 8*UInt(address<1:0>));
5912 #endif
5913 
5914     bool success = false;
5915 
5916     if (ConditionPassed(opcode))
5917     {
5918         const uint32_t addr_byte_size = GetAddressByteSize();
5919 
5920         uint32_t t;
5921         uint32_t n;
5922         uint32_t imm32;
5923         bool index;
5924         bool add;
5925         bool wback;
5926 
5927         switch (encoding)
5928         {
5929             case eEncodingA1:
5930                 // if Rn == '1111' then SEE LDR (literal);
5931                 // if P == '0' && W == '1' then SEE LDRT;
5932                 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP;
5933                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5934                 t = Bits32 (opcode, 15, 12);
5935                 n = Bits32 (opcode, 19, 16);
5936                 imm32 = Bits32 (opcode, 11, 0);
5937 
5938                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5939                 index = BitIsSet (opcode, 24);
5940                 add = BitIsSet (opcode, 23);
5941                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5942 
5943                 // if wback && n == t then UNPREDICTABLE;
5944                 if (wback && (n == t))
5945                     return false;
5946 
5947                 break;
5948 
5949             default:
5950                 return false;
5951         }
5952 
5953         addr_t address;
5954         addr_t offset_addr;
5955         addr_t base_address = ReadCoreReg (n, &success);
5956         if (!success)
5957             return false;
5958 
5959         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5960         if (add)
5961             offset_addr = base_address + imm32;
5962         else
5963             offset_addr = base_address - imm32;
5964 
5965         // address = if index then offset_addr else R[n];
5966         if (index)
5967             address = offset_addr;
5968         else
5969             address = base_address;
5970 
5971         // data = MemU[address,4];
5972 
5973         RegisterInfo base_reg;
5974         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5975 
5976         EmulateInstruction::Context context;
5977         context.type = eContextRegisterLoad;
5978         context.SetRegisterPlusOffset (base_reg, address - base_address);
5979 
5980         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5981         if (!success)
5982             return false;
5983 
5984         // if wback then R[n] = offset_addr;
5985         if (wback)
5986         {
5987             context.type = eContextAdjustBaseRegister;
5988             context.SetAddress (offset_addr);
5989             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5990                 return false;
5991         }
5992 
5993         // if t == 15 then
5994         if (t == 15)
5995         {
5996             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5997             if (BitIsClear (address, 1) && BitIsClear (address, 0))
5998             {
5999                 // LoadWritePC (data);
6000                 context.type = eContextRegisterLoad;
6001                 context.SetRegisterPlusOffset (base_reg, address - base_address);
6002                 LoadWritePC (context, data);
6003             }
6004             else
6005                   return false;
6006         }
6007         // elsif UnalignedSupport() || address<1:0> = '00' then
6008         else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
6009         {
6010             // R[t] = data;
6011             context.type = eContextRegisterLoad;
6012             context.SetRegisterPlusOffset (base_reg, address - base_address);
6013             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6014                 return false;
6015         }
6016         // else // Can only apply before ARMv7
6017         else
6018         {
6019             // R[t] = ROR(data, 8*UInt(address<1:0>));
6020             data = ROR (data, Bits32 (address, 1, 0), &success);
6021             if (!success)
6022                 return false;
6023             context.type = eContextRegisterLoad;
6024             context.SetImmediate (data);
6025             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6026                 return false;
6027         }
6028 
6029     }
6030     return true;
6031 }
6032 
6033 // LDR (register) calculates an address from a base register value and an offset register value, loads a word
6034 // from memory, and writes it to a register.  The offset register value can optionally be shifted.
6035 bool
6036 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding)
6037 {
6038 #if 0
6039     if ConditionPassed() then
6040         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6041         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6042         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6043         address = if index then offset_addr else R[n];
6044         data = MemU[address,4];
6045         if wback then R[n] = offset_addr;
6046         if t == 15 then
6047             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6048         elsif UnalignedSupport() || address<1:0> = '00' then
6049             R[t] = data;
6050         else // Can only apply before ARMv7
6051             if CurrentInstrSet() == InstrSet_ARM then
6052                 R[t] = ROR(data, 8*UInt(address<1:0>));
6053             else
6054                 R[t] = bits(32) UNKNOWN;
6055 #endif
6056 
6057     bool success = false;
6058 
6059     if (ConditionPassed(opcode))
6060     {
6061         const uint32_t addr_byte_size = GetAddressByteSize();
6062 
6063         uint32_t t;
6064         uint32_t n;
6065         uint32_t m;
6066         bool index;
6067         bool add;
6068         bool wback;
6069         ARM_ShifterType shift_t;
6070         uint32_t shift_n;
6071 
6072         switch (encoding)
6073         {
6074             case eEncodingT1:
6075                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6076                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6077                 t = Bits32 (opcode, 2, 0);
6078                 n = Bits32 (opcode, 5, 3);
6079                 m = Bits32 (opcode, 8, 6);
6080 
6081                 // index = TRUE; add = TRUE; wback = FALSE;
6082                 index = true;
6083                 add = true;
6084                 wback = false;
6085 
6086                 // (shift_t, shift_n) = (SRType_LSL, 0);
6087                 shift_t = SRType_LSL;
6088                 shift_n = 0;
6089 
6090                 break;
6091 
6092             case eEncodingT2:
6093                 // if Rn == '1111' then SEE LDR (literal);
6094                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6095                 t = Bits32 (opcode, 15, 12);
6096                 n = Bits32 (opcode, 19, 16);
6097                 m = Bits32 (opcode, 3, 0);
6098 
6099                 // index = TRUE; add = TRUE; wback = FALSE;
6100                 index = true;
6101                 add = true;
6102                 wback = false;
6103 
6104                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6105                 shift_t = SRType_LSL;
6106                 shift_n = Bits32 (opcode, 5, 4);
6107 
6108                 // if BadReg(m) then UNPREDICTABLE;
6109                 if (BadReg (m))
6110                     return false;
6111 
6112                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
6113                 if ((t == 15) && InITBlock() && !LastInITBlock())
6114                     return false;
6115 
6116                 break;
6117 
6118             case eEncodingA1:
6119             {
6120                 // if P == '0' && W == '1' then SEE LDRT;
6121                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6122                 t = Bits32 (opcode, 15, 12);
6123                 n = Bits32 (opcode, 19, 16);
6124                 m = Bits32 (opcode, 3, 0);
6125 
6126                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6127                 index = BitIsSet (opcode, 24);
6128                 add = BitIsSet (opcode, 23);
6129                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6130 
6131                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6132                 uint32_t type = Bits32 (opcode, 6, 5);
6133                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6134                 shift_n = DecodeImmShift (type, imm5, shift_t);
6135 
6136                 // if m == 15 then UNPREDICTABLE;
6137                 if (m == 15)
6138                     return false;
6139 
6140                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6141                 if (wback && ((n == 15) || (n == t)))
6142                     return false;
6143             }
6144                 break;
6145 
6146 
6147             default:
6148                 return false;
6149         }
6150 
6151         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6152         if (!success)
6153             return false;
6154 
6155         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6156         if (!success)
6157             return false;
6158 
6159         addr_t offset_addr;
6160         addr_t address;
6161 
6162         // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an application level alias for the CPSR".
6163         addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success);
6164         if (!success)
6165             return false;
6166 
6167         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6168         if (add)
6169             offset_addr = Rn + offset;
6170         else
6171             offset_addr = Rn - offset;
6172 
6173         // address = if index then offset_addr else R[n];
6174             if (index)
6175                 address = offset_addr;
6176             else
6177                 address = Rn;
6178 
6179         // data = MemU[address,4];
6180         RegisterInfo base_reg;
6181         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6182 
6183         EmulateInstruction::Context context;
6184         context.type = eContextRegisterLoad;
6185         context.SetRegisterPlusOffset (base_reg, address - Rn);
6186 
6187         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
6188         if (!success)
6189             return false;
6190 
6191         // if wback then R[n] = offset_addr;
6192         if (wback)
6193         {
6194             context.type = eContextAdjustBaseRegister;
6195             context.SetAddress (offset_addr);
6196             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6197                 return false;
6198         }
6199 
6200         // if t == 15 then
6201         if (t == 15)
6202         {
6203             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6204             if (BitIsClear (address, 1) && BitIsClear (address, 0))
6205             {
6206                 context.type = eContextRegisterLoad;
6207                 context.SetRegisterPlusOffset (base_reg, address - Rn);
6208                 LoadWritePC (context, data);
6209             }
6210             else
6211                 return false;
6212         }
6213         // elsif UnalignedSupport() || address<1:0> = '00' then
6214         else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
6215         {
6216             // R[t] = data;
6217             context.type = eContextRegisterLoad;
6218             context.SetRegisterPlusOffset (base_reg, address - Rn);
6219             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6220                 return false;
6221         }
6222         else // Can only apply before ARMv7
6223         {
6224             // if CurrentInstrSet() == InstrSet_ARM then
6225             if (CurrentInstrSet () == eModeARM)
6226             {
6227                 // R[t] = ROR(data, 8*UInt(address<1:0>));
6228                 data = ROR (data, Bits32 (address, 1, 0), &success);
6229                 if (!success)
6230                     return false;
6231                 context.type = eContextRegisterLoad;
6232                 context.SetImmediate (data);
6233                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6234                     return false;
6235             }
6236             else
6237             {
6238                 // R[t] = bits(32) UNKNOWN;
6239                 WriteBits32Unknown (t);
6240             }
6241         }
6242     }
6243     return true;
6244 }
6245 
6246 // LDRB (immediate, Thumb)
6247 bool
6248 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6249 {
6250 #if 0
6251     if ConditionPassed() then
6252         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6253         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6254         address = if index then offset_addr else R[n];
6255         R[t] = ZeroExtend(MemU[address,1], 32);
6256         if wback then R[n] = offset_addr;
6257 #endif
6258 
6259     bool success = false;
6260 
6261     if (ConditionPassed(opcode))
6262     {
6263         uint32_t t;
6264         uint32_t n;
6265         uint32_t imm32;
6266         bool index;
6267         bool add;
6268         bool wback;
6269 
6270         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6271         switch (encoding)
6272         {
6273             case eEncodingT1:
6274                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6275                 t = Bits32 (opcode, 2, 0);
6276                 n = Bits32 (opcode, 5, 3);
6277                 imm32 = Bits32 (opcode, 10, 6);
6278 
6279                 // index = TRUE; add = TRUE; wback = FALSE;
6280                 index = true;
6281                 add = true;
6282                 wback= false;
6283 
6284                 break;
6285 
6286             case eEncodingT2:
6287                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6288                 t = Bits32 (opcode, 15, 12);
6289                 n = Bits32 (opcode, 19, 16);
6290                 imm32 = Bits32 (opcode, 11, 0);
6291 
6292                 // index = TRUE; add = TRUE; wback = FALSE;
6293                 index = true;
6294                 add = true;
6295                 wback = false;
6296 
6297                 // if Rt == '1111' then SEE PLD;
6298                 if (t == 15)
6299                     return false; // PLD is not implemented yet
6300 
6301                 // if Rn == '1111' then SEE LDRB (literal);
6302                 if (n == 15)
6303                     return EmulateLDRBLiteral(opcode, eEncodingT1);
6304 
6305                 // if t == 13 then UNPREDICTABLE;
6306                 if (t == 13)
6307                     return false;
6308 
6309                 break;
6310 
6311             case eEncodingT3:
6312                 // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6313                 // if P == '0' && W == '0' then UNDEFINED;
6314                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6315                     return false;
6316 
6317                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6318                 t = Bits32 (opcode, 15, 12);
6319                 n = Bits32 (opcode, 19, 16);
6320                 imm32 = Bits32 (opcode, 7, 0);
6321 
6322                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6323                 index = BitIsSet (opcode, 10);
6324                 add = BitIsSet (opcode, 9);
6325                 wback = BitIsSet (opcode, 8);
6326 
6327                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6328                 if (t == 15)
6329                     return false; // PLD is not implemented yet
6330 
6331                 // if Rn == '1111' then SEE LDRB (literal);
6332                 if (n == 15)
6333                     return EmulateLDRBLiteral(opcode, eEncodingT1);
6334 
6335                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6336                 if (BadReg (t) || (wback && (n == t)))
6337                     return false;
6338 
6339                 break;
6340 
6341             default:
6342                 return false;
6343         }
6344 
6345         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6346         if (!success)
6347             return false;
6348 
6349         addr_t address;
6350         addr_t offset_addr;
6351 
6352         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6353         if (add)
6354             offset_addr = Rn + imm32;
6355         else
6356             offset_addr = Rn - imm32;
6357 
6358         // address = if index then offset_addr else R[n];
6359         if (index)
6360             address = offset_addr;
6361         else
6362             address = Rn;
6363 
6364         // R[t] = ZeroExtend(MemU[address,1], 32);
6365         RegisterInfo base_reg;
6366         RegisterInfo data_reg;
6367         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6368         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6369 
6370         EmulateInstruction::Context context;
6371         context.type = eContextRegisterLoad;
6372         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
6373 
6374         uint64_t data = MemURead (context, address, 1, 0, &success);
6375         if (!success)
6376             return false;
6377 
6378         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6379             return false;
6380 
6381         // if wback then R[n] = offset_addr;
6382         if (wback)
6383         {
6384             context.type = eContextAdjustBaseRegister;
6385             context.SetAddress (offset_addr);
6386             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6387                 return false;
6388         }
6389     }
6390     return true;
6391 }
6392 
6393 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6394 // zero-extends it to form a 32-bit word and writes it to a register.
6395 bool
6396 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6397 {
6398 #if 0
6399     if ConditionPassed() then
6400         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6401         base = Align(PC,4);
6402         address = if add then (base + imm32) else (base - imm32);
6403         R[t] = ZeroExtend(MemU[address,1], 32);
6404 #endif
6405 
6406     bool success = false;
6407 
6408     if (ConditionPassed(opcode))
6409     {
6410         uint32_t t;
6411         uint32_t imm32;
6412         bool add;
6413         switch (encoding)
6414         {
6415             case eEncodingT1:
6416                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6417                 t = Bits32 (opcode, 15, 12);
6418                 imm32 = Bits32 (opcode, 11, 0);
6419                 add = BitIsSet (opcode, 23);
6420 
6421                 // if Rt == '1111' then SEE PLD;
6422                 if (t == 15)
6423                     return false; // PLD is not implemented yet
6424 
6425                 // if t == 13 then UNPREDICTABLE;
6426                 if (t == 13)
6427                     return false;
6428 
6429                 break;
6430 
6431             case eEncodingA1:
6432                 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6433                 t = Bits32 (opcode, 15, 12);
6434                 imm32 = Bits32 (opcode, 11, 0);
6435                 add = BitIsSet (opcode, 23);
6436 
6437                 // if t == 15 then UNPREDICTABLE;
6438                 if (t == 15)
6439                     return false;
6440                 break;
6441 
6442             default:
6443                 return false;
6444         }
6445 
6446         // base = Align(PC,4);
6447         uint32_t pc_val = ReadCoreReg (PC_REG, &success);
6448         if (!success)
6449             return false;
6450 
6451         uint32_t base = AlignPC (pc_val);
6452 
6453         addr_t address;
6454         // address = if add then (base + imm32) else (base - imm32);
6455         if (add)
6456             address = base + imm32;
6457         else
6458             address = base - imm32;
6459 
6460         // R[t] = ZeroExtend(MemU[address,1], 32);
6461         EmulateInstruction::Context context;
6462         context.type = eContextRelativeBranchImmediate;
6463         context.SetImmediate (address - base);
6464 
6465         uint64_t data = MemURead (context, address, 1, 0, &success);
6466         if (!success)
6467             return false;
6468 
6469         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6470             return false;
6471     }
6472     return true;
6473 }
6474 
6475 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from
6476 // memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6477 // optionally be shifted.
6478 bool
6479 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding)
6480 {
6481 #if 0
6482     if ConditionPassed() then
6483         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6484         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6485         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6486         address = if index then offset_addr else R[n];
6487         R[t] = ZeroExtend(MemU[address,1],32);
6488         if wback then R[n] = offset_addr;
6489 #endif
6490 
6491     bool success = false;
6492 
6493     if (ConditionPassed(opcode))
6494     {
6495         uint32_t t;
6496         uint32_t n;
6497         uint32_t m;
6498         bool index;
6499         bool add;
6500         bool wback;
6501         ARM_ShifterType shift_t;
6502         uint32_t shift_n;
6503 
6504         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6505         switch (encoding)
6506         {
6507             case eEncodingT1:
6508                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6509                 t = Bits32 (opcode, 2, 0);
6510                 n = Bits32 (opcode, 5, 3);
6511                 m = Bits32 (opcode, 8, 6);
6512 
6513                 // index = TRUE; add = TRUE; wback = FALSE;
6514                 index = true;
6515                 add = true;
6516                 wback = false;
6517 
6518                 // (shift_t, shift_n) = (SRType_LSL, 0);
6519                 shift_t = SRType_LSL;
6520                 shift_n = 0;
6521                 break;
6522 
6523             case eEncodingT2:
6524                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6525                 t = Bits32 (opcode, 15, 12);
6526                 n = Bits32 (opcode, 19, 16);
6527                 m = Bits32 (opcode, 3, 0);
6528 
6529                 // index = TRUE; add = TRUE; wback = FALSE;
6530                 index = true;
6531                 add = true;
6532                 wback = false;
6533 
6534                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6535                 shift_t = SRType_LSL;
6536                 shift_n = Bits32 (opcode, 5, 4);
6537 
6538                 // if Rt == '1111' then SEE PLD;
6539                 if (t == 15)
6540                     return false; // PLD is not implemented yet
6541 
6542                 // if Rn == '1111' then SEE LDRB (literal);
6543                 if (n == 15)
6544                     return EmulateLDRBLiteral(opcode, eEncodingT1);
6545 
6546                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6547                 if ((t == 13) || BadReg (m))
6548                     return false;
6549                 break;
6550 
6551             case eEncodingA1:
6552             {
6553                 // if P == '0' && W == '1' then SEE LDRBT;
6554                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6555                 t = Bits32 (opcode, 15, 12);
6556                 n = Bits32 (opcode, 19, 16);
6557                 m = Bits32 (opcode, 3, 0);
6558 
6559                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6560                 index = BitIsSet (opcode, 24);
6561                 add = BitIsSet (opcode, 23);
6562                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6563 
6564                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6565                 uint32_t type = Bits32 (opcode, 6, 5);
6566                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6567                 shift_n = DecodeImmShift (type, imm5, shift_t);
6568 
6569                 // if t == 15 || m == 15 then UNPREDICTABLE;
6570                 if ((t == 15) || (m == 15))
6571                     return false;
6572 
6573                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6574                 if (wback && ((n == 15) || (n == t)))
6575                     return false;
6576             }
6577                 break;
6578 
6579             default:
6580                 return false;
6581         }
6582 
6583         addr_t offset_addr;
6584         addr_t address;
6585 
6586         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6587         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6588         if (!success)
6589             return false;
6590 
6591         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6592         if (!success)
6593             return false;
6594 
6595         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6596         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6597         if (!success)
6598             return false;
6599 
6600         if (add)
6601             offset_addr = Rn + offset;
6602         else
6603             offset_addr = Rn - offset;
6604 
6605         // address = if index then offset_addr else R[n];
6606         if (index)
6607             address = offset_addr;
6608         else
6609             address = Rn;
6610 
6611         // R[t] = ZeroExtend(MemU[address,1],32);
6612         RegisterInfo base_reg;
6613         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6614 
6615         EmulateInstruction::Context context;
6616         context.type = eContextRegisterLoad;
6617         context.SetRegisterPlusOffset (base_reg, address - Rn);
6618 
6619         uint64_t data = MemURead (context, address, 1, 0, &success);
6620         if (!success)
6621             return false;
6622 
6623         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6624             return false;
6625 
6626         // if wback then R[n] = offset_addr;
6627         if (wback)
6628         {
6629             context.type = eContextAdjustBaseRegister;
6630             context.SetAddress (offset_addr);
6631             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6632                 return false;
6633         }
6634     }
6635     return true;
6636 }
6637 
6638 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a
6639 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register.  It can use offset,
6640 // post-indexed, or pre-indexed addressing.
6641 bool
6642 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding)
6643 {
6644 #if 0
6645     if ConditionPassed() then
6646         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6647         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6648         address = if index then offset_addr else R[n];
6649         data = MemU[address,2];
6650         if wback then R[n] = offset_addr;
6651         if UnalignedSupport() || address<0> = '0' then
6652             R[t] = ZeroExtend(data, 32);
6653         else // Can only apply before ARMv7
6654             R[t] = bits(32) UNKNOWN;
6655 #endif
6656 
6657 
6658     bool success = false;
6659 
6660     if (ConditionPassed(opcode))
6661     {
6662         uint32_t t;
6663         uint32_t n;
6664         uint32_t imm32;
6665         bool index;
6666         bool add;
6667         bool wback;
6668 
6669         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6670         switch (encoding)
6671         {
6672             case eEncodingT1:
6673                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
6674                 t = Bits32 (opcode, 2, 0);
6675                 n = Bits32 (opcode, 5, 3);
6676                 imm32 = Bits32 (opcode, 10, 6) << 1;
6677 
6678                 // index = TRUE; add = TRUE; wback = FALSE;
6679                 index = true;
6680                 add = true;
6681                 wback = false;
6682 
6683                 break;
6684 
6685             case eEncodingT2:
6686                 // if Rt == '1111' then SEE "Unallocated memory hints";
6687                 // if Rn == '1111' then SEE LDRH (literal);
6688                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6689                 t = Bits32 (opcode, 15, 12);
6690                 n = Bits32 (opcode, 19, 16);
6691                 imm32 = Bits32 (opcode, 11, 0);
6692 
6693                 // index = TRUE; add = TRUE; wback = FALSE;
6694                 index = true;
6695                 add = true;
6696                 wback = false;
6697 
6698                 // if t == 13 then UNPREDICTABLE;
6699                 if (t == 13)
6700                     return false;
6701                 break;
6702 
6703             case eEncodingT3:
6704                 // if Rn == '1111' then SEE LDRH (literal);
6705                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
6706                 // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
6707                 // if P == '0' && W == '0' then UNDEFINED;
6708                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6709                     return false;
6710 
6711                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6712                 t = Bits32 (opcode, 15, 12);
6713                 n = Bits32 (opcode, 19, 16);
6714                 imm32 = Bits32 (opcode, 7, 0);
6715 
6716                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6717                 index = BitIsSet (opcode, 10);
6718                 add = BitIsSet (opcode, 9);
6719                 wback = BitIsSet (opcode, 8);
6720 
6721                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6722                 if (BadReg (t) || (wback && (n == t)))
6723                     return false;
6724                 break;
6725 
6726             default:
6727                 return false;
6728         }
6729 
6730         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6731         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6732         if (!success)
6733             return false;
6734 
6735         addr_t offset_addr;
6736         addr_t address;
6737 
6738         if (add)
6739             offset_addr = Rn + imm32;
6740         else
6741             offset_addr = Rn - imm32;
6742 
6743         // address = if index then offset_addr else R[n];
6744         if (index)
6745             address = offset_addr;
6746         else
6747             address = Rn;
6748 
6749         // data = MemU[address,2];
6750         RegisterInfo base_reg;
6751         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6752 
6753         EmulateInstruction::Context context;
6754         context.type = eContextRegisterLoad;
6755         context.SetRegisterPlusOffset (base_reg, address - Rn);
6756 
6757         uint64_t data = MemURead (context, address, 2, 0, &success);
6758         if (!success)
6759             return false;
6760 
6761         // if wback then R[n] = offset_addr;
6762         if (wback)
6763         {
6764             context.type = eContextAdjustBaseRegister;
6765             context.SetAddress (offset_addr);
6766             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6767                 return false;
6768         }
6769 
6770         // if UnalignedSupport() || address<0> = '0' then
6771         if (UnalignedSupport () || BitIsClear (address, 0))
6772         {
6773             // R[t] = ZeroExtend(data, 32);
6774             context.type = eContextRegisterLoad;
6775             context.SetRegisterPlusOffset (base_reg, address - Rn);
6776             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6777                 return false;
6778         }
6779         else // Can only apply before ARMv7
6780         {
6781             // R[t] = bits(32) UNKNOWN;
6782             WriteBits32Unknown (t);
6783         }
6784     }
6785     return true;
6786 }
6787 
6788 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory,
6789 // zero-extends it to form a 32-bit word, and writes it to a register.
6790 bool
6791 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding)
6792 {
6793 #if 0
6794     if ConditionPassed() then
6795         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6796         base = Align(PC,4);
6797         address = if add then (base + imm32) else (base - imm32);
6798         data = MemU[address,2];
6799         if UnalignedSupport() || address<0> = '0' then
6800             R[t] = ZeroExtend(data, 32);
6801         else // Can only apply before ARMv7
6802             R[t] = bits(32) UNKNOWN;
6803 #endif
6804 
6805     bool success = false;
6806 
6807     if (ConditionPassed(opcode))
6808     {
6809         uint32_t t;
6810         uint32_t imm32;
6811         bool add;
6812 
6813         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6814         switch (encoding)
6815         {
6816             case eEncodingT1:
6817                 // if Rt == '1111' then SEE "Unallocated memory hints";
6818                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6819                 t = Bits32 (opcode, 15, 12);
6820                 imm32 = Bits32 (opcode, 11, 0);
6821                 add = BitIsSet (opcode, 23);
6822 
6823                 // if t == 13 then UNPREDICTABLE;
6824                 if (t == 13)
6825                     return false;
6826 
6827                 break;
6828 
6829             case eEncodingA1:
6830             {
6831                 uint32_t imm4H = Bits32 (opcode, 11, 8);
6832                 uint32_t imm4L = Bits32 (opcode, 3, 0);
6833 
6834                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6835                 t = Bits32 (opcode, 15, 12);
6836                 imm32 = (imm4H << 4) | imm4L;
6837                 add = BitIsSet (opcode, 23);
6838 
6839                 // if t == 15 then UNPREDICTABLE;
6840                 if (t == 15)
6841                     return false;
6842                 break;
6843             }
6844 
6845             default:
6846                 return false;
6847         }
6848 
6849         // base = Align(PC,4);
6850         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6851         if (!success)
6852             return false;
6853 
6854         addr_t base = AlignPC (pc_value);
6855         addr_t address;
6856 
6857         // address = if add then (base + imm32) else (base - imm32);
6858         if (add)
6859             address = base + imm32;
6860         else
6861             address = base - imm32;
6862 
6863         // data = MemU[address,2];
6864         RegisterInfo base_reg;
6865         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
6866 
6867         EmulateInstruction::Context context;
6868         context.type = eContextRegisterLoad;
6869         context.SetRegisterPlusOffset (base_reg, address - base);
6870 
6871         uint64_t data = MemURead (context, address, 2, 0, &success);
6872         if (!success)
6873             return false;
6874 
6875 
6876         // if UnalignedSupport() || address<0> = '0' then
6877         if (UnalignedSupport () || BitIsClear (address, 0))
6878         {
6879             // R[t] = ZeroExtend(data, 32);
6880             context.type = eContextRegisterLoad;
6881             context.SetRegisterPlusOffset (base_reg, address - base);
6882             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6883                 return false;
6884 
6885         }
6886         else // Can only apply before ARMv7
6887         {
6888             // R[t] = bits(32) UNKNOWN;
6889             WriteBits32Unknown (t);
6890         }
6891     }
6892     return true;
6893 }
6894 
6895 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword
6896 // from memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6897 // be shifted left by 0, 1, 2, or 3 bits.
6898 bool
6899 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding)
6900 {
6901 #if 0
6902     if ConditionPassed() then
6903         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6904         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6905         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6906         address = if index then offset_addr else R[n];
6907         data = MemU[address,2];
6908         if wback then R[n] = offset_addr;
6909         if UnalignedSupport() || address<0> = '0' then
6910             R[t] = ZeroExtend(data, 32);
6911         else // Can only apply before ARMv7
6912             R[t] = bits(32) UNKNOWN;
6913 #endif
6914 
6915     bool success = false;
6916 
6917     if (ConditionPassed(opcode))
6918     {
6919         uint32_t t;
6920         uint32_t n;
6921         uint32_t m;
6922         bool index;
6923         bool add;
6924         bool wback;
6925         ARM_ShifterType shift_t;
6926         uint32_t shift_n;
6927 
6928         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6929         switch (encoding)
6930         {
6931             case eEncodingT1:
6932                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6933                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6934                 t = Bits32 (opcode, 2, 0);
6935                 n = Bits32 (opcode, 5, 3);
6936                 m = Bits32 (opcode, 8, 6);
6937 
6938                 // index = TRUE; add = TRUE; wback = FALSE;
6939                 index = true;
6940                 add = true;
6941                 wback = false;
6942 
6943                 // (shift_t, shift_n) = (SRType_LSL, 0);
6944                 shift_t = SRType_LSL;
6945                 shift_n = 0;
6946 
6947                 break;
6948 
6949             case eEncodingT2:
6950                 // if Rn == '1111' then SEE LDRH (literal);
6951                 // if Rt == '1111' then SEE "Unallocated memory hints";
6952                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6953                 t = Bits32 (opcode, 15, 12);
6954                 n = Bits32 (opcode, 19, 16);
6955                 m = Bits32 (opcode, 3, 0);
6956 
6957                 // index = TRUE; add = TRUE; wback = FALSE;
6958                 index = true;
6959                 add = true;
6960                 wback = false;
6961 
6962                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6963                 shift_t = SRType_LSL;
6964                 shift_n = Bits32 (opcode, 5, 4);
6965 
6966                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6967                 if ((t == 13) || BadReg (m))
6968                     return false;
6969                 break;
6970 
6971             case eEncodingA1:
6972                 // if P == '0' && W == '1' then SEE LDRHT;
6973                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6974                 t = Bits32 (opcode, 15, 12);
6975                 n = Bits32 (opcode, 19, 16);
6976                 m = Bits32 (opcode, 3, 0);
6977 
6978                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6979                 index = BitIsSet (opcode, 24);
6980                 add = BitIsSet (opcode, 23);
6981                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6982 
6983                 // (shift_t, shift_n) = (SRType_LSL, 0);
6984                 shift_t = SRType_LSL;
6985                 shift_n = 0;
6986 
6987                 // if t == 15 || m == 15 then UNPREDICTABLE;
6988                 if ((t == 15) || (m == 15))
6989                     return false;
6990 
6991                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6992                 if (wback && ((n == 15) || (n == t)))
6993                     return false;
6994 
6995                 break;
6996 
6997             default:
6998                 return false;
6999         }
7000 
7001         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7002 
7003         uint64_t Rm  = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7004         if (!success)
7005             return false;
7006 
7007         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7008         if (!success)
7009             return false;
7010 
7011         addr_t offset_addr;
7012         addr_t address;
7013 
7014         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7015         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7016         if (!success)
7017             return false;
7018 
7019         if (add)
7020             offset_addr = Rn + offset;
7021         else
7022             offset_addr = Rn - offset;
7023 
7024         // address = if index then offset_addr else R[n];
7025         if (index)
7026             address = offset_addr;
7027         else
7028             address = Rn;
7029 
7030         // data = MemU[address,2];
7031         RegisterInfo base_reg;
7032         RegisterInfo offset_reg;
7033         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7034         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7035 
7036         EmulateInstruction::Context context;
7037         context.type = eContextRegisterLoad;
7038         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7039         uint64_t data = MemURead (context, address, 2, 0, &success);
7040         if (!success)
7041             return false;
7042 
7043         // if wback then R[n] = offset_addr;
7044         if (wback)
7045         {
7046             context.type = eContextAdjustBaseRegister;
7047             context.SetAddress (offset_addr);
7048             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7049                 return false;
7050         }
7051 
7052         // if UnalignedSupport() || address<0> = '0' then
7053         if (UnalignedSupport() || BitIsClear (address, 0))
7054         {
7055             // R[t] = ZeroExtend(data, 32);
7056             context.type = eContextRegisterLoad;
7057             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7058             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
7059                 return false;
7060         }
7061         else // Can only apply before ARMv7
7062         {
7063             // R[t] = bits(32) UNKNOWN;
7064             WriteBits32Unknown (t);
7065         }
7066     }
7067     return true;
7068 }
7069 
7070 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from
7071 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed,
7072 // or pre-indexed addressing.
7073 bool
7074 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding)
7075 {
7076 #if 0
7077     if ConditionPassed() then
7078         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7079         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7080         address = if index then offset_addr else R[n];
7081         R[t] = SignExtend(MemU[address,1], 32);
7082         if wback then R[n] = offset_addr;
7083 #endif
7084 
7085     bool success = false;
7086 
7087     if (ConditionPassed(opcode))
7088     {
7089         uint32_t t;
7090         uint32_t n;
7091         uint32_t imm32;
7092         bool index;
7093         bool add;
7094         bool wback;
7095 
7096         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7097         switch (encoding)
7098         {
7099             case eEncodingT1:
7100                 // if Rt == '1111' then SEE PLI;
7101                 // if Rn == '1111' then SEE LDRSB (literal);
7102                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7103                 t = Bits32 (opcode, 15, 12);
7104                 n = Bits32 (opcode, 19, 16);
7105                 imm32 = Bits32 (opcode, 11, 0);
7106 
7107                 // index = TRUE; add = TRUE; wback = FALSE;
7108                 index = true;
7109                 add = true;
7110                 wback = false;
7111 
7112                 // if t == 13 then UNPREDICTABLE;
7113                 if (t == 13)
7114                     return false;
7115 
7116                 break;
7117 
7118             case eEncodingT2:
7119                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
7120                 // if Rn == '1111' then SEE LDRSB (literal);
7121                 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
7122                 // if P == '0' && W == '0' then UNDEFINED;
7123                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7124                     return false;
7125 
7126                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7127                 t = Bits32 (opcode, 15, 12);
7128                 n = Bits32 (opcode, 19, 16);
7129                 imm32 = Bits32 (opcode, 7, 0);
7130 
7131                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7132                 index = BitIsSet (opcode, 10);
7133                 add = BitIsSet (opcode, 9);
7134                 wback = BitIsSet (opcode, 8);
7135 
7136                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7137                   if (((t == 13) || ((t == 15)
7138                                      && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8))))
7139                       || (wback && (n == t)))
7140                     return false;
7141 
7142                 break;
7143 
7144             case eEncodingA1:
7145             {
7146                 // if Rn == '1111' then SEE LDRSB (literal);
7147                 // if P == '0' && W == '1' then SEE LDRSBT;
7148                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7149                 t = Bits32 (opcode, 15, 12);
7150                 n = Bits32 (opcode, 19, 16);
7151 
7152                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7153                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7154                 imm32 = (imm4H << 4) | imm4L;
7155 
7156                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7157                 index = BitIsSet (opcode, 24);
7158                 add = BitIsSet (opcode, 23);
7159                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
7160 
7161                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7162                 if ((t == 15) || (wback && (n == t)))
7163                     return false;
7164 
7165                 break;
7166             }
7167 
7168             default:
7169                 return false;
7170         }
7171 
7172         uint64_t Rn = ReadCoreReg (n, &success);
7173         if (!success)
7174             return false;
7175 
7176         addr_t offset_addr;
7177         addr_t address;
7178 
7179         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7180         if (add)
7181             offset_addr = Rn + imm32;
7182         else
7183             offset_addr = Rn - imm32;
7184 
7185         // address = if index then offset_addr else R[n];
7186         if (index)
7187             address = offset_addr;
7188         else
7189             address = Rn;
7190 
7191         // R[t] = SignExtend(MemU[address,1], 32);
7192         RegisterInfo base_reg;
7193         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7194 
7195         EmulateInstruction::Context context;
7196         context.type = eContextRegisterLoad;
7197         context.SetRegisterPlusOffset (base_reg, address - Rn);
7198 
7199         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7200         if (!success)
7201             return false;
7202 
7203         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7204         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7205             return false;
7206 
7207         // if wback then R[n] = offset_addr;
7208         if (wback)
7209         {
7210             context.type = eContextAdjustBaseRegister;
7211             context.SetAddress (offset_addr);
7212             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7213                 return false;
7214         }
7215     }
7216 
7217     return true;
7218 }
7219 
7220 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
7221 // sign-extends it to form a 32-bit word, and writes tit to a register.
7222 bool
7223 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding)
7224 {
7225 #if 0
7226     if ConditionPassed() then
7227         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7228         base = Align(PC,4);
7229         address = if add then (base + imm32) else (base - imm32);
7230         R[t] = SignExtend(MemU[address,1], 32);
7231 #endif
7232 
7233     bool success = false;
7234 
7235     if (ConditionPassed(opcode))
7236     {
7237         uint32_t t;
7238         uint32_t imm32;
7239         bool add;
7240 
7241         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7242         switch (encoding)
7243         {
7244             case eEncodingT1:
7245                 // if Rt == '1111' then SEE PLI;
7246                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7247                 t = Bits32 (opcode, 15, 12);
7248                 imm32 = Bits32 (opcode, 11, 0);
7249                 add = BitIsSet (opcode, 23);
7250 
7251                 // if t == 13 then UNPREDICTABLE;
7252                 if (t == 13)
7253                     return false;
7254 
7255                 break;
7256 
7257             case eEncodingA1:
7258             {
7259                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7260                 t = Bits32 (opcode, 15, 12);
7261                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7262                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7263                 imm32 = (imm4H << 4) | imm4L;
7264                 add = BitIsSet (opcode, 23);
7265 
7266                 // if t == 15 then UNPREDICTABLE;
7267                 if (t == 15)
7268                     return false;
7269 
7270                 break;
7271             }
7272 
7273             default:
7274                 return false;
7275         }
7276 
7277         // base = Align(PC,4);
7278         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7279         if (!success)
7280             return false;
7281         uint64_t base = AlignPC (pc_value);
7282 
7283         // address = if add then (base + imm32) else (base - imm32);
7284         addr_t address;
7285         if (add)
7286             address = base + imm32;
7287         else
7288             address = base - imm32;
7289 
7290         // R[t] = SignExtend(MemU[address,1], 32);
7291         RegisterInfo base_reg;
7292         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7293 
7294         EmulateInstruction::Context context;
7295         context.type = eContextRegisterLoad;
7296         context.SetRegisterPlusOffset (base_reg, address - base);
7297 
7298         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7299         if (!success)
7300             return false;
7301 
7302         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7303         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7304             return false;
7305     }
7306     return true;
7307 }
7308 
7309 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from
7310 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7311 // shifted left by 0, 1, 2, or 3 bits.
7312 bool
7313 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding)
7314 {
7315 #if 0
7316     if ConditionPassed() then
7317         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7318         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7319         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7320         address = if index then offset_addr else R[n];
7321         R[t] = SignExtend(MemU[address,1], 32);
7322         if wback then R[n] = offset_addr;
7323 #endif
7324 
7325     bool success = false;
7326 
7327     if (ConditionPassed(opcode))
7328     {
7329         uint32_t t;
7330         uint32_t n;
7331         uint32_t m;
7332         bool index;
7333         bool add;
7334         bool wback;
7335         ARM_ShifterType shift_t;
7336         uint32_t shift_n;
7337 
7338         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7339         switch (encoding)
7340         {
7341             case eEncodingT1:
7342                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7343                 t = Bits32 (opcode, 2, 0);
7344                 n = Bits32 (opcode, 5, 3);
7345                 m = Bits32 (opcode, 8, 6);
7346 
7347                 // index = TRUE; add = TRUE; wback = FALSE;
7348                 index = true;
7349                 add = true;
7350                 wback = false;
7351 
7352                 // (shift_t, shift_n) = (SRType_LSL, 0);
7353                 shift_t = SRType_LSL;
7354                 shift_n = 0;
7355 
7356                 break;
7357 
7358             case eEncodingT2:
7359                 // if Rt == '1111' then SEE PLI;
7360                 // if Rn == '1111' then SEE LDRSB (literal);
7361                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7362                 t = Bits32 (opcode, 15, 12);
7363                 n = Bits32 (opcode, 19, 16);
7364                 m = Bits32 (opcode, 3, 0);
7365 
7366                 // index = TRUE; add = TRUE; wback = FALSE;
7367                 index = true;
7368                 add = true;
7369                 wback = false;
7370 
7371                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7372                 shift_t = SRType_LSL;
7373                 shift_n = Bits32 (opcode, 5, 4);
7374 
7375                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7376                 if ((t == 13) || BadReg (m))
7377                     return false;
7378                 break;
7379 
7380             case eEncodingA1:
7381                 // if P == '0' && W == '1' then SEE LDRSBT;
7382                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7383                 t = Bits32 (opcode, 15, 12);
7384                 n = Bits32 (opcode, 19, 16);
7385                 m = Bits32 (opcode, 3, 0);
7386 
7387                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7388                 index = BitIsSet (opcode, 24);
7389                 add = BitIsSet (opcode, 23);
7390                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7391 
7392                 // (shift_t, shift_n) = (SRType_LSL, 0);
7393                 shift_t = SRType_LSL;
7394                 shift_n = 0;
7395 
7396                 // if t == 15 || m == 15 then UNPREDICTABLE;
7397                 if ((t == 15) || (m == 15))
7398                     return false;
7399 
7400                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7401                 if (wback && ((n == 15) || (n == t)))
7402                     return false;
7403                 break;
7404 
7405             default:
7406                 return false;
7407         }
7408 
7409         uint64_t Rm =  ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7410         if (!success)
7411             return false;
7412 
7413         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7414         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7415         if (!success)
7416             return false;
7417 
7418         addr_t offset_addr;
7419         addr_t address;
7420 
7421         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7422         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7423         if (!success)
7424             return false;
7425 
7426         if (add)
7427             offset_addr = Rn + offset;
7428         else
7429             offset_addr = Rn - offset;
7430 
7431         // address = if index then offset_addr else R[n];
7432         if (index)
7433             address = offset_addr;
7434         else
7435             address = Rn;
7436 
7437         // R[t] = SignExtend(MemU[address,1], 32);
7438         RegisterInfo base_reg;
7439         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7440         RegisterInfo offset_reg;
7441         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7442 
7443         EmulateInstruction::Context context;
7444         context.type = eContextRegisterLoad;
7445         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7446 
7447         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7448         if (!success)
7449             return false;
7450 
7451         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7452         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7453             return false;
7454 
7455         // if wback then R[n] = offset_addr;
7456         if (wback)
7457         {
7458             context.type = eContextAdjustBaseRegister;
7459             context.SetAddress (offset_addr);
7460             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7461                 return false;
7462         }
7463     }
7464     return true;
7465 }
7466 
7467 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from
7468 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed, or
7469 // pre-indexed addressing.
7470 bool
7471 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding)
7472 {
7473 #if 0
7474     if ConditionPassed() then
7475         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7476         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7477         address = if index then offset_addr else R[n];
7478         data = MemU[address,2];
7479         if wback then R[n] = offset_addr;
7480         if UnalignedSupport() || address<0> = '0' then
7481             R[t] = SignExtend(data, 32);
7482         else // Can only apply before ARMv7
7483             R[t] = bits(32) UNKNOWN;
7484 #endif
7485 
7486     bool success = false;
7487 
7488     if (ConditionPassed(opcode))
7489     {
7490         uint32_t t;
7491         uint32_t n;
7492         uint32_t imm32;
7493         bool index;
7494         bool add;
7495         bool wback;
7496 
7497         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7498         switch (encoding)
7499         {
7500             case eEncodingT1:
7501                 // if Rn == '1111' then SEE LDRSH (literal);
7502                 // if Rt == '1111' then SEE "Unallocated memory hints";
7503                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7504                 t = Bits32 (opcode, 15, 12);
7505                 n = Bits32 (opcode, 19, 16);
7506                 imm32 = Bits32 (opcode, 11, 0);
7507 
7508                 // index = TRUE; add = TRUE; wback = FALSE;
7509                 index = true;
7510                 add = true;
7511                 wback = false;
7512 
7513                 // if t == 13 then UNPREDICTABLE;
7514                 if (t == 13)
7515                     return false;
7516 
7517                 break;
7518 
7519             case eEncodingT2:
7520                 // if Rn == '1111' then SEE LDRSH (literal);
7521                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
7522                 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7523                 // if P == '0' && W == '0' then UNDEFINED;
7524                   if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7525                   return false;
7526 
7527                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7528                 t = Bits32 (opcode, 15, 12);
7529                 n = Bits32 (opcode, 19, 16);
7530                 imm32 = Bits32 (opcode, 7, 0);
7531 
7532                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7533                 index = BitIsSet (opcode, 10);
7534                 add = BitIsSet (opcode, 9);
7535                 wback = BitIsSet (opcode, 8);
7536 
7537                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7538                 if (BadReg (t) || (wback && (n == t)))
7539                     return false;
7540 
7541                 break;
7542 
7543             case eEncodingA1:
7544             {
7545                 // if Rn == '1111' then SEE LDRSH (literal);
7546                 // if P == '0' && W == '1' then SEE LDRSHT;
7547                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7548                 t = Bits32 (opcode, 15, 12);
7549                 n = Bits32 (opcode, 19, 16);
7550                 uint32_t imm4H = Bits32 (opcode, 11,8);
7551                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7552                 imm32 = (imm4H << 4) | imm4L;
7553 
7554                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7555                 index = BitIsSet (opcode, 24);
7556                 add = BitIsSet (opcode, 23);
7557                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7558 
7559                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7560                 if ((t == 15) || (wback && (n == t)))
7561                     return false;
7562 
7563                 break;
7564             }
7565 
7566             default:
7567                 return false;
7568         }
7569 
7570         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7571         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7572         if (!success)
7573             return false;
7574 
7575         addr_t offset_addr;
7576         if (add)
7577             offset_addr = Rn + imm32;
7578         else
7579             offset_addr = Rn - imm32;
7580 
7581         // address = if index then offset_addr else R[n];
7582         addr_t address;
7583         if (index)
7584             address = offset_addr;
7585         else
7586             address = Rn;
7587 
7588         // data = MemU[address,2];
7589         RegisterInfo base_reg;
7590         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7591 
7592         EmulateInstruction::Context context;
7593         context.type = eContextRegisterLoad;
7594         context.SetRegisterPlusOffset (base_reg, address - Rn);
7595 
7596         uint64_t data = MemURead (context, address, 2, 0, &success);
7597         if (!success)
7598             return false;
7599 
7600         // if wback then R[n] = offset_addr;
7601         if (wback)
7602         {
7603             context.type = eContextAdjustBaseRegister;
7604             context.SetAddress (offset_addr);
7605             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7606                 return false;
7607         }
7608 
7609         // if UnalignedSupport() || address<0> = '0' then
7610         if (UnalignedSupport() || BitIsClear (address, 0))
7611         {
7612             // R[t] = SignExtend(data, 32);
7613             int64_t signed_data = llvm::SignExtend64<16>(data);
7614             context.type = eContextRegisterLoad;
7615             context.SetRegisterPlusOffset (base_reg, address - Rn);
7616             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7617                 return false;
7618         }
7619         else // Can only apply before ARMv7
7620         {
7621             // R[t] = bits(32) UNKNOWN;
7622             WriteBits32Unknown (t);
7623         }
7624     }
7625     return true;
7626 }
7627 
7628 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory,
7629 // sign-extends it to from a 32-bit word, and writes it to a register.
7630 bool
7631 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding)
7632 {
7633 #if 0
7634     if ConditionPassed() then
7635         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7636         base = Align(PC,4);
7637         address = if add then (base + imm32) else (base - imm32);
7638         data = MemU[address,2];
7639         if UnalignedSupport() || address<0> = '0' then
7640             R[t] = SignExtend(data, 32);
7641         else // Can only apply before ARMv7
7642             R[t] = bits(32) UNKNOWN;
7643 #endif
7644 
7645     bool success = false;
7646 
7647     if (ConditionPassed(opcode))
7648     {
7649         uint32_t t;
7650         uint32_t imm32;
7651         bool add;
7652 
7653         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7654         switch (encoding)
7655         {
7656             case eEncodingT1:
7657                 // if Rt == '1111' then SEE "Unallocated memory hints";
7658                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7659                 t = Bits32  (opcode, 15, 12);
7660                 imm32 = Bits32 (opcode, 11, 0);
7661                 add = BitIsSet (opcode, 23);
7662 
7663                 // if t == 13 then UNPREDICTABLE;
7664                 if (t == 13)
7665                     return false;
7666 
7667                 break;
7668 
7669             case eEncodingA1:
7670             {
7671                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7672                 t = Bits32 (opcode, 15, 12);
7673                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7674                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7675                 imm32 = (imm4H << 4) | imm4L;
7676                 add = BitIsSet (opcode, 23);
7677 
7678                 // if t == 15 then UNPREDICTABLE;
7679                 if (t == 15)
7680                     return false;
7681 
7682                 break;
7683             }
7684             default:
7685                 return false;
7686         }
7687 
7688         // base = Align(PC,4);
7689         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7690         if (!success)
7691             return false;
7692 
7693         uint64_t base = AlignPC (pc_value);
7694 
7695         addr_t address;
7696         // address = if add then (base + imm32) else (base - imm32);
7697         if (add)
7698             address = base + imm32;
7699         else
7700             address = base - imm32;
7701 
7702         // data = MemU[address,2];
7703         RegisterInfo base_reg;
7704         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7705 
7706         EmulateInstruction::Context context;
7707         context.type = eContextRegisterLoad;
7708         context.SetRegisterPlusOffset (base_reg, imm32);
7709 
7710         uint64_t data = MemURead (context, address, 2, 0, &success);
7711         if (!success)
7712             return false;
7713 
7714         // if UnalignedSupport() || address<0> = '0' then
7715         if (UnalignedSupport() || BitIsClear (address, 0))
7716         {
7717             // R[t] = SignExtend(data, 32);
7718             int64_t signed_data = llvm::SignExtend64<16>(data);
7719             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7720                 return false;
7721         }
7722         else // Can only apply before ARMv7
7723         {
7724             // R[t] = bits(32) UNKNOWN;
7725             WriteBits32Unknown (t);
7726         }
7727     }
7728     return true;
7729 }
7730 
7731 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword
7732 // from memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7733 // shifted left by 0, 1, 2, or 3 bits.
7734 bool
7735 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding)
7736 {
7737 #if 0
7738     if ConditionPassed() then
7739         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7740         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7741         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7742         address = if index then offset_addr else R[n];
7743         data = MemU[address,2];
7744         if wback then R[n] = offset_addr;
7745         if UnalignedSupport() || address<0> = '0' then
7746             R[t] = SignExtend(data, 32);
7747         else // Can only apply before ARMv7
7748             R[t] = bits(32) UNKNOWN;
7749 #endif
7750 
7751     bool success = false;
7752 
7753     if (ConditionPassed(opcode))
7754     {
7755         uint32_t t;
7756         uint32_t n;
7757         uint32_t m;
7758         bool index;
7759         bool add;
7760         bool wback;
7761         ARM_ShifterType shift_t;
7762         uint32_t shift_n;
7763 
7764         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7765         switch (encoding)
7766         {
7767             case eEncodingT1:
7768                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
7769                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7770                 t = Bits32 (opcode, 2, 0);
7771                 n = Bits32 (opcode, 5, 3);
7772                 m = Bits32 (opcode, 8, 6);
7773 
7774                 // index = TRUE; add = TRUE; wback = FALSE;
7775                 index = true;
7776                 add = true;
7777                 wback = false;
7778 
7779                 // (shift_t, shift_n) = (SRType_LSL, 0);
7780                 shift_t = SRType_LSL;
7781                 shift_n = 0;
7782 
7783                 break;
7784 
7785             case eEncodingT2:
7786                 // if Rn == '1111' then SEE LDRSH (literal);
7787                 // if Rt == '1111' then SEE "Unallocated memory hints";
7788                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7789                 t = Bits32 (opcode, 15, 12);
7790                 n = Bits32 (opcode, 19, 16);
7791                 m = Bits32 (opcode, 3, 0);
7792 
7793                 // index = TRUE; add = TRUE; wback = FALSE;
7794                 index = true;
7795                 add = true;
7796                 wback = false;
7797 
7798                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7799                 shift_t = SRType_LSL;
7800                 shift_n = Bits32 (opcode, 5, 4);
7801 
7802                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7803                 if ((t == 13) || BadReg (m))
7804                     return false;
7805 
7806                 break;
7807 
7808             case eEncodingA1:
7809                 // if P == '0' && W == '1' then SEE LDRSHT;
7810                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7811                 t = Bits32 (opcode, 15, 12);
7812                 n = Bits32 (opcode, 19, 16);
7813                 m = Bits32 (opcode, 3, 0);
7814 
7815                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7816                 index = BitIsSet (opcode, 24);
7817                 add = BitIsSet (opcode, 23);
7818                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7819 
7820                 // (shift_t, shift_n) = (SRType_LSL, 0);
7821                 shift_t = SRType_LSL;
7822                 shift_n = 0;
7823 
7824                 // if t == 15 || m == 15 then UNPREDICTABLE;
7825                 if ((t == 15) || (m == 15))
7826                     return false;
7827 
7828                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7829                 if (wback && ((n == 15) || (n == t)))
7830                     return false;
7831 
7832                 break;
7833 
7834             default:
7835                 return false;
7836         }
7837 
7838         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7839         if (!success)
7840             return false;
7841 
7842         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7843         if (!success)
7844             return false;
7845 
7846         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7847         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7848         if (!success)
7849             return false;
7850 
7851         addr_t offset_addr;
7852         addr_t address;
7853 
7854         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7855         if (add)
7856             offset_addr = Rn + offset;
7857         else
7858             offset_addr = Rn - offset;
7859 
7860         // address = if index then offset_addr else R[n];
7861         if (index)
7862             address = offset_addr;
7863         else
7864             address = Rn;
7865 
7866         // data = MemU[address,2];
7867         RegisterInfo base_reg;
7868         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7869 
7870         RegisterInfo offset_reg;
7871         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7872 
7873         EmulateInstruction::Context context;
7874         context.type = eContextRegisterLoad;
7875         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7876 
7877         uint64_t data = MemURead (context, address, 2, 0, &success);
7878         if (!success)
7879             return false;
7880 
7881         // if wback then R[n] = offset_addr;
7882         if (wback)
7883         {
7884             context.type = eContextAdjustBaseRegister;
7885             context.SetAddress (offset_addr);
7886             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7887                 return false;
7888         }
7889 
7890         // if UnalignedSupport() || address<0> = '0' then
7891         if (UnalignedSupport() || BitIsClear (address, 0))
7892         {
7893             // R[t] = SignExtend(data, 32);
7894             context.type = eContextRegisterLoad;
7895             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7896 
7897             int64_t signed_data = llvm::SignExtend64<16>(data);
7898             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7899                 return false;
7900         }
7901         else // Can only apply before ARMv7
7902         {
7903             // R[t] = bits(32) UNKNOWN;
7904             WriteBits32Unknown (t);
7905         }
7906     }
7907     return true;
7908 }
7909 
7910 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7911 // register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7912 bool
7913 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding)
7914 {
7915 #if 0
7916     if ConditionPassed() then
7917         EncodingSpecificOperations();
7918         rotated = ROR(R[m], rotation);
7919         R[d] = SignExtend(rotated<7:0>, 32);
7920 #endif
7921 
7922     bool success = false;
7923 
7924     if (ConditionPassed(opcode))
7925     {
7926         uint32_t d;
7927         uint32_t m;
7928         uint32_t rotation;
7929 
7930         // EncodingSpecificOperations();
7931         switch (encoding)
7932         {
7933             case eEncodingT1:
7934                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7935                 d = Bits32 (opcode, 2, 0);
7936                 m = Bits32 (opcode, 5, 3);
7937                 rotation = 0;
7938 
7939                 break;
7940 
7941             case eEncodingT2:
7942                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7943                 d = Bits32 (opcode, 11, 8);
7944                 m = Bits32 (opcode, 3, 0);
7945                 rotation = Bits32 (opcode, 5, 4) << 3;
7946 
7947                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7948                 if (BadReg (d) || BadReg (m))
7949                     return false;
7950 
7951                 break;
7952 
7953             case eEncodingA1:
7954                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7955                 d = Bits32 (opcode, 15, 12);
7956                 m = Bits32 (opcode, 3, 0);
7957                 rotation = Bits32 (opcode, 11, 10) << 3;
7958 
7959                 // if d == 15 || m == 15 then UNPREDICTABLE;
7960                 if ((d == 15) || (m == 15))
7961                     return false;
7962 
7963                 break;
7964 
7965             default:
7966                 return false;
7967         }
7968 
7969         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7970         if (!success)
7971             return false;
7972 
7973         // rotated = ROR(R[m], rotation);
7974         uint64_t rotated = ROR (Rm, rotation, &success);
7975         if (!success)
7976             return false;
7977 
7978         // R[d] = SignExtend(rotated<7:0>, 32);
7979         int64_t data = llvm::SignExtend64<8>(rotated);
7980 
7981         RegisterInfo source_reg;
7982         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7983 
7984         EmulateInstruction::Context context;
7985         context.type = eContextRegisterLoad;
7986         context.SetRegister (source_reg);
7987 
7988         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7989             return false;
7990     }
7991     return true;
7992 }
7993 
7994 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7995 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7996 bool
7997 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding)
7998 {
7999 #if 0
8000     if ConditionPassed() then
8001         EncodingSpecificOperations();
8002         rotated = ROR(R[m], rotation);
8003         R[d] = SignExtend(rotated<15:0>, 32);
8004 #endif
8005 
8006     bool success = false;
8007 
8008     if (ConditionPassed(opcode))
8009     {
8010         uint32_t d;
8011         uint32_t m;
8012         uint32_t rotation;
8013 
8014         // EncodingSpecificOperations();
8015         switch (encoding)
8016         {
8017             case eEncodingT1:
8018                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8019                 d = Bits32 (opcode, 2, 0);
8020                 m = Bits32 (opcode, 5, 3);
8021                 rotation = 0;
8022 
8023                 break;
8024 
8025             case eEncodingT2:
8026                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8027                 d = Bits32 (opcode, 11, 8);
8028                 m = Bits32 (opcode, 3, 0);
8029                 rotation = Bits32 (opcode, 5, 4) << 3;
8030 
8031                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8032                 if (BadReg (d) || BadReg (m))
8033                     return false;
8034 
8035                 break;
8036 
8037             case eEncodingA1:
8038                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8039                 d = Bits32 (opcode, 15, 12);
8040                 m = Bits32 (opcode, 3, 0);
8041                 rotation = Bits32 (opcode, 11, 10) << 3;
8042 
8043                 // if d == 15 || m == 15 then UNPREDICTABLE;
8044                 if ((d == 15) || (m == 15))
8045                     return false;
8046 
8047                 break;
8048 
8049             default:
8050                 return false;
8051         }
8052 
8053         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8054         if (!success)
8055             return false;
8056 
8057         // rotated = ROR(R[m], rotation);
8058         uint64_t rotated = ROR (Rm, rotation, &success);
8059         if (!success)
8060             return false;
8061 
8062         // R[d] = SignExtend(rotated<15:0>, 32);
8063         RegisterInfo source_reg;
8064         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8065 
8066         EmulateInstruction::Context context;
8067         context.type = eContextRegisterLoad;
8068         context.SetRegister (source_reg);
8069 
8070         int64_t data = llvm::SignExtend64<16> (rotated);
8071         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
8072             return false;
8073     }
8074 
8075     return true;
8076 }
8077 
8078 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination
8079 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
8080 bool
8081 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding)
8082 {
8083 #if 0
8084     if ConditionPassed() then
8085         EncodingSpecificOperations();
8086         rotated = ROR(R[m], rotation);
8087         R[d] = ZeroExtend(rotated<7:0>, 32);
8088 #endif
8089 
8090     bool success = false;
8091 
8092     if (ConditionPassed(opcode))
8093     {
8094         uint32_t d;
8095         uint32_t m;
8096         uint32_t rotation;
8097 
8098         // EncodingSpecificOperations();
8099         switch (encoding)
8100         {
8101             case eEncodingT1:
8102                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8103                 d = Bits32 (opcode, 2, 0);
8104                 m = Bits32 (opcode, 5, 3);
8105                 rotation = 0;
8106 
8107                 break;
8108 
8109             case eEncodingT2:
8110                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8111                 d = Bits32 (opcode, 11, 8);
8112                 m = Bits32 (opcode, 3, 0);
8113                   rotation = Bits32 (opcode, 5, 4) << 3;
8114 
8115                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8116                 if (BadReg (d) || BadReg (m))
8117                   return false;
8118 
8119                 break;
8120 
8121             case eEncodingA1:
8122                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8123                 d = Bits32 (opcode, 15, 12);
8124                 m = Bits32 (opcode, 3, 0);
8125                 rotation = Bits32 (opcode, 11, 10) << 3;
8126 
8127                 // if d == 15 || m == 15 then UNPREDICTABLE;
8128                 if ((d == 15) || (m == 15))
8129                     return false;
8130 
8131                 break;
8132 
8133             default:
8134                 return false;
8135         }
8136 
8137         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8138         if (!success)
8139             return false;
8140 
8141         // rotated = ROR(R[m], rotation);
8142         uint64_t rotated = ROR (Rm, rotation, &success);
8143         if (!success)
8144             return false;
8145 
8146         // R[d] = ZeroExtend(rotated<7:0>, 32);
8147         RegisterInfo source_reg;
8148         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8149 
8150         EmulateInstruction::Context context;
8151         context.type = eContextRegisterLoad;
8152         context.SetRegister (source_reg);
8153 
8154         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0)))
8155             return false;
8156     }
8157     return true;
8158 }
8159 
8160 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination
8161 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
8162 bool
8163 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding)
8164 {
8165 #if 0
8166     if ConditionPassed() then
8167         EncodingSpecificOperations();
8168         rotated = ROR(R[m], rotation);
8169         R[d] = ZeroExtend(rotated<15:0>, 32);
8170 #endif
8171 
8172     bool success = false;
8173 
8174     if (ConditionPassed(opcode))
8175     {
8176         uint32_t d;
8177         uint32_t m;
8178         uint32_t rotation;
8179 
8180         switch (encoding)
8181         {
8182             case eEncodingT1:
8183                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8184                 d = Bits32 (opcode, 2, 0);
8185                 m = Bits32 (opcode, 5, 3);
8186                 rotation = 0;
8187 
8188                 break;
8189 
8190             case eEncodingT2:
8191                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8192                 d = Bits32 (opcode, 11, 8);
8193                 m = Bits32 (opcode, 3, 0);
8194                 rotation = Bits32 (opcode, 5, 4) << 3;
8195 
8196                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8197                 if (BadReg (d) || BadReg (m))
8198                   return false;
8199 
8200                 break;
8201 
8202             case eEncodingA1:
8203                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8204                 d = Bits32 (opcode, 15, 12);
8205                 m = Bits32 (opcode, 3, 0);
8206                 rotation = Bits32 (opcode, 11, 10) << 3;
8207 
8208                 // if d == 15 || m == 15 then UNPREDICTABLE;
8209                 if ((d == 15) || (m == 15))
8210                     return false;
8211 
8212                 break;
8213 
8214             default:
8215                 return false;
8216         }
8217 
8218         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8219         if (!success)
8220             return false;
8221 
8222         // rotated = ROR(R[m], rotation);
8223         uint64_t rotated = ROR (Rm, rotation, &success);
8224         if (!success)
8225             return false;
8226 
8227         // R[d] = ZeroExtend(rotated<15:0>, 32);
8228         RegisterInfo source_reg;
8229         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8230 
8231         EmulateInstruction::Context context;
8232         context.type = eContextRegisterLoad;
8233         context.SetRegister (source_reg);
8234 
8235         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0)))
8236             return false;
8237     }
8238     return true;
8239 }
8240 
8241 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following
8242 // word respectively.
8243 bool
8244 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding)
8245 {
8246 #if 0
8247     if ConditionPassed() then
8248         EncodingSpecificOperations();
8249         if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8250             UNPREDICTABLE;
8251         else
8252             address = if increment then R[n] else R[n]-8;
8253             if wordhigher then address = address+4;
8254             CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8255             BranchWritePC(MemA[address,4]);
8256             if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8257 #endif
8258 
8259     bool success = false;
8260 
8261     if (ConditionPassed(opcode))
8262     {
8263         uint32_t n;
8264         bool wback;
8265         bool increment;
8266         bool wordhigher;
8267 
8268         // EncodingSpecificOperations();
8269         switch (encoding)
8270         {
8271             case eEncodingT1:
8272                 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE;
8273                 n = Bits32 (opcode, 19, 16);
8274                 wback = BitIsSet (opcode, 21);
8275                 increment = false;
8276                 wordhigher = false;
8277 
8278                 // if n == 15 then UNPREDICTABLE;
8279                 if (n == 15)
8280                     return false;
8281 
8282                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8283                 if (InITBlock() && !LastInITBlock())
8284                     return false;
8285 
8286                 break;
8287 
8288             case eEncodingT2:
8289                 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8290                 n = Bits32 (opcode, 19, 16);
8291                 wback = BitIsSet (opcode, 21);
8292                 increment = true;
8293                 wordhigher = false;
8294 
8295                 // if n == 15 then UNPREDICTABLE;
8296                 if (n == 15)
8297                     return false;
8298 
8299                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8300                 if (InITBlock() && !LastInITBlock())
8301                     return false;
8302 
8303                 break;
8304 
8305             case eEncodingA1:
8306                 // n = UInt(Rn);
8307                 n = Bits32 (opcode, 19, 16);
8308 
8309                 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8310                 wback = BitIsSet (opcode, 21);
8311                 increment = BitIsSet (opcode, 23);
8312                 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23));
8313 
8314                 // if n == 15 then UNPREDICTABLE;
8315                 if (n == 15)
8316                     return false;
8317 
8318                 break;
8319 
8320             default:
8321                 return false;
8322         }
8323 
8324         // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8325         if (!CurrentModeIsPrivileged ())
8326             // UNPREDICTABLE;
8327             return false;
8328         else
8329         {
8330             uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8331             if (!success)
8332                 return false;
8333 
8334             addr_t address;
8335             // address = if increment then R[n] else R[n]-8;
8336             if (increment)
8337                 address = Rn;
8338             else
8339                 address = Rn - 8;
8340 
8341             // if wordhigher then address = address+4;
8342             if (wordhigher)
8343                 address = address + 4;
8344 
8345             // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8346             RegisterInfo base_reg;
8347             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8348 
8349             EmulateInstruction::Context context;
8350             context.type = eContextReturnFromException;
8351             context.SetRegisterPlusOffset (base_reg, address - Rn);
8352 
8353             uint64_t data = MemARead (context, address + 4, 4, 0, &success);
8354             if (!success)
8355                 return false;
8356 
8357             CPSRWriteByInstr (data, 15, true);
8358 
8359             // BranchWritePC(MemA[address,4]);
8360             uint64_t data2 = MemARead (context, address, 4, 0, &success);
8361             if (!success)
8362                 return false;
8363 
8364             BranchWritePC (context, data2);
8365 
8366             // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8367             if (wback)
8368             {
8369                 context.type = eContextAdjustBaseRegister;
8370                 if (increment)
8371                 {
8372                     context.SetOffset (8);
8373                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8))
8374                         return false;
8375                 }
8376                 else
8377                 {
8378                     context.SetOffset (-8);
8379                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8))
8380                         return false;
8381                 }
8382             } // if wback
8383         }
8384     } // if ConditionPassed()
8385     return true;
8386 }
8387 
8388 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
8389 // and writes the result to the destination register.  It can optionally update the condition flags based on
8390 // the result.
8391 bool
8392 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding)
8393 {
8394 #if 0
8395     // ARM pseudo code...
8396     if ConditionPassed() then
8397         EncodingSpecificOperations();
8398         result = R[n] EOR imm32;
8399         if d == 15 then         // Can only occur for ARM encoding
8400             ALUWritePC(result); // setflags is always FALSE here
8401         else
8402             R[d] = result;
8403             if setflags then
8404                 APSR.N = result<31>;
8405                 APSR.Z = IsZeroBit(result);
8406                 APSR.C = carry;
8407                 // APSR.V unchanged
8408 #endif
8409 
8410     bool success = false;
8411 
8412     if (ConditionPassed(opcode))
8413     {
8414         uint32_t Rd, Rn;
8415         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8416         bool setflags;
8417         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8418         switch (encoding)
8419         {
8420         case eEncodingT1:
8421             Rd = Bits32(opcode, 11, 8);
8422             Rn = Bits32(opcode, 19, 16);
8423             setflags = BitIsSet(opcode, 20);
8424             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8425             // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8426             if (Rd == 15 && setflags)
8427                 return EmulateTEQImm (opcode, eEncodingT1);
8428             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8429                 return false;
8430             break;
8431         case eEncodingA1:
8432             Rd = Bits32(opcode, 15, 12);
8433             Rn = Bits32(opcode, 19, 16);
8434             setflags = BitIsSet(opcode, 20);
8435             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8436 
8437             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8438             if (Rd == 15 && setflags)
8439                 return EmulateSUBSPcLrEtc (opcode, encoding);
8440             break;
8441         default:
8442             return false;
8443         }
8444 
8445         // Read the first operand.
8446         uint32_t val1 = ReadCoreReg(Rn, &success);
8447         if (!success)
8448             return false;
8449 
8450         uint32_t result = val1 ^ imm32;
8451 
8452         EmulateInstruction::Context context;
8453         context.type = EmulateInstruction::eContextImmediate;
8454         context.SetNoArgs ();
8455 
8456         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8457             return false;
8458     }
8459     return true;
8460 }
8461 
8462 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an
8463 // optionally-shifted register value, and writes the result to the destination register.
8464 // It can optionally update the condition flags based on the result.
8465 bool
8466 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding)
8467 {
8468 #if 0
8469     // ARM pseudo code...
8470     if ConditionPassed() then
8471         EncodingSpecificOperations();
8472         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8473         result = R[n] EOR shifted;
8474         if d == 15 then         // Can only occur for ARM encoding
8475             ALUWritePC(result); // setflags is always FALSE here
8476         else
8477             R[d] = result;
8478             if setflags then
8479                 APSR.N = result<31>;
8480                 APSR.Z = IsZeroBit(result);
8481                 APSR.C = carry;
8482                 // APSR.V unchanged
8483 #endif
8484 
8485     bool success = false;
8486 
8487     if (ConditionPassed(opcode))
8488     {
8489         uint32_t Rd, Rn, Rm;
8490         ARM_ShifterType shift_t;
8491         uint32_t shift_n; // the shift applied to the value read from Rm
8492         bool setflags;
8493         uint32_t carry;
8494         switch (encoding)
8495         {
8496         case eEncodingT1:
8497             Rd = Rn = Bits32(opcode, 2, 0);
8498             Rm = Bits32(opcode, 5, 3);
8499             setflags = !InITBlock();
8500             shift_t = SRType_LSL;
8501             shift_n = 0;
8502             break;
8503         case eEncodingT2:
8504             Rd = Bits32(opcode, 11, 8);
8505             Rn = Bits32(opcode, 19, 16);
8506             Rm = Bits32(opcode, 3, 0);
8507             setflags = BitIsSet(opcode, 20);
8508             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8509             // if Rd == '1111' && S == '1' then SEE TEQ (register);
8510             if (Rd == 15 && setflags)
8511                 return EmulateTEQReg (opcode, eEncodingT1);
8512             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8513                 return false;
8514             break;
8515         case eEncodingA1:
8516             Rd = Bits32(opcode, 15, 12);
8517             Rn = Bits32(opcode, 19, 16);
8518             Rm = Bits32(opcode, 3, 0);
8519             setflags = BitIsSet(opcode, 20);
8520             shift_n = DecodeImmShiftARM(opcode, shift_t);
8521 
8522             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8523             if (Rd == 15 && setflags)
8524                 return EmulateSUBSPcLrEtc (opcode, encoding);
8525             break;
8526         default:
8527             return false;
8528         }
8529 
8530         // Read the first operand.
8531         uint32_t val1 = ReadCoreReg(Rn, &success);
8532         if (!success)
8533             return false;
8534 
8535         // Read the second operand.
8536         uint32_t val2 = ReadCoreReg(Rm, &success);
8537         if (!success)
8538             return false;
8539 
8540         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8541         if (!success)
8542             return false;
8543         uint32_t result = val1 ^ shifted;
8544 
8545         EmulateInstruction::Context context;
8546         context.type = EmulateInstruction::eContextImmediate;
8547         context.SetNoArgs ();
8548 
8549         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8550             return false;
8551     }
8552     return true;
8553 }
8554 
8555 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and
8556 // writes the result to the destination register.  It can optionally update the condition flags based
8557 // on the result.
8558 bool
8559 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding)
8560 {
8561 #if 0
8562     // ARM pseudo code...
8563     if ConditionPassed() then
8564         EncodingSpecificOperations();
8565         result = R[n] OR imm32;
8566         if d == 15 then         // Can only occur for ARM encoding
8567             ALUWritePC(result); // setflags is always FALSE here
8568         else
8569             R[d] = result;
8570             if setflags then
8571                 APSR.N = result<31>;
8572                 APSR.Z = IsZeroBit(result);
8573                 APSR.C = carry;
8574                 // APSR.V unchanged
8575 #endif
8576 
8577     bool success = false;
8578 
8579     if (ConditionPassed(opcode))
8580     {
8581         uint32_t Rd, Rn;
8582         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8583         bool setflags;
8584         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8585         switch (encoding)
8586         {
8587         case eEncodingT1:
8588             Rd = Bits32(opcode, 11, 8);
8589             Rn = Bits32(opcode, 19, 16);
8590             setflags = BitIsSet(opcode, 20);
8591             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8592             // if Rn == '1111' then SEE MOV (immediate);
8593             if (Rn == 15)
8594                 return EmulateMOVRdImm (opcode, eEncodingT2);
8595             if (BadReg(Rd) || Rn == 13)
8596                 return false;
8597             break;
8598         case eEncodingA1:
8599             Rd = Bits32(opcode, 15, 12);
8600             Rn = Bits32(opcode, 19, 16);
8601             setflags = BitIsSet(opcode, 20);
8602             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8603 
8604             if (Rd == 15 && setflags)
8605                 return EmulateSUBSPcLrEtc (opcode, encoding);
8606             break;
8607         default:
8608             return false;
8609         }
8610 
8611         // Read the first operand.
8612         uint32_t val1 = ReadCoreReg(Rn, &success);
8613         if (!success)
8614             return false;
8615 
8616         uint32_t result = val1 | imm32;
8617 
8618         EmulateInstruction::Context context;
8619         context.type = EmulateInstruction::eContextImmediate;
8620         context.SetNoArgs ();
8621 
8622         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8623             return false;
8624     }
8625     return true;
8626 }
8627 
8628 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register
8629 // value, and writes the result to the destination register.  It can optionally update the condition flags based
8630 // on the result.
8631 bool
8632 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding)
8633 {
8634 #if 0
8635     // ARM pseudo code...
8636     if ConditionPassed() then
8637         EncodingSpecificOperations();
8638         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8639         result = R[n] OR shifted;
8640         if d == 15 then         // Can only occur for ARM encoding
8641             ALUWritePC(result); // setflags is always FALSE here
8642         else
8643             R[d] = result;
8644             if setflags then
8645                 APSR.N = result<31>;
8646                 APSR.Z = IsZeroBit(result);
8647                 APSR.C = carry;
8648                 // APSR.V unchanged
8649 #endif
8650 
8651     bool success = false;
8652 
8653     if (ConditionPassed(opcode))
8654     {
8655         uint32_t Rd, Rn, Rm;
8656         ARM_ShifterType shift_t;
8657         uint32_t shift_n; // the shift applied to the value read from Rm
8658         bool setflags;
8659         uint32_t carry;
8660         switch (encoding)
8661         {
8662         case eEncodingT1:
8663             Rd = Rn = Bits32(opcode, 2, 0);
8664             Rm = Bits32(opcode, 5, 3);
8665             setflags = !InITBlock();
8666             shift_t = SRType_LSL;
8667             shift_n = 0;
8668             break;
8669         case eEncodingT2:
8670             Rd = Bits32(opcode, 11, 8);
8671             Rn = Bits32(opcode, 19, 16);
8672             Rm = Bits32(opcode, 3, 0);
8673             setflags = BitIsSet(opcode, 20);
8674             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8675             // if Rn == '1111' then SEE MOV (register);
8676             if (Rn == 15)
8677                 return EmulateMOVRdRm (opcode, eEncodingT3);
8678             if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
8679                 return false;
8680             break;
8681         case eEncodingA1:
8682             Rd = Bits32(opcode, 15, 12);
8683             Rn = Bits32(opcode, 19, 16);
8684             Rm = Bits32(opcode, 3, 0);
8685             setflags = BitIsSet(opcode, 20);
8686             shift_n = DecodeImmShiftARM(opcode, shift_t);
8687 
8688             if (Rd == 15 && setflags)
8689                 return EmulateSUBSPcLrEtc (opcode, encoding);
8690             break;
8691         default:
8692             return false;
8693         }
8694 
8695         // Read the first operand.
8696         uint32_t val1 = ReadCoreReg(Rn, &success);
8697         if (!success)
8698             return false;
8699 
8700         // Read the second operand.
8701         uint32_t val2 = ReadCoreReg(Rm, &success);
8702         if (!success)
8703             return false;
8704 
8705         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8706         if (!success)
8707             return false;
8708         uint32_t result = val1 | shifted;
8709 
8710         EmulateInstruction::Context context;
8711         context.type = EmulateInstruction::eContextImmediate;
8712         context.SetNoArgs ();
8713 
8714         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8715             return false;
8716     }
8717     return true;
8718 }
8719 
8720 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to
8721 // the destination register. It can optionally update the condition flags based on the result.
8722 bool
8723 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding)
8724 {
8725 #if 0
8726     // ARM pseudo code...
8727     if ConditionPassed() then
8728         EncodingSpecificOperations();
8729         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
8730         if d == 15 then         // Can only occur for ARM encoding
8731             ALUWritePC(result); // setflags is always FALSE here
8732         else
8733             R[d] = result;
8734             if setflags then
8735                 APSR.N = result<31>;
8736                 APSR.Z = IsZeroBit(result);
8737                 APSR.C = carry;
8738                 APSR.V = overflow;
8739 #endif
8740 
8741     bool success = false;
8742 
8743     uint32_t Rd; // the destination register
8744     uint32_t Rn; // the first operand
8745     bool setflags;
8746     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8747     switch (encoding) {
8748     case eEncodingT1:
8749         Rd = Bits32(opcode, 2, 0);
8750         Rn = Bits32(opcode, 5, 3);
8751         setflags = !InITBlock();
8752         imm32 = 0;
8753         break;
8754     case eEncodingT2:
8755         Rd = Bits32(opcode, 11, 8);
8756         Rn = Bits32(opcode, 19, 16);
8757         setflags = BitIsSet(opcode, 20);
8758         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8759         if (BadReg(Rd) || BadReg(Rn))
8760             return false;
8761         break;
8762     case eEncodingA1:
8763         Rd = Bits32(opcode, 15, 12);
8764         Rn = Bits32(opcode, 19, 16);
8765         setflags = BitIsSet(opcode, 20);
8766         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8767 
8768         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8769         if (Rd == 15 && setflags)
8770             return EmulateSUBSPcLrEtc (opcode, encoding);
8771         break;
8772     default:
8773         return false;
8774     }
8775     // Read the register value from the operand register Rn.
8776     uint32_t reg_val = ReadCoreReg(Rn, &success);
8777     if (!success)
8778         return false;
8779 
8780     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
8781 
8782     EmulateInstruction::Context context;
8783     context.type = EmulateInstruction::eContextImmediate;
8784     context.SetNoArgs ();
8785 
8786     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8787         return false;
8788 
8789     return true;
8790 }
8791 
8792 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the
8793 // result to the destination register. It can optionally update the condition flags based on the result.
8794 bool
8795 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding)
8796 {
8797 #if 0
8798     // ARM pseudo code...
8799     if ConditionPassed() then
8800         EncodingSpecificOperations();
8801         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8802         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
8803         if d == 15 then         // Can only occur for ARM encoding
8804             ALUWritePC(result); // setflags is always FALSE here
8805         else
8806             R[d] = result;
8807             if setflags then
8808                 APSR.N = result<31>;
8809                 APSR.Z = IsZeroBit(result);
8810                 APSR.C = carry;
8811                 APSR.V = overflow;
8812 #endif
8813 
8814     bool success = false;
8815 
8816     uint32_t Rd; // the destination register
8817     uint32_t Rn; // the first operand
8818     uint32_t Rm; // the second operand
8819     bool setflags;
8820     ARM_ShifterType shift_t;
8821     uint32_t shift_n; // the shift applied to the value read from Rm
8822     switch (encoding) {
8823     case eEncodingT1:
8824         Rd = Bits32(opcode, 11, 8);
8825         Rn = Bits32(opcode, 19, 16);
8826         Rm = Bits32(opcode, 3, 0);
8827         setflags = BitIsSet(opcode, 20);
8828         shift_n = DecodeImmShiftThumb(opcode, shift_t);
8829         // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
8830         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8831             return false;
8832         break;
8833     case eEncodingA1:
8834         Rd = Bits32(opcode, 15, 12);
8835         Rn = Bits32(opcode, 19, 16);
8836         Rm = Bits32(opcode, 3, 0);
8837         setflags = BitIsSet(opcode, 20);
8838         shift_n = DecodeImmShiftARM(opcode, shift_t);
8839 
8840         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8841         if (Rd == 15 && setflags)
8842             return EmulateSUBSPcLrEtc (opcode, encoding);
8843         break;
8844     default:
8845         return false;
8846     }
8847     // Read the register value from register Rn.
8848     uint32_t val1 = ReadCoreReg(Rn, &success);
8849     if (!success)
8850         return false;
8851 
8852     // Read the register value from register Rm.
8853     uint32_t val2 = ReadCoreReg(Rm, &success);
8854     if (!success)
8855         return false;
8856 
8857     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8858     if (!success)
8859         return false;
8860     AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
8861 
8862     EmulateInstruction::Context context;
8863     context.type = EmulateInstruction::eContextImmediate;
8864     context.SetNoArgs();
8865     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8866         return false;
8867 
8868     return true;
8869 }
8870 
8871 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from
8872 // an immediate value, and writes the result to the destination register. It can optionally update the condition
8873 // flags based on the result.
8874 bool
8875 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding)
8876 {
8877 #if 0
8878     // ARM pseudo code...
8879     if ConditionPassed() then
8880         EncodingSpecificOperations();
8881         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
8882         if d == 15 then
8883             ALUWritePC(result); // setflags is always FALSE here
8884         else
8885             R[d] = result;
8886             if setflags then
8887                 APSR.N = result<31>;
8888                 APSR.Z = IsZeroBit(result);
8889                 APSR.C = carry;
8890                 APSR.V = overflow;
8891 #endif
8892 
8893     bool success = false;
8894 
8895     uint32_t Rd; // the destination register
8896     uint32_t Rn; // the first operand
8897     bool setflags;
8898     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8899     switch (encoding) {
8900     case eEncodingA1:
8901         Rd = Bits32(opcode, 15, 12);
8902         Rn = Bits32(opcode, 19, 16);
8903         setflags = BitIsSet(opcode, 20);
8904         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8905 
8906         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8907         if (Rd == 15 && setflags)
8908             return EmulateSUBSPcLrEtc  (opcode, encoding);
8909         break;
8910     default:
8911         return false;
8912     }
8913     // Read the register value from the operand register Rn.
8914     uint32_t reg_val = ReadCoreReg(Rn, &success);
8915     if (!success)
8916         return false;
8917 
8918     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
8919 
8920     EmulateInstruction::Context context;
8921     context.type = EmulateInstruction::eContextImmediate;
8922     context.SetNoArgs ();
8923 
8924     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8925         return false;
8926 
8927     return true;
8928 }
8929 
8930 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an
8931 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the
8932 // condition flags based on the result.
8933 bool
8934 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding)
8935 {
8936 #if 0
8937     // ARM pseudo code...
8938     if ConditionPassed() then
8939         EncodingSpecificOperations();
8940         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8941         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
8942         if d == 15 then
8943             ALUWritePC(result); // setflags is always FALSE here
8944         else
8945             R[d] = result;
8946             if setflags then
8947                 APSR.N = result<31>;
8948                 APSR.Z = IsZeroBit(result);
8949                 APSR.C = carry;
8950                 APSR.V = overflow;
8951 #endif
8952 
8953     bool success = false;
8954 
8955     uint32_t Rd; // the destination register
8956     uint32_t Rn; // the first operand
8957     uint32_t Rm; // the second operand
8958     bool setflags;
8959     ARM_ShifterType shift_t;
8960     uint32_t shift_n; // the shift applied to the value read from Rm
8961     switch (encoding) {
8962     case eEncodingA1:
8963         Rd = Bits32(opcode, 15, 12);
8964         Rn = Bits32(opcode, 19, 16);
8965         Rm = Bits32(opcode, 3, 0);
8966         setflags = BitIsSet(opcode, 20);
8967         shift_n = DecodeImmShiftARM(opcode, shift_t);
8968 
8969         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8970         if (Rd == 15 && setflags)
8971             return EmulateSUBSPcLrEtc (opcode, encoding);
8972         break;
8973     default:
8974         return false;
8975     }
8976     // Read the register value from register Rn.
8977     uint32_t val1 = ReadCoreReg(Rn, &success);
8978     if (!success)
8979         return false;
8980 
8981     // Read the register value from register Rm.
8982     uint32_t val2 = ReadCoreReg(Rm, &success);
8983     if (!success)
8984         return false;
8985 
8986     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8987     if (!success)
8988         return false;
8989     AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
8990 
8991     EmulateInstruction::Context context;
8992     context.type = EmulateInstruction::eContextImmediate;
8993     context.SetNoArgs();
8994     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8995         return false;
8996 
8997     return true;
8998 }
8999 
9000 // Subtract with Carry (immediate) subtracts an immediate value and the value of
9001 // NOT (Carry flag) from a register value, and writes the result to the destination register.
9002 // It can optionally update the condition flags based on the result.
9003 bool
9004 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding)
9005 {
9006 #if 0
9007     // ARM pseudo code...
9008     if ConditionPassed() then
9009         EncodingSpecificOperations();
9010         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
9011         if d == 15 then         // Can only occur for ARM encoding
9012             ALUWritePC(result); // setflags is always FALSE here
9013         else
9014             R[d] = result;
9015             if setflags then
9016                 APSR.N = result<31>;
9017                 APSR.Z = IsZeroBit(result);
9018                 APSR.C = carry;
9019                 APSR.V = overflow;
9020 #endif
9021 
9022     bool success = false;
9023 
9024     uint32_t Rd; // the destination register
9025     uint32_t Rn; // the first operand
9026     bool setflags;
9027     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
9028     switch (encoding) {
9029     case eEncodingT1:
9030         Rd = Bits32(opcode, 11, 8);
9031         Rn = Bits32(opcode, 19, 16);
9032         setflags = BitIsSet(opcode, 20);
9033         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9034         if (BadReg(Rd) || BadReg(Rn))
9035             return false;
9036         break;
9037     case eEncodingA1:
9038         Rd = Bits32(opcode, 15, 12);
9039         Rn = Bits32(opcode, 19, 16);
9040         setflags = BitIsSet(opcode, 20);
9041         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9042 
9043         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9044         if (Rd == 15 && setflags)
9045             return EmulateSUBSPcLrEtc (opcode, encoding);
9046         break;
9047     default:
9048         return false;
9049     }
9050     // Read the register value from the operand register Rn.
9051     uint32_t reg_val = ReadCoreReg(Rn, &success);
9052     if (!success)
9053         return false;
9054 
9055     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
9056 
9057     EmulateInstruction::Context context;
9058     context.type = EmulateInstruction::eContextImmediate;
9059     context.SetNoArgs ();
9060 
9061     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9062         return false;
9063 
9064     return true;
9065 }
9066 
9067 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of
9068 // NOT (Carry flag) from a register value, and writes the result to the destination register.
9069 // It can optionally update the condition flags based on the result.
9070 bool
9071 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding)
9072 {
9073 #if 0
9074     // ARM pseudo code...
9075     if ConditionPassed() then
9076         EncodingSpecificOperations();
9077         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9078         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
9079         if d == 15 then         // Can only occur for ARM encoding
9080             ALUWritePC(result); // setflags is always FALSE here
9081         else
9082             R[d] = result;
9083             if setflags then
9084                 APSR.N = result<31>;
9085                 APSR.Z = IsZeroBit(result);
9086                 APSR.C = carry;
9087                 APSR.V = overflow;
9088 #endif
9089 
9090     bool success = false;
9091 
9092     uint32_t Rd; // the destination register
9093     uint32_t Rn; // the first operand
9094     uint32_t Rm; // the second operand
9095     bool setflags;
9096     ARM_ShifterType shift_t;
9097     uint32_t shift_n; // the shift applied to the value read from Rm
9098     switch (encoding) {
9099     case eEncodingT1:
9100         Rd = Rn = Bits32(opcode, 2, 0);
9101         Rm = Bits32(opcode, 5, 3);
9102         setflags = !InITBlock();
9103         shift_t = SRType_LSL;
9104         shift_n = 0;
9105         break;
9106     case eEncodingT2:
9107         Rd = Bits32(opcode, 11, 8);
9108         Rn = Bits32(opcode, 19, 16);
9109         Rm = Bits32(opcode, 3, 0);
9110         setflags = BitIsSet(opcode, 20);
9111         shift_n = DecodeImmShiftThumb(opcode, shift_t);
9112         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9113             return false;
9114         break;
9115     case eEncodingA1:
9116         Rd = Bits32(opcode, 15, 12);
9117         Rn = Bits32(opcode, 19, 16);
9118         Rm = Bits32(opcode, 3, 0);
9119         setflags = BitIsSet(opcode, 20);
9120         shift_n = DecodeImmShiftARM(opcode, shift_t);
9121 
9122         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9123         if (Rd == 15 && setflags)
9124             return EmulateSUBSPcLrEtc (opcode, encoding);
9125         break;
9126     default:
9127         return false;
9128     }
9129     // Read the register value from register Rn.
9130     uint32_t val1 = ReadCoreReg(Rn, &success);
9131     if (!success)
9132         return false;
9133 
9134     // Read the register value from register Rm.
9135     uint32_t val2 = ReadCoreReg(Rm, &success);
9136     if (!success)
9137         return false;
9138 
9139     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9140     if (!success)
9141         return false;
9142     AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
9143 
9144     EmulateInstruction::Context context;
9145     context.type = EmulateInstruction::eContextImmediate;
9146     context.SetNoArgs();
9147     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9148         return false;
9149 
9150     return true;
9151 }
9152 
9153 // This instruction subtracts an immediate value from a register value, and writes the result
9154 // to the destination register.  It can optionally update the condition flags based on the result.
9155 bool
9156 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding)
9157 {
9158 #if 0
9159     // ARM pseudo code...
9160     if ConditionPassed() then
9161         EncodingSpecificOperations();
9162         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9163         R[d] = result;
9164         if setflags then
9165             APSR.N = result<31>;
9166             APSR.Z = IsZeroBit(result);
9167             APSR.C = carry;
9168             APSR.V = overflow;
9169 #endif
9170 
9171     bool success = false;
9172 
9173     uint32_t Rd; // the destination register
9174     uint32_t Rn; // the first operand
9175     bool setflags;
9176     uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9177     switch (encoding) {
9178     case eEncodingT1:
9179         Rd = Bits32(opcode, 2, 0);
9180         Rn = Bits32(opcode, 5, 3);
9181         setflags = !InITBlock();
9182         imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9183         break;
9184     case eEncodingT2:
9185         Rd = Rn = Bits32(opcode, 10, 8);
9186         setflags = !InITBlock();
9187         imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9188         break;
9189     case eEncodingT3:
9190         Rd = Bits32(opcode, 11, 8);
9191         Rn = Bits32(opcode, 19, 16);
9192         setflags = BitIsSet(opcode, 20);
9193         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9194 
9195         // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9196         if (Rd == 15 && setflags)
9197             return EmulateCMPImm (opcode, eEncodingT2);
9198 
9199         // if Rn == '1101' then SEE SUB (SP minus immediate);
9200         if (Rn == 13)
9201             return EmulateSUBSPImm (opcode, eEncodingT2);
9202 
9203         // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9204         if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9205             return false;
9206         break;
9207     case eEncodingT4:
9208         Rd = Bits32(opcode, 11, 8);
9209         Rn = Bits32(opcode, 19, 16);
9210         setflags = BitIsSet(opcode, 20);
9211         imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9212 
9213         // if Rn == '1111' then SEE ADR;
9214         if (Rn == 15)
9215             return EmulateADR (opcode, eEncodingT2);
9216 
9217         // if Rn == '1101' then SEE SUB (SP minus immediate);
9218         if (Rn == 13)
9219             return EmulateSUBSPImm (opcode, eEncodingT3);
9220 
9221         if (BadReg(Rd))
9222             return false;
9223         break;
9224     default:
9225         return false;
9226     }
9227     // Read the register value from the operand register Rn.
9228     uint32_t reg_val = ReadCoreReg(Rn, &success);
9229     if (!success)
9230         return false;
9231 
9232     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9233 
9234     EmulateInstruction::Context context;
9235     context.type = EmulateInstruction::eContextImmediate;
9236     context.SetNoArgs ();
9237 
9238     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9239         return false;
9240 
9241     return true;
9242 }
9243 
9244 // This instruction subtracts an immediate value from a register value, and writes the result
9245 // to the destination register.  It can optionally update the condition flags based on the result.
9246 bool
9247 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9248 {
9249 #if 0
9250     // ARM pseudo code...
9251     if ConditionPassed() then
9252         EncodingSpecificOperations();
9253         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9254         if d == 15 then
9255             ALUWritePC(result); // setflags is always FALSE here
9256         else
9257             R[d] = result;
9258             if setflags then
9259                 APSR.N = result<31>;
9260                 APSR.Z = IsZeroBit(result);
9261                 APSR.C = carry;
9262                 APSR.V = overflow;
9263 #endif
9264 
9265     bool success = false;
9266 
9267     if (ConditionPassed(opcode))
9268     {
9269         uint32_t Rd; // the destination register
9270         uint32_t Rn; // the first operand
9271         bool setflags;
9272         uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9273         switch (encoding) {
9274         case eEncodingA1:
9275             Rd = Bits32(opcode, 15, 12);
9276             Rn = Bits32(opcode, 19, 16);
9277             setflags = BitIsSet(opcode, 20);
9278             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9279 
9280             // if Rn == '1111' && S == '0' then SEE ADR;
9281             if (Rn == 15 && !setflags)
9282                 return EmulateADR (opcode, eEncodingA2);
9283 
9284             // if Rn == '1101' then SEE SUB (SP minus immediate);
9285             if (Rn == 13)
9286                 return EmulateSUBSPImm (opcode, eEncodingA1);
9287 
9288             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9289             if (Rd == 15 && setflags)
9290                 return EmulateSUBSPcLrEtc (opcode, encoding);
9291             break;
9292         default:
9293             return false;
9294         }
9295         // Read the register value from the operand register Rn.
9296         uint32_t reg_val = ReadCoreReg(Rn, &success);
9297         if (!success)
9298             return false;
9299 
9300         AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9301 
9302         EmulateInstruction::Context context;
9303         if (Rd == 13)
9304             context.type = EmulateInstruction::eContextAdjustStackPointer;
9305         else
9306             context.type = EmulateInstruction::eContextRegisterPlusOffset;
9307 
9308         RegisterInfo dwarf_reg;
9309         GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
9310         int64_t imm32_signed = imm32;
9311         context.SetRegisterPlusOffset (dwarf_reg, -imm32_signed);
9312 
9313         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9314             return false;
9315     }
9316     return true;
9317 }
9318 
9319 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an
9320 // immediate value.  It updates the condition flags based on the result, and discards the result.
9321 bool
9322 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding)
9323 {
9324 #if 0
9325     // ARM pseudo code...
9326     if ConditionPassed() then
9327         EncodingSpecificOperations();
9328         result = R[n] EOR imm32;
9329         APSR.N = result<31>;
9330         APSR.Z = IsZeroBit(result);
9331         APSR.C = carry;
9332         // APSR.V unchanged
9333 #endif
9334 
9335     bool success = false;
9336 
9337     if (ConditionPassed(opcode))
9338     {
9339         uint32_t Rn;
9340         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9341         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9342         switch (encoding)
9343         {
9344         case eEncodingT1:
9345             Rn = Bits32(opcode, 19, 16);
9346             imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9347             if (BadReg(Rn))
9348                 return false;
9349             break;
9350         case eEncodingA1:
9351             Rn = Bits32(opcode, 19, 16);
9352             imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9353             break;
9354         default:
9355             return false;
9356         }
9357 
9358         // Read the first operand.
9359         uint32_t val1 = ReadCoreReg(Rn, &success);
9360         if (!success)
9361             return false;
9362 
9363         uint32_t result = val1 ^ imm32;
9364 
9365         EmulateInstruction::Context context;
9366         context.type = EmulateInstruction::eContextImmediate;
9367         context.SetNoArgs ();
9368 
9369         if (!WriteFlags(context, result, carry))
9370             return false;
9371     }
9372     return true;
9373 }
9374 
9375 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an
9376 // optionally-shifted register value.  It updates the condition flags based on the result, and discards
9377 // the result.
9378 bool
9379 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding)
9380 {
9381 #if 0
9382     // ARM pseudo code...
9383     if ConditionPassed() then
9384         EncodingSpecificOperations();
9385         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9386         result = R[n] EOR shifted;
9387         APSR.N = result<31>;
9388         APSR.Z = IsZeroBit(result);
9389         APSR.C = carry;
9390         // APSR.V unchanged
9391 #endif
9392 
9393     bool success = false;
9394 
9395     if (ConditionPassed(opcode))
9396     {
9397         uint32_t Rn, Rm;
9398         ARM_ShifterType shift_t;
9399         uint32_t shift_n; // the shift applied to the value read from Rm
9400         uint32_t carry;
9401         switch (encoding)
9402         {
9403         case eEncodingT1:
9404             Rn = Bits32(opcode, 19, 16);
9405             Rm = Bits32(opcode, 3, 0);
9406             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9407             if (BadReg(Rn) || BadReg(Rm))
9408                 return false;
9409             break;
9410         case eEncodingA1:
9411             Rn = Bits32(opcode, 19, 16);
9412             Rm = Bits32(opcode, 3, 0);
9413             shift_n = DecodeImmShiftARM(opcode, shift_t);
9414             break;
9415         default:
9416             return false;
9417         }
9418 
9419         // Read the first operand.
9420         uint32_t val1 = ReadCoreReg(Rn, &success);
9421         if (!success)
9422             return false;
9423 
9424         // Read the second operand.
9425         uint32_t val2 = ReadCoreReg(Rm, &success);
9426         if (!success)
9427             return false;
9428 
9429         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9430         if (!success)
9431             return false;
9432         uint32_t result = val1 ^ shifted;
9433 
9434         EmulateInstruction::Context context;
9435         context.type = EmulateInstruction::eContextImmediate;
9436         context.SetNoArgs ();
9437 
9438         if (!WriteFlags(context, result, carry))
9439             return false;
9440     }
9441     return true;
9442 }
9443 
9444 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value.
9445 // It updates the condition flags based on the result, and discards the result.
9446 bool
9447 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding)
9448 {
9449 #if 0
9450     // ARM pseudo code...
9451     if ConditionPassed() then
9452         EncodingSpecificOperations();
9453         result = R[n] AND imm32;
9454         APSR.N = result<31>;
9455         APSR.Z = IsZeroBit(result);
9456         APSR.C = carry;
9457         // APSR.V unchanged
9458 #endif
9459 
9460     bool success = false;
9461 
9462     if (ConditionPassed(opcode))
9463     {
9464         uint32_t Rn;
9465         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9466         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9467         switch (encoding)
9468         {
9469         case eEncodingT1:
9470             Rn = Bits32(opcode, 19, 16);
9471             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9472             if (BadReg(Rn))
9473                 return false;
9474             break;
9475         case eEncodingA1:
9476             Rn = Bits32(opcode, 19, 16);
9477             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9478             break;
9479         default:
9480             return false;
9481         }
9482 
9483         // Read the first operand.
9484         uint32_t val1 = ReadCoreReg(Rn, &success);
9485         if (!success)
9486             return false;
9487 
9488         uint32_t result = val1 & imm32;
9489 
9490         EmulateInstruction::Context context;
9491         context.type = EmulateInstruction::eContextImmediate;
9492         context.SetNoArgs ();
9493 
9494         if (!WriteFlags(context, result, carry))
9495             return false;
9496     }
9497     return true;
9498 }
9499 
9500 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value.
9501 // It updates the condition flags based on the result, and discards the result.
9502 bool
9503 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding)
9504 {
9505 #if 0
9506     // ARM pseudo code...
9507     if ConditionPassed() then
9508         EncodingSpecificOperations();
9509         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9510         result = R[n] AND shifted;
9511         APSR.N = result<31>;
9512         APSR.Z = IsZeroBit(result);
9513         APSR.C = carry;
9514         // APSR.V unchanged
9515 #endif
9516 
9517     bool success = false;
9518 
9519     if (ConditionPassed(opcode))
9520     {
9521         uint32_t Rn, Rm;
9522         ARM_ShifterType shift_t;
9523         uint32_t shift_n; // the shift applied to the value read from Rm
9524         uint32_t carry;
9525         switch (encoding)
9526         {
9527         case eEncodingT1:
9528             Rn = Bits32(opcode, 2, 0);
9529             Rm = Bits32(opcode, 5, 3);
9530             shift_t = SRType_LSL;
9531             shift_n = 0;
9532             break;
9533         case eEncodingT2:
9534             Rn = Bits32(opcode, 19, 16);
9535             Rm = Bits32(opcode, 3, 0);
9536             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9537             if (BadReg(Rn) || BadReg(Rm))
9538                 return false;
9539             break;
9540         case eEncodingA1:
9541             Rn = Bits32(opcode, 19, 16);
9542             Rm = Bits32(opcode, 3, 0);
9543             shift_n = DecodeImmShiftARM(opcode, shift_t);
9544             break;
9545         default:
9546             return false;
9547         }
9548 
9549         // Read the first operand.
9550         uint32_t val1 = ReadCoreReg(Rn, &success);
9551         if (!success)
9552             return false;
9553 
9554         // Read the second operand.
9555         uint32_t val2 = ReadCoreReg(Rm, &success);
9556         if (!success)
9557             return false;
9558 
9559         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9560         if (!success)
9561             return false;
9562         uint32_t result = val1 & shifted;
9563 
9564         EmulateInstruction::Context context;
9565         context.type = EmulateInstruction::eContextImmediate;
9566         context.SetNoArgs ();
9567 
9568         if (!WriteFlags(context, result, carry))
9569             return false;
9570     }
9571     return true;
9572 }
9573 
9574 // A8.6.216 SUB (SP minus register)
9575 bool
9576 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding)
9577 {
9578 #if 0
9579     if ConditionPassed() then
9580         EncodingSpecificOperations();
9581         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9582         (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9583         if d == 15 then // Can only occur for ARM encoding
9584             ALUWritePC(result); // setflags is always FALSE here
9585         else
9586             R[d] = result;
9587             if setflags then
9588                 APSR.N = result<31>;
9589                 APSR.Z = IsZeroBit(result);
9590                 APSR.C = carry;
9591                 APSR.V = overflow;
9592 #endif
9593 
9594     bool success = false;
9595 
9596     if (ConditionPassed(opcode))
9597     {
9598         uint32_t d;
9599         uint32_t m;
9600         bool setflags;
9601         ARM_ShifterType shift_t;
9602         uint32_t shift_n;
9603 
9604         switch (encoding)
9605         {
9606             case eEncodingT1:
9607                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9608                 d = Bits32 (opcode, 11, 8);
9609                 m = Bits32 (opcode, 3, 0);
9610                 setflags = BitIsSet (opcode, 20);
9611 
9612                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9613                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9614 
9615                 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE;
9616                 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
9617                     return false;
9618 
9619                 // if d == 15 || BadReg(m) then UNPREDICTABLE;
9620                 if ((d == 15) || BadReg (m))
9621                     return false;
9622                 break;
9623 
9624             case eEncodingA1:
9625                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9626                 d = Bits32 (opcode, 15, 12);
9627                 m = Bits32 (opcode, 3, 0);
9628                 setflags = BitIsSet (opcode, 20);
9629 
9630                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9631                 if (d == 15 && setflags)
9632                     EmulateSUBSPcLrEtc (opcode, encoding);
9633 
9634                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9635                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9636                 break;
9637 
9638             default:
9639                 return false;
9640         }
9641 
9642         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9643         uint32_t Rm = ReadCoreReg (m, &success);
9644         if (!success)
9645             return false;
9646 
9647         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9648         if (!success)
9649             return false;
9650 
9651         // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9652         uint32_t sp_val = ReadCoreReg (SP_REG, &success);
9653         if (!success)
9654             return false;
9655 
9656         AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1);
9657 
9658         EmulateInstruction::Context context;
9659         context.type = eContextArithmetic;
9660         RegisterInfo sp_reg;
9661         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
9662         RegisterInfo dwarf_reg;
9663         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
9664         context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
9665 
9666         if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9667             return false;
9668     }
9669     return true;
9670 }
9671 
9672 
9673 // A8.6.7 ADD (register-shifted register)
9674 bool
9675 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding)
9676 {
9677 #if 0
9678     if ConditionPassed() then
9679         EncodingSpecificOperations();
9680         shift_n = UInt(R[s]<7:0>);
9681         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9682         (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9683         R[d] = result;
9684         if setflags then
9685             APSR.N = result<31>;
9686             APSR.Z = IsZeroBit(result);
9687             APSR.C = carry;
9688             APSR.V = overflow;
9689 #endif
9690 
9691     bool success = false;
9692 
9693     if (ConditionPassed(opcode))
9694     {
9695         uint32_t d;
9696         uint32_t n;
9697         uint32_t m;
9698         uint32_t s;
9699         bool setflags;
9700         ARM_ShifterType shift_t;
9701 
9702         switch (encoding)
9703         {
9704             case eEncodingA1:
9705                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
9706                 d = Bits32 (opcode, 15, 12);
9707                 n = Bits32 (opcode, 19, 16);
9708                 m = Bits32 (opcode, 3, 0);
9709                 s = Bits32 (opcode, 11, 8);
9710 
9711                 // setflags = (S == �1�); shift_t = DecodeRegShift(type);
9712                 setflags = BitIsSet (opcode, 20);
9713                 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5));
9714 
9715                 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
9716                 if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
9717                     return false;
9718                 break;
9719 
9720             default:
9721                 return false;
9722         }
9723 
9724         // shift_n = UInt(R[s]<7:0>);
9725         uint32_t Rs = ReadCoreReg (s, &success);
9726         if (!success)
9727             return false;
9728 
9729         uint32_t shift_n = Bits32 (Rs, 7, 0);
9730 
9731         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9732         uint32_t Rm = ReadCoreReg (m, &success);
9733         if (!success)
9734             return false;
9735 
9736         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9737         if (!success)
9738             return false;
9739 
9740         // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9741         uint32_t Rn = ReadCoreReg (n, &success);
9742         if (!success)
9743             return false;
9744 
9745         AddWithCarryResult res = AddWithCarry (Rn, shifted, 0);
9746 
9747         // R[d] = result;
9748         EmulateInstruction::Context context;
9749         context.type = eContextArithmetic;
9750         RegisterInfo reg_n;
9751         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9752         RegisterInfo reg_m;
9753         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9754 
9755         context.SetRegisterRegisterOperands (reg_n, reg_m);
9756 
9757         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result))
9758             return false;
9759 
9760         // if setflags then
9761             // APSR.N = result<31>;
9762             // APSR.Z = IsZeroBit(result);
9763             // APSR.C = carry;
9764             // APSR.V = overflow;
9765         if (setflags)
9766             return WriteFlags (context, res.result, res.carry_out, res.overflow);
9767     }
9768     return true;
9769 }
9770 
9771 // A8.6.213 SUB (register)
9772 bool
9773 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding)
9774 {
9775 #if 0
9776     if ConditionPassed() then
9777         EncodingSpecificOperations();
9778         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9779         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9780         if d == 15 then // Can only occur for ARM encoding
9781             ALUWritePC(result); // setflags is always FALSE here
9782         else
9783             R[d] = result;
9784             if setflags then
9785                 APSR.N = result<31>;
9786                 APSR.Z = IsZeroBit(result);
9787                 APSR.C = carry;
9788                 APSR.V = overflow;
9789 #endif
9790 
9791     bool success = false;
9792 
9793     if (ConditionPassed(opcode))
9794     {
9795         uint32_t d;
9796         uint32_t n;
9797         uint32_t m;
9798         bool setflags;
9799         ARM_ShifterType shift_t;
9800         uint32_t shift_n;
9801 
9802         switch (encoding)
9803         {
9804             case eEncodingT1:
9805                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
9806                 d = Bits32 (opcode, 2, 0);
9807                 n = Bits32 (opcode, 5, 3);
9808                 m = Bits32 (opcode, 8, 6);
9809                 setflags = !InITBlock();
9810 
9811                 // (shift_t, shift_n) = (SRType_LSL, 0);
9812                 shift_t = SRType_LSL;
9813                 shift_n = 0;
9814 
9815                 break;
9816 
9817             case eEncodingT2:
9818                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1");
9819                 d = Bits32 (opcode, 11, 8);
9820                 n = Bits32 (opcode, 19, 16);
9821                 m = Bits32 (opcode, 3, 0);
9822                 setflags = BitIsSet (opcode, 20);
9823 
9824                 // if Rd == "1111" && S == "1" then SEE CMP (register);
9825                 if (d == 15 && setflags == 1)
9826                     return EmulateCMPImm (opcode, eEncodingT3);
9827 
9828                 // if Rn == "1101" then SEE SUB (SP minus register);
9829                 if (n == 13)
9830                     return EmulateSUBSPReg (opcode, eEncodingT1);
9831 
9832                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9833                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9834 
9835                 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE;
9836                 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m))
9837                     return false;
9838 
9839                 break;
9840 
9841             case eEncodingA1:
9842                 // if Rn == �1101� then SEE SUB (SP minus register);
9843                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9844                 d = Bits32 (opcode, 15, 12);
9845                 n = Bits32 (opcode, 19, 16);
9846                 m = Bits32 (opcode, 3, 0);
9847                 setflags = BitIsSet (opcode, 20);
9848 
9849                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9850                 if ((d == 15) && setflags)
9851                     EmulateSUBSPcLrEtc (opcode, encoding);
9852 
9853                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9854                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9855 
9856                 break;
9857 
9858             default:
9859                 return false;
9860         }
9861 
9862         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9863         uint32_t Rm = ReadCoreReg (m, &success);
9864         if (!success)
9865             return false;
9866 
9867         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9868         if (!success)
9869             return false;
9870 
9871         // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9872         uint32_t Rn = ReadCoreReg (n, &success);
9873         if (!success)
9874             return false;
9875 
9876         AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1);
9877 
9878         // if d == 15 then // Can only occur for ARM encoding
9879             // ALUWritePC(result); // setflags is always FALSE here
9880         // else
9881             // R[d] = result;
9882             // if setflags then
9883                 // APSR.N = result<31>;
9884                 // APSR.Z = IsZeroBit(result);
9885                 // APSR.C = carry;
9886                 // APSR.V = overflow;
9887 
9888         EmulateInstruction::Context context;
9889         context.type = eContextArithmetic;
9890         RegisterInfo reg_n;
9891         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9892         RegisterInfo reg_m;
9893         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9894         context.SetRegisterRegisterOperands (reg_n, reg_m);
9895 
9896         if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9897             return false;
9898     }
9899     return true;
9900 }
9901 
9902 // A8.6.202 STREX
9903 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a
9904 // word from a register to memory if the executing processor has exclusive access to the memory addressed.
9905 bool
9906 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding)
9907 {
9908 #if 0
9909     if ConditionPassed() then
9910         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9911         address = R[n] + imm32;
9912         if ExclusiveMonitorsPass(address,4) then
9913             MemA[address,4] = R[t];
9914             R[d] = 0;
9915         else
9916             R[d] = 1;
9917 #endif
9918 
9919     bool success = false;
9920 
9921     if (ConditionPassed(opcode))
9922     {
9923         uint32_t d;
9924         uint32_t t;
9925         uint32_t n;
9926         uint32_t imm32;
9927         const uint32_t addr_byte_size = GetAddressByteSize();
9928 
9929         switch (encoding)
9930         {
9931             case eEncodingT1:
9932                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
9933                 d = Bits32 (opcode, 11, 8);
9934                 t = Bits32 (opcode, 15, 12);
9935                 n = Bits32 (opcode, 19, 16);
9936                 imm32 = Bits32 (opcode, 7, 0) << 2;
9937 
9938                 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
9939                 if (BadReg (d) || BadReg (t) || (n == 15))
9940                   return false;
9941 
9942                 // if d == n || d == t then UNPREDICTABLE;
9943                 if ((d == n) || (d == t))
9944                   return false;
9945 
9946                 break;
9947 
9948             case eEncodingA1:
9949                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset
9950                 d = Bits32 (opcode, 15, 12);
9951                 t = Bits32 (opcode, 3, 0);
9952                 n = Bits32 (opcode, 19, 16);
9953                 imm32 = 0;
9954 
9955                 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
9956                 if ((d == 15) || (t == 15) || (n == 15))
9957                     return false;
9958 
9959                 // if d == n || d == t then UNPREDICTABLE;
9960                 if ((d == n) || (d == t))
9961                     return false;
9962 
9963                 break;
9964 
9965             default:
9966                 return false;
9967         }
9968 
9969         // address = R[n] + imm32;
9970         uint32_t Rn = ReadCoreReg (n, &success);
9971         if (!success)
9972             return false;
9973 
9974         addr_t address = Rn + imm32;
9975 
9976         RegisterInfo base_reg;
9977         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9978         RegisterInfo data_reg;
9979         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9980         EmulateInstruction::Context context;
9981         context.type = eContextRegisterStore;
9982         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32);
9983 
9984         // if ExclusiveMonitorsPass(address,4) then
9985         // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this
9986         //                                                         always return true.
9987         if (true)
9988         {
9989             // MemA[address,4] = R[t];
9990             uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
9991             if (!success)
9992                 return false;
9993 
9994             if (!MemAWrite (context, address, Rt, addr_byte_size))
9995                 return false;
9996 
9997             // R[d] = 0;
9998             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0))
9999                 return false;
10000         }
10001 #if 0 // unreachable because if true
10002         else
10003         {
10004             // R[d] = 1;
10005             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
10006                 return false;
10007         }
10008 #endif // unreachable because if true
10009     }
10010     return true;
10011 }
10012 
10013 // A8.6.197 STRB (immediate, ARM)
10014 bool
10015 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding)
10016 {
10017 #if 0
10018     if ConditionPassed() then
10019         EncodingSpecificOperations();
10020         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10021         address = if index then offset_addr else R[n];
10022         MemU[address,1] = R[t]<7:0>;
10023         if wback then R[n] = offset_addr;
10024 #endif
10025 
10026     bool success = false;
10027 
10028     if (ConditionPassed(opcode))
10029     {
10030         uint32_t t;
10031         uint32_t n;
10032         uint32_t imm32;
10033         bool index;
10034         bool add;
10035         bool wback;
10036 
10037         switch (encoding)
10038         {
10039             case eEncodingA1:
10040                 // if P == �0� && W == �1� then SEE STRBT;
10041                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10042                 t = Bits32 (opcode, 15, 12);
10043                 n = Bits32 (opcode, 19, 16);
10044                 imm32 = Bits32 (opcode, 11, 0);
10045 
10046                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10047                 index = BitIsSet (opcode, 24);
10048                 add = BitIsSet (opcode, 23);
10049                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10050 
10051                 // if t == 15 then UNPREDICTABLE;
10052                 if (t == 15)
10053                     return false;
10054 
10055                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10056                 if (wback && ((n == 15) || (n == t)))
10057                     return false;
10058 
10059                 break;
10060 
10061             default:
10062                 return false;
10063         }
10064 
10065         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10066         uint32_t Rn = ReadCoreReg (n, &success);
10067         if (!success)
10068             return false;
10069 
10070         addr_t offset_addr;
10071         if (add)
10072             offset_addr = Rn + imm32;
10073         else
10074             offset_addr = Rn - imm32;
10075 
10076         // address = if index then offset_addr else R[n];
10077         addr_t address;
10078         if (index)
10079             address = offset_addr;
10080         else
10081             address = Rn;
10082 
10083         // MemU[address,1] = R[t]<7:0>;
10084         uint32_t Rt = ReadCoreReg (t, &success);
10085         if (!success)
10086             return false;
10087 
10088         RegisterInfo base_reg;
10089         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10090         RegisterInfo data_reg;
10091         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10092         EmulateInstruction::Context context;
10093         context.type = eContextRegisterStore;
10094         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10095 
10096         if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1))
10097             return false;
10098 
10099         // if wback then R[n] = offset_addr;
10100         if (wback)
10101         {
10102             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10103                 return false;
10104         }
10105     }
10106     return true;
10107 }
10108 
10109 // A8.6.194 STR (immediate, ARM)
10110 bool
10111 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding)
10112 {
10113 #if 0
10114     if ConditionPassed() then
10115         EncodingSpecificOperations();
10116         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10117         address = if index then offset_addr else R[n];
10118         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10119         if wback then R[n] = offset_addr;
10120 #endif
10121 
10122     bool success = false;
10123 
10124     if (ConditionPassed(opcode))
10125     {
10126         uint32_t t;
10127         uint32_t n;
10128         uint32_t imm32;
10129         bool index;
10130         bool add;
10131         bool wback;
10132 
10133         const uint32_t addr_byte_size = GetAddressByteSize();
10134 
10135         switch (encoding)
10136         {
10137             case eEncodingA1:
10138                 // if P == �0� && W == �1� then SEE STRT;
10139                 // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH;
10140                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10141                 t = Bits32 (opcode, 15, 12);
10142                 n = Bits32 (opcode, 19, 16);
10143                 imm32 = Bits32 (opcode, 11, 0);
10144 
10145                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10146                 index = BitIsSet (opcode, 24);
10147                 add = BitIsSet (opcode, 23);
10148                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10149 
10150                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10151                 if (wback && ((n == 15) || (n == t)))
10152                     return false;
10153 
10154                 break;
10155 
10156             default:
10157                 return false;
10158         }
10159 
10160         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10161         uint32_t Rn = ReadCoreReg (n, &success);
10162         if (!success)
10163             return false;
10164 
10165         addr_t offset_addr;
10166         if (add)
10167             offset_addr = Rn + imm32;
10168         else
10169             offset_addr = Rn - imm32;
10170 
10171         // address = if index then offset_addr else R[n];
10172         addr_t address;
10173         if (index)
10174             address = offset_addr;
10175         else
10176             address = Rn;
10177 
10178         RegisterInfo base_reg;
10179         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10180         RegisterInfo data_reg;
10181         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10182         EmulateInstruction::Context context;
10183         context.type = eContextRegisterStore;
10184         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10185 
10186         // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10187         uint32_t Rt = ReadCoreReg (t, &success);
10188         if (!success)
10189             return false;
10190 
10191         if (t == 15)
10192         {
10193             uint32_t pc_value = ReadCoreReg (PC_REG, &success);
10194             if (!success)
10195                 return false;
10196 
10197             if (!MemUWrite (context, address, pc_value, addr_byte_size))
10198                 return false;
10199         }
10200         else
10201         {
10202             if (!MemUWrite (context, address, Rt, addr_byte_size))
10203                   return false;
10204         }
10205 
10206         // if wback then R[n] = offset_addr;
10207         if (wback)
10208         {
10209             context.type = eContextAdjustBaseRegister;
10210             context.SetImmediate (offset_addr);
10211 
10212             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10213                 return false;
10214         }
10215     }
10216     return true;
10217 }
10218 
10219 // A8.6.66 LDRD (immediate)
10220 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two
10221 // words from memory, and writes them to two registers.  It can use offset, post-indexed, or pre-indexed addressing.
10222 bool
10223 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding)
10224 {
10225 #if 0
10226     if ConditionPassed() then
10227         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10228         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10229         address = if index then offset_addr else R[n];
10230         R[t] = MemA[address,4];
10231         R[t2] = MemA[address+4,4];
10232         if wback then R[n] = offset_addr;
10233 #endif
10234 
10235     bool success = false;
10236 
10237     if (ConditionPassed(opcode))
10238     {
10239         uint32_t t;
10240         uint32_t t2;
10241         uint32_t n;
10242         uint32_t imm32;
10243         bool index;
10244         bool add;
10245         bool wback;
10246 
10247         switch (encoding)
10248         {
10249             case eEncodingT1:
10250                 //if P == �0� && W == �0� then SEE �Related encodings�;
10251                 //if Rn == �1111� then SEE LDRD (literal);
10252                 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10253                 t = Bits32 (opcode, 15, 12);
10254                 t2 = Bits32 (opcode, 11, 8);
10255                 n = Bits32 (opcode, 19, 16);
10256                 imm32 = Bits32 (opcode, 7, 0) << 2;
10257 
10258                 //index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10259                 index = BitIsSet (opcode, 24);
10260                 add = BitIsSet (opcode, 23);
10261                 wback = BitIsSet (opcode, 21);
10262 
10263                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10264                 if (wback && ((n == t) || (n == t2)))
10265                     return false;
10266 
10267                 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10268                 if (BadReg (t) || BadReg (t2) || (t == t2))
10269                     return false;
10270 
10271                 break;
10272 
10273             case eEncodingA1:
10274                 //if Rn == �1111� then SEE LDRD (literal);
10275                 //if Rt<0> == �1� then UNPREDICTABLE;
10276                 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10277                 t = Bits32 (opcode, 15, 12);
10278                 if (BitIsSet (t, 0))
10279                     return false;
10280                 t2 = t + 1;
10281                 n = Bits32 (opcode, 19, 16);
10282                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10283 
10284                 //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10285                 index = BitIsSet (opcode, 24);
10286                 add = BitIsSet (opcode, 23);
10287                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10288 
10289                 //if P == �0� && W == �1� then UNPREDICTABLE;
10290                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10291                     return false;
10292 
10293                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10294                 if (wback && ((n == t) || (n == t2)))
10295                     return false;
10296 
10297                 //if t2 == 15 then UNPREDICTABLE;
10298                 if (t2 == 15)
10299                     return false;
10300 
10301                 break;
10302 
10303             default:
10304                 return false;
10305         }
10306 
10307         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10308         uint32_t Rn = ReadCoreReg (n, &success);
10309         if (!success)
10310             return false;
10311 
10312         addr_t offset_addr;
10313         if (add)
10314                   offset_addr = Rn + imm32;
10315         else
10316             offset_addr = Rn - imm32;
10317 
10318         //address = if index then offset_addr else R[n];
10319         addr_t address;
10320         if (index)
10321             address = offset_addr;
10322         else
10323             address = Rn;
10324 
10325         //R[t] = MemA[address,4];
10326         RegisterInfo base_reg;
10327         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10328 
10329         EmulateInstruction::Context context;
10330         context.type = eContextRegisterLoad;
10331         context.SetRegisterPlusOffset (base_reg, address - Rn);
10332 
10333         const uint32_t addr_byte_size = GetAddressByteSize();
10334         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10335         if (!success)
10336             return false;
10337 
10338         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10339             return false;
10340 
10341         //R[t2] = MemA[address+4,4];
10342 
10343         context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10344         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10345         if (!success)
10346             return false;
10347 
10348         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10349             return false;
10350 
10351         //if wback then R[n] = offset_addr;
10352         if (wback)
10353         {
10354             context.type = eContextAdjustBaseRegister;
10355             context.SetAddress (offset_addr);
10356 
10357             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10358                 return false;
10359         }
10360     }
10361     return true;
10362 }
10363 
10364 // A8.6.68 LDRD (register)
10365 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two
10366 // words from memory, and writes them to two registers.  It can use offset, post-indexed or pre-indexed addressing.
10367 bool
10368 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding)
10369 {
10370 #if 0
10371     if ConditionPassed() then
10372         EncodingSpecificOperations();
10373         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10374         address = if index then offset_addr else R[n];
10375         R[t] = MemA[address,4];
10376         R[t2] = MemA[address+4,4];
10377         if wback then R[n] = offset_addr;
10378 #endif
10379 
10380     bool success = false;
10381 
10382     if (ConditionPassed(opcode))
10383     {
10384         uint32_t t;
10385         uint32_t t2;
10386         uint32_t n;
10387         uint32_t m;
10388         bool index;
10389         bool add;
10390         bool wback;
10391 
10392         switch (encoding)
10393         {
10394             case eEncodingA1:
10395                 // if Rt<0> == �1� then UNPREDICTABLE;
10396                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10397                 t = Bits32 (opcode, 15, 12);
10398                 if (BitIsSet (t, 0))
10399                     return false;
10400                 t2 = t + 1;
10401                 n = Bits32 (opcode, 19, 16);
10402                 m = Bits32 (opcode, 3, 0);
10403 
10404                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10405                 index = BitIsSet (opcode, 24);
10406                 add = BitIsSet (opcode, 23);
10407                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10408 
10409                 // if P == �0� && W == �1� then UNPREDICTABLE;
10410                   if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10411                   return false;
10412 
10413                 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10414                   if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10415                   return false;
10416 
10417                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10418                   if (wback && ((n == 15) || (n == t) || (n == t2)))
10419                   return false;
10420 
10421                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10422                 if ((ArchVersion() < 6) && wback && (m == n))
10423                   return false;
10424                 break;
10425 
10426             default:
10427                 return false;
10428         }
10429 
10430         uint32_t Rn = ReadCoreReg (n, &success);
10431         if (!success)
10432             return false;
10433         RegisterInfo base_reg;
10434         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10435 
10436         uint32_t Rm = ReadCoreReg (m, &success);
10437         if (!success)
10438             return false;
10439         RegisterInfo offset_reg;
10440         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10441 
10442         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10443         addr_t offset_addr;
10444         if (add)
10445             offset_addr = Rn + Rm;
10446         else
10447             offset_addr = Rn - Rm;
10448 
10449         // address = if index then offset_addr else R[n];
10450         addr_t address;
10451         if (index)
10452             address = offset_addr;
10453         else
10454             address = Rn;
10455 
10456         EmulateInstruction::Context context;
10457         context.type = eContextRegisterLoad;
10458         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
10459 
10460         // R[t] = MemA[address,4];
10461         const uint32_t addr_byte_size = GetAddressByteSize();
10462         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10463         if (!success)
10464             return false;
10465 
10466         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10467             return false;
10468 
10469         // R[t2] = MemA[address+4,4];
10470 
10471         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10472         if (!success)
10473             return false;
10474 
10475         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10476             return false;
10477 
10478         // if wback then R[n] = offset_addr;
10479         if (wback)
10480         {
10481             context.type = eContextAdjustBaseRegister;
10482             context.SetAddress (offset_addr);
10483 
10484             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10485                 return false;
10486         }
10487     }
10488     return true;
10489 }
10490 
10491 // A8.6.200 STRD (immediate)
10492 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and
10493 // stores two words from two registers to memory.  It can use offset, post-indexed, or pre-indexed addressing.
10494 bool
10495 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding)
10496 {
10497 #if 0
10498     if ConditionPassed() then
10499         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10500         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10501         address = if index then offset_addr else R[n];
10502         MemA[address,4] = R[t];
10503         MemA[address+4,4] = R[t2];
10504         if wback then R[n] = offset_addr;
10505 #endif
10506 
10507     bool success = false;
10508 
10509     if (ConditionPassed(opcode))
10510     {
10511         uint32_t t;
10512         uint32_t t2;
10513         uint32_t n;
10514         uint32_t imm32;
10515         bool index;
10516         bool add;
10517         bool wback;
10518 
10519         switch (encoding)
10520         {
10521             case eEncodingT1:
10522                 // if P == �0� && W == �0� then SEE �Related encodings�;
10523                 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10524                 t = Bits32 (opcode, 15, 12);
10525                 t2 = Bits32 (opcode, 11, 8);
10526                 n = Bits32 (opcode, 19, 16);
10527                 imm32 = Bits32 (opcode, 7, 0) << 2;
10528 
10529                 // index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10530                 index = BitIsSet (opcode, 24);
10531                 add = BitIsSet (opcode, 23);
10532                 wback = BitIsSet (opcode, 21);
10533 
10534                 // if wback && (n == t || n == t2) then UNPREDICTABLE;
10535                 if (wback && ((n == t) || (n == t2)))
10536                     return false;
10537 
10538                 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10539                 if ((n == 15) || BadReg (t) || BadReg (t2))
10540                     return false;
10541 
10542                 break;
10543 
10544             case eEncodingA1:
10545                 // if Rt<0> == �1� then UNPREDICTABLE;
10546                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10547                 t = Bits32 (opcode, 15, 12);
10548                 if (BitIsSet (t, 0))
10549                     return false;
10550 
10551                 t2 = t + 1;
10552                 n = Bits32 (opcode, 19, 16);
10553                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10554 
10555                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10556                 index = BitIsSet (opcode, 24);
10557                 add = BitIsSet (opcode, 23);
10558                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10559 
10560                 // if P == �0� && W == �1� then UNPREDICTABLE;
10561                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10562                     return false;
10563 
10564                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10565                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10566                     return false;
10567 
10568                 // if t2 == 15 then UNPREDICTABLE;
10569                 if (t2 == 15)
10570                     return false;
10571 
10572                 break;
10573 
10574             default:
10575                 return false;
10576         }
10577 
10578         RegisterInfo base_reg;
10579         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10580 
10581         uint32_t Rn = ReadCoreReg (n, &success);
10582         if (!success)
10583             return false;
10584 
10585         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10586         addr_t offset_addr;
10587         if (add)
10588             offset_addr = Rn + imm32;
10589         else
10590             offset_addr = Rn - imm32;
10591 
10592         //address = if index then offset_addr else R[n];
10593         addr_t address;
10594         if (index)
10595             address = offset_addr;
10596         else
10597             address = Rn;
10598 
10599         //MemA[address,4] = R[t];
10600         RegisterInfo data_reg;
10601         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10602 
10603         uint32_t data = ReadCoreReg (t, &success);
10604         if (!success)
10605             return false;
10606 
10607         EmulateInstruction::Context context;
10608         context.type = eContextRegisterStore;
10609         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10610 
10611         const uint32_t addr_byte_size = GetAddressByteSize();
10612 
10613         if (!MemAWrite (context, address, data, addr_byte_size))
10614             return false;
10615 
10616         //MemA[address+4,4] = R[t2];
10617         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10618         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10619 
10620         data = ReadCoreReg (t2, &success);
10621         if (!success)
10622             return false;
10623 
10624         if (!MemAWrite (context, address + 4, data, addr_byte_size))
10625             return false;
10626 
10627         //if wback then R[n] = offset_addr;
10628         if (wback)
10629         {
10630             context.type = eContextAdjustBaseRegister;
10631             context.SetAddress (offset_addr);
10632 
10633             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10634                 return false;
10635         }
10636     }
10637     return true;
10638 }
10639 
10640 
10641 // A8.6.201 STRD (register)
10642 bool
10643 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding)
10644 {
10645 #if 0
10646     if ConditionPassed() then
10647         EncodingSpecificOperations();
10648         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10649         address = if index then offset_addr else R[n];
10650         MemA[address,4] = R[t];
10651         MemA[address+4,4] = R[t2];
10652         if wback then R[n] = offset_addr;
10653 #endif
10654 
10655     bool success = false;
10656 
10657     if (ConditionPassed(opcode))
10658     {
10659         uint32_t t;
10660         uint32_t t2;
10661         uint32_t n;
10662         uint32_t m;
10663         bool index;
10664         bool add;
10665         bool wback;
10666 
10667         switch (encoding)
10668         {
10669             case eEncodingA1:
10670                 // if Rt<0> == �1� then UNPREDICTABLE;
10671                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10672                 t = Bits32 (opcode, 15, 12);
10673                 if (BitIsSet (t, 0))
10674                    return false;
10675 
10676                 t2 = t+1;
10677                 n = Bits32 (opcode, 19, 16);
10678                 m = Bits32 (opcode, 3, 0);
10679 
10680                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10681                 index = BitIsSet (opcode, 24);
10682                 add = BitIsSet (opcode, 23);
10683                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10684 
10685                 // if P == �0� && W == �1� then UNPREDICTABLE;
10686                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10687                    return false;
10688 
10689                 // if t2 == 15 || m == 15 then UNPREDICTABLE;
10690                 if ((t2 == 15) || (m == 15))
10691                    return false;
10692 
10693                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10694                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10695                    return false;
10696 
10697                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10698                 if ((ArchVersion() < 6) && wback && (m == n))
10699                    return false;
10700 
10701                 break;
10702 
10703             default:
10704                 return false;
10705         }
10706 
10707         RegisterInfo base_reg;
10708         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10709         RegisterInfo offset_reg;
10710         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10711         RegisterInfo data_reg;
10712 
10713         uint32_t Rn = ReadCoreReg (n, &success);
10714         if (!success)
10715             return false;
10716 
10717         uint32_t Rm = ReadCoreReg (m, &success);
10718         if (!success)
10719             return false;
10720 
10721         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10722         addr_t offset_addr;
10723         if (add)
10724             offset_addr = Rn + Rm;
10725         else
10726             offset_addr = Rn - Rm;
10727 
10728         // address = if index then offset_addr else R[n];
10729         addr_t address;
10730         if (index)
10731             address = offset_addr;
10732         else
10733             address = Rn;
10734                           // MemA[address,4] = R[t];
10735         uint32_t Rt = ReadCoreReg (t, &success);
10736         if (!success)
10737             return false;
10738 
10739         EmulateInstruction::Context context;
10740         context.type = eContextRegisterStore;
10741         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10742         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10743 
10744         const uint32_t addr_byte_size = GetAddressByteSize();
10745 
10746         if (!MemAWrite (context, address, Rt, addr_byte_size))
10747             return false;
10748 
10749         // MemA[address+4,4] = R[t2];
10750         uint32_t Rt2 = ReadCoreReg (t2, &success);
10751         if (!success)
10752             return false;
10753 
10754         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10755 
10756         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10757 
10758         if (!MemAWrite (context, address + 4, Rt2, addr_byte_size))
10759             return false;
10760 
10761         // if wback then R[n] = offset_addr;
10762         if (wback)
10763         {
10764             context.type = eContextAdjustBaseRegister;
10765             context.SetAddress (offset_addr);
10766 
10767             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10768                 return false;
10769 
10770         }
10771     }
10772     return true;
10773 }
10774 
10775 // A8.6.319 VLDM
10776 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from
10777 // an ARM core register.
10778 bool
10779 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding)
10780 {
10781 #if 0
10782     if ConditionPassed() then
10783         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10784         address = if add then R[n] else R[n]-imm32;
10785         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10786         for r = 0 to regs-1
10787             if single_regs then
10788                 S[d+r] = MemA[address,4]; address = address+4;
10789             else
10790                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10791                 // Combine the word-aligned words in the correct order for current endianness.
10792                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10793 #endif
10794 
10795     bool success = false;
10796 
10797     if (ConditionPassed(opcode))
10798     {
10799         bool single_regs;
10800         bool add;
10801         bool wback;
10802         uint32_t d;
10803         uint32_t n;
10804         uint32_t imm32;
10805         uint32_t regs;
10806 
10807         switch (encoding)
10808         {
10809             case eEncodingT1:
10810             case eEncodingA1:
10811                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10812                 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10813                 // if P == �1� && W == �0� then SEE VLDR;
10814                 // if P == U && W == �1� then UNDEFINED;
10815                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10816                     return false;
10817 
10818                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10819                 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10820                 single_regs = false;
10821                 add = BitIsSet (opcode, 23);
10822                 wback = BitIsSet (opcode, 21);
10823 
10824                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10825                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10826                 n = Bits32 (opcode, 19, 16);
10827                 imm32 = Bits32 (opcode, 7, 0) << 2;
10828 
10829                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�.
10830                 regs = Bits32 (opcode, 7, 0) / 2;
10831 
10832                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10833                 if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
10834                     return false;
10835 
10836                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10837                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10838                     return false;
10839 
10840                 break;
10841 
10842             case eEncodingT2:
10843             case eEncodingA2:
10844                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10845                 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10846                 // if P == �1� && W == �0� then SEE VLDR;
10847                 // if P == U && W == �1� then UNDEFINED;
10848                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10849                     return false;
10850 
10851                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10852                 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10853                 single_regs = true;
10854                 add = BitIsSet (opcode, 23);
10855                 wback = BitIsSet (opcode, 21);
10856                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10857                 n = Bits32 (opcode, 19, 16);
10858 
10859                 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10860                 imm32 = Bits32 (opcode, 7, 0) << 2;
10861                 regs = Bits32 (opcode, 7, 0);
10862 
10863                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10864                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10865                     return false;
10866 
10867                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10868                 if ((regs == 0) || ((d + regs) > 32))
10869                     return false;
10870                 break;
10871 
10872             default:
10873                 return false;
10874         }
10875 
10876         RegisterInfo base_reg;
10877         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10878 
10879         uint32_t Rn = ReadCoreReg (n, &success);
10880         if (!success)
10881             return false;
10882 
10883         // address = if add then R[n] else R[n]-imm32;
10884         addr_t address;
10885         if (add)
10886             address = Rn;
10887         else
10888             address = Rn - imm32;
10889 
10890         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10891         EmulateInstruction::Context context;
10892 
10893         if (wback)
10894         {
10895             uint32_t value;
10896             if (add)
10897                 value = Rn + imm32;
10898             else
10899                 value = Rn - imm32;
10900 
10901             context.type = eContextAdjustBaseRegister;
10902             context.SetImmediateSigned (value - Rn);
10903             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10904                 return false;
10905 
10906         }
10907 
10908         const uint32_t addr_byte_size = GetAddressByteSize();
10909         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10910 
10911         context.type = eContextRegisterLoad;
10912 
10913         // for r = 0 to regs-1
10914         for (uint32_t r = 0; r < regs; ++r)
10915         {
10916             if (single_regs)
10917             {
10918                 // S[d+r] = MemA[address,4]; address = address+4;
10919                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10920 
10921                 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10922                 if (!success)
10923                     return false;
10924 
10925                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10926                     return false;
10927 
10928                 address = address + 4;
10929             }
10930             else
10931             {
10932                 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10933                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10934                 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10935                 if (!success)
10936                     return false;
10937 
10938                 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10939                 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10940                 if (!success)
10941                     return false;
10942 
10943                 address = address + 8;
10944                 // // Combine the word-aligned words in the correct order for current endianness.
10945                 // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10946                 uint64_t data;
10947                 if (GetByteOrder() == eByteOrderBig)
10948                 {
10949                     data = word1;
10950                     data = (data << 32) | word2;
10951                 }
10952                 else
10953                 {
10954                     data = word2;
10955                     data = (data << 32) | word1;
10956                 }
10957 
10958                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10959                     return false;
10960             }
10961         }
10962     }
10963     return true;
10964 }
10965 
10966 // A8.6.399 VSTM
10967 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an
10968 // ARM core register.
10969 bool
10970 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding)
10971 {
10972 #if 0
10973     if ConditionPassed() then
10974         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10975         address = if add then R[n] else R[n]-imm32;
10976         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10977         for r = 0 to regs-1
10978             if single_regs then
10979                 MemA[address,4] = S[d+r]; address = address+4;
10980             else
10981                 // Store as two word-aligned words in the correct order for current endianness.
10982                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10983                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10984                 address = address+8;
10985 #endif
10986 
10987     bool success = false;
10988 
10989     if (ConditionPassed (opcode))
10990     {
10991         bool single_regs;
10992         bool add;
10993         bool wback;
10994         uint32_t d;
10995         uint32_t n;
10996         uint32_t imm32;
10997         uint32_t regs;
10998 
10999         switch (encoding)
11000         {
11001             case eEncodingT1:
11002             case eEncodingA1:
11003                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
11004                 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
11005                 // if P == �1� && W == �0� then SEE VSTR;
11006                 // if P == U && W == �1� then UNDEFINED;
11007                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
11008                     return false;
11009 
11010                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
11011                 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
11012                 single_regs = false;
11013                 add = BitIsSet (opcode, 23);
11014                 wback = BitIsSet (opcode, 21);
11015 
11016                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
11017                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11018                 n = Bits32 (opcode, 19, 16);
11019                 imm32 = Bits32 (opcode, 7, 0) << 2;
11020 
11021                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�.
11022                 regs = Bits32 (opcode, 7, 0) / 2;
11023 
11024                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
11025                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11026                     return false;
11027 
11028                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11029                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11030                     return false;
11031 
11032                 break;
11033 
11034             case eEncodingT2:
11035             case eEncodingA2:
11036                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
11037                 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
11038                 // if P == �1� && W == �0� then SEE VSTR;
11039                 // if P == U && W == �1� then UNDEFINED;
11040                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
11041                     return false;
11042 
11043                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
11044                 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
11045                 single_regs = true;
11046                 add = BitIsSet (opcode, 23);
11047                 wback = BitIsSet (opcode, 21);
11048                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11049                 n = Bits32 (opcode, 19, 16);
11050 
11051                 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
11052                 imm32 = Bits32 (opcode, 7, 0) << 2;
11053                 regs = Bits32 (opcode, 7, 0);
11054 
11055                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
11056                 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM)))
11057                     return false;
11058 
11059                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11060                 if ((regs == 0) || ((d + regs) > 32))
11061                     return false;
11062 
11063                 break;
11064 
11065             default:
11066                 return false;
11067         }
11068 
11069         RegisterInfo base_reg;
11070         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11071 
11072         uint32_t Rn = ReadCoreReg (n, &success);
11073         if (!success)
11074             return false;
11075 
11076         // address = if add then R[n] else R[n]-imm32;
11077         addr_t address;
11078         if (add)
11079             address = Rn;
11080         else
11081             address = Rn - imm32;
11082 
11083         EmulateInstruction::Context context;
11084         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11085         if (wback)
11086         {
11087             uint32_t value;
11088             if (add)
11089                 value = Rn + imm32;
11090             else
11091                 value = Rn - imm32;
11092 
11093             context.type = eContextAdjustBaseRegister;
11094             context.SetRegisterPlusOffset (base_reg, value - Rn);
11095 
11096             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11097                 return false;
11098         }
11099 
11100         const uint32_t addr_byte_size = GetAddressByteSize();
11101         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11102 
11103         context.type = eContextRegisterStore;
11104         // for r = 0 to regs-1
11105         for (uint32_t r = 0; r < regs; ++r)
11106         {
11107 
11108             if (single_regs)
11109             {
11110                 // MemA[address,4] = S[d+r]; address = address+4;
11111                 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
11112                 if (!success)
11113                     return false;
11114 
11115                 RegisterInfo data_reg;
11116                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
11117                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11118                 if (!MemAWrite (context, address, data, addr_byte_size))
11119                     return false;
11120 
11121                 address = address + 4;
11122             }
11123             else
11124             {
11125                 // // Store as two word-aligned words in the correct order for current endianness.
11126                 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
11127                 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
11128                 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
11129                 if (!success)
11130                     return false;
11131 
11132                 RegisterInfo data_reg;
11133                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
11134 
11135                 if (GetByteOrder() == eByteOrderBig)
11136                 {
11137                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11138                     if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11139                         return false;
11140 
11141                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11142                     if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size))
11143                         return false;
11144                 }
11145                 else
11146                 {
11147                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11148                     if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11149                         return false;
11150 
11151                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11152                     if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11153                         return false;
11154                 }
11155                 // address = address+8;
11156                 address = address + 8;
11157             }
11158         }
11159     }
11160     return true;
11161 }
11162 
11163 // A8.6.320
11164 // This instruction loads a single extension register from memory, using an address from an ARM core register, with
11165 // an optional offset.
11166 bool
11167 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
11168 {
11169 #if 0
11170     if ConditionPassed() then
11171         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11172         base = if n == 15 then Align(PC,4) else R[n];
11173         address = if add then (base + imm32) else (base - imm32);
11174         if single_reg then
11175             S[d] = MemA[address,4];
11176         else
11177             word1 = MemA[address,4]; word2 = MemA[address+4,4];
11178             // Combine the word-aligned words in the correct order for current endianness.
11179             D[d] = if BigEndian() then word1:word2 else word2:word1;
11180 #endif
11181 
11182     bool success = false;
11183 
11184     if (ConditionPassed (opcode))
11185     {
11186         bool single_reg;
11187         bool add;
11188         uint32_t imm32;
11189         uint32_t d;
11190         uint32_t n;
11191 
11192         switch (encoding)
11193         {
11194             case eEncodingT1:
11195             case eEncodingA1:
11196                 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11197                 single_reg = false;
11198                 add = BitIsSet (opcode, 23);
11199                 imm32 = Bits32 (opcode, 7, 0) << 2;
11200 
11201                 // d = UInt(D:Vd); n = UInt(Rn);
11202                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11203                 n = Bits32 (opcode, 19, 16);
11204 
11205                 break;
11206 
11207             case eEncodingT2:
11208             case eEncodingA2:
11209                 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11210                 single_reg = true;
11211                 add = BitIsSet (opcode, 23);
11212                 imm32 = Bits32 (opcode, 7, 0) << 2;
11213 
11214                 // d = UInt(Vd:D); n = UInt(Rn);
11215                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11216                 n = Bits32 (opcode, 19, 16);
11217 
11218                 break;
11219 
11220             default:
11221                 return false;
11222         }
11223         RegisterInfo base_reg;
11224         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11225 
11226         uint32_t Rn = ReadCoreReg (n, &success);
11227         if (!success)
11228             return false;
11229 
11230         // base = if n == 15 then Align(PC,4) else R[n];
11231         uint32_t base;
11232         if (n == 15)
11233             base = AlignPC (Rn);
11234         else
11235             base = Rn;
11236 
11237         // address = if add then (base + imm32) else (base - imm32);
11238         addr_t address;
11239         if (add)
11240             address = base + imm32;
11241         else
11242             address = base - imm32;
11243 
11244         const uint32_t addr_byte_size = GetAddressByteSize();
11245         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11246 
11247         EmulateInstruction::Context context;
11248         context.type = eContextRegisterLoad;
11249         context.SetRegisterPlusOffset (base_reg, address - base);
11250 
11251         if (single_reg)
11252         {
11253             // S[d] = MemA[address,4];
11254             uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
11255             if (!success)
11256                 return false;
11257 
11258             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data))
11259                 return false;
11260         }
11261         else
11262         {
11263             // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11264             uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
11265             if (!success)
11266                 return false;
11267 
11268             context.SetRegisterPlusOffset (base_reg, (address + 4) - base);
11269             uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
11270             if (!success)
11271                 return false;
11272             // // Combine the word-aligned words in the correct order for current endianness.
11273             // D[d] = if BigEndian() then word1:word2 else word2:word1;
11274             uint64_t data64;
11275             if (GetByteOrder() == eByteOrderBig)
11276             {
11277                 data64 = word1;
11278                 data64 = (data64 << 32) | word2;
11279             }
11280             else
11281             {
11282                 data64 = word2;
11283                 data64 = (data64 << 32) | word1;
11284             }
11285 
11286             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64))
11287                 return false;
11288         }
11289     }
11290     return true;
11291 }
11292 
11293 // A8.6.400 VSTR
11294 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an
11295 // optional offset.
11296 bool
11297 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
11298 {
11299 #if 0
11300     if ConditionPassed() then
11301         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11302         address = if add then (R[n] + imm32) else (R[n] - imm32);
11303         if single_reg then
11304             MemA[address,4] = S[d];
11305         else
11306             // Store as two word-aligned words in the correct order for current endianness.
11307             MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11308             MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11309 #endif
11310 
11311     bool success = false;
11312 
11313     if (ConditionPassed (opcode))
11314     {
11315         bool single_reg;
11316         bool add;
11317         uint32_t imm32;
11318         uint32_t d;
11319         uint32_t n;
11320 
11321         switch (encoding)
11322         {
11323             case eEncodingT1:
11324             case eEncodingA1:
11325                 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11326                 single_reg = false;
11327                 add = BitIsSet (opcode, 23);
11328                 imm32 = Bits32 (opcode, 7, 0) << 2;
11329 
11330                 // d = UInt(D:Vd); n = UInt(Rn);
11331                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11332                 n = Bits32 (opcode, 19, 16);
11333 
11334                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11335                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11336                     return false;
11337 
11338                 break;
11339 
11340             case eEncodingT2:
11341             case eEncodingA2:
11342                 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11343                 single_reg = true;
11344                 add = BitIsSet (opcode, 23);
11345                 imm32 = Bits32 (opcode, 7, 0) << 2;
11346 
11347                 // d = UInt(Vd:D); n = UInt(Rn);
11348                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11349                 n = Bits32 (opcode, 19, 16);
11350 
11351                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11352                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11353                     return false;
11354 
11355                 break;
11356 
11357             default:
11358                 return false;
11359         }
11360 
11361         RegisterInfo base_reg;
11362         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11363 
11364         uint32_t Rn = ReadCoreReg (n, &success);
11365         if (!success)
11366             return false;
11367 
11368         // address = if add then (R[n] + imm32) else (R[n] - imm32);
11369         addr_t address;
11370         if (add)
11371             address = Rn + imm32;
11372         else
11373             address = Rn - imm32;
11374 
11375         const uint32_t addr_byte_size = GetAddressByteSize();
11376         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11377 
11378         RegisterInfo data_reg;
11379         GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg);
11380         EmulateInstruction::Context context;
11381         context.type = eContextRegisterStore;
11382         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11383 
11384         if (single_reg)
11385         {
11386             // MemA[address,4] = S[d];
11387             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11388             if (!success)
11389                 return false;
11390 
11391             if (!MemAWrite (context, address, data, addr_byte_size))
11392                 return false;
11393         }
11394         else
11395         {
11396             // // Store as two word-aligned words in the correct order for current endianness.
11397             // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11398             // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11399             uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11400             if (!success)
11401                 return false;
11402 
11403             if (GetByteOrder() == eByteOrderBig)
11404             {
11405                 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11406                     return false;
11407 
11408                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11409                 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size))
11410                     return false;
11411             }
11412             else
11413             {
11414                 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11415                     return false;
11416 
11417                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11418                 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11419                     return false;
11420             }
11421         }
11422     }
11423     return true;
11424 }
11425 
11426 // A8.6.307 VLDI1 (multiple single elements)
11427 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving.  Every
11428 // element of each register is loaded.
11429 bool
11430 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding)
11431 {
11432 #if 0
11433     if ConditionPassed() then
11434         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11435         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11436         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11437         for r = 0 to regs-1
11438             for e = 0 to elements-1
11439                 Elem[D[d+r],e,esize] = MemU[address,ebytes];
11440                 address = address + ebytes;
11441 #endif
11442 
11443     bool success = false;
11444 
11445     if (ConditionPassed (opcode))
11446     {
11447         uint32_t regs;
11448         uint32_t alignment;
11449         uint32_t ebytes;
11450         uint32_t esize;
11451         uint32_t elements;
11452         uint32_t d;
11453         uint32_t n;
11454         uint32_t m;
11455         bool wback;
11456         bool register_index;
11457 
11458         switch (encoding)
11459         {
11460             case eEncodingT1:
11461             case eEncodingA1:
11462             {
11463                 // case type of
11464                     // when �0111�
11465                         // regs = 1; if align<1> == �1� then UNDEFINED;
11466                     // when �1010�
11467                         // regs = 2; if align == �11� then UNDEFINED;
11468                     // when �0110�
11469                         // regs = 3; if align<1> == �1� then UNDEFINED;
11470                     // when �0010�
11471                         // regs = 4;
11472                     // otherwise
11473                         // SEE �Related encodings�;
11474                 uint32_t type = Bits32 (opcode, 11, 8);
11475                 uint32_t align = Bits32 (opcode, 5, 4);
11476                 if (type == 7) // '0111'
11477                 {
11478                     regs = 1;
11479                     if (BitIsSet (align, 1))
11480                         return false;
11481                 }
11482                 else if (type == 10) // '1010'
11483                 {
11484                     regs = 2;
11485                     if (align == 3)
11486                         return false;
11487 
11488                 }
11489                 else if (type == 6) // '0110'
11490                 {
11491                     regs = 3;
11492                     if (BitIsSet (align, 1))
11493                         return false;
11494                 }
11495                 else if (type == 2) // '0010'
11496                 {
11497                     regs = 4;
11498                 }
11499                 else
11500                     return false;
11501 
11502                 // alignment = if align == �00� then 1 else 4 << UInt(align);
11503                 if (align == 0)
11504                     alignment = 1;
11505                 else
11506                     alignment = 4 << align;
11507 
11508                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11509                 ebytes = 1 << Bits32 (opcode, 7, 6);
11510                 esize = 8 * ebytes;
11511                 elements = 8 / ebytes;
11512 
11513                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11514                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11515                 n = Bits32 (opcode, 19, 15);
11516                 m = Bits32 (opcode, 3, 0);
11517 
11518                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11519                 wback = (m != 15);
11520                 register_index = ((m != 15) && (m != 13));
11521 
11522                 // if d+regs > 32 then UNPREDICTABLE;
11523                 if ((d + regs) > 32)
11524                     return false;
11525             }
11526                 break;
11527 
11528             default:
11529                 return false;
11530         }
11531 
11532         RegisterInfo base_reg;
11533         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11534 
11535         uint32_t Rn = ReadCoreReg (n, &success);
11536         if (!success)
11537             return false;
11538 
11539         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11540         addr_t address = Rn;
11541         if ((address % alignment) != 0)
11542             return false;
11543 
11544         EmulateInstruction::Context context;
11545         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11546         if (wback)
11547         {
11548             uint32_t Rm = ReadCoreReg (m, &success);
11549             if (!success)
11550                 return false;
11551 
11552             uint32_t offset;
11553             if (register_index)
11554                 offset = Rm;
11555             else
11556                 offset = 8 * regs;
11557 
11558             uint32_t value = Rn + offset;
11559             context.type = eContextAdjustBaseRegister;
11560             context.SetRegisterPlusOffset (base_reg, offset);
11561 
11562             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11563                 return false;
11564 
11565         }
11566 
11567         // for r = 0 to regs-1
11568         for (uint32_t r = 0; r < regs; ++r)
11569         {
11570             // for e = 0 to elements-1
11571             uint64_t assembled_data = 0;
11572             for (uint32_t e = 0; e < elements; ++e)
11573             {
11574                 // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11575                 context.type = eContextRegisterLoad;
11576                 context.SetRegisterPlusOffset (base_reg, address - Rn);
11577                 uint64_t data = MemURead (context, address, ebytes, 0, &success);
11578                 if (!success)
11579                     return false;
11580 
11581                 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data
11582 
11583                 // address = address + ebytes;
11584                 address = address + ebytes;
11585             }
11586             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data))
11587                 return false;
11588         }
11589     }
11590     return true;
11591 }
11592 
11593 // A8.6.308 VLD1 (single element to one lane)
11594 //
11595 bool
11596 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding)
11597 {
11598 #if 0
11599     if ConditionPassed() then
11600         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11601         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11602         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11603         Elem[D[d],index,esize] = MemU[address,ebytes];
11604 #endif
11605 
11606     bool success = false;
11607 
11608     if (ConditionPassed (opcode))
11609     {
11610         uint32_t ebytes;
11611         uint32_t esize;
11612         uint32_t index;
11613         uint32_t alignment;
11614         uint32_t d;
11615         uint32_t n;
11616         uint32_t m;
11617         bool wback;
11618         bool register_index;
11619 
11620         switch (encoding)
11621         {
11622             case eEncodingT1:
11623             case eEncodingA1:
11624             {
11625                 uint32_t size = Bits32 (opcode, 11, 10);
11626                 uint32_t index_align = Bits32 (opcode, 7, 4);
11627                 // if size == �11� then SEE VLD1 (single element to all lanes);
11628                 if (size == 3)
11629                    return EmulateVLD1SingleAll (opcode, encoding);
11630                 // case size of
11631                 if (size == 0) // when '00'
11632                 {
11633                     // if index_align<0> != �0� then UNDEFINED;
11634                     if (BitIsClear (index_align, 0))
11635                         return false;
11636 
11637                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11638                     ebytes = 1;
11639                     esize = 8;
11640                     index = Bits32 (index_align, 3, 1);
11641                     alignment = 1;
11642                 }
11643                 else if (size == 1) // when �01�
11644                 {
11645                     // if index_align<1> != �0� then UNDEFINED;
11646                     if (BitIsClear (index_align, 1))
11647                         return false;
11648 
11649                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11650                     ebytes = 2;
11651                     esize = 16;
11652                     index = Bits32 (index_align, 3, 2);
11653 
11654                     // alignment = if index_align<0> == �0� then 1 else 2;
11655                     if (BitIsClear (index_align, 0))
11656                         alignment = 1;
11657                     else
11658                         alignment = 2;
11659                 }
11660                 else if (size == 2) // when �10�
11661                 {
11662                     // if index_align<2> != �0� then UNDEFINED;
11663                     if (BitIsClear (index_align, 2))
11664                         return false;
11665 
11666                     // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11667                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11668                         return false;
11669 
11670                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11671                     ebytes = 4;
11672                     esize = 32;
11673                     index = Bit32 (index_align, 3);
11674 
11675                     // alignment = if index_align<1:0> == �00� then 1 else 4;
11676                     if (Bits32 (index_align, 1, 0) == 0)
11677                         alignment = 1;
11678                     else
11679                         alignment = 4;
11680                 }
11681                 else
11682                 {
11683                     return false;
11684                 }
11685                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11686                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11687                 n = Bits32 (opcode, 19, 16);
11688                 m = Bits32 (opcode, 3, 0);
11689 
11690                 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
11691                 wback = (m != 15);
11692                 register_index = ((m != 15) && (m != 13));
11693 
11694                 if (n == 15)
11695                     return false;
11696 
11697             }
11698                 break;
11699 
11700             default:
11701                 return false;
11702         }
11703 
11704         RegisterInfo base_reg;
11705         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11706 
11707         uint32_t Rn = ReadCoreReg (n, &success);
11708         if (!success)
11709             return false;
11710 
11711         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11712         addr_t address = Rn;
11713         if ((address % alignment) != 0)
11714             return false;
11715 
11716         EmulateInstruction::Context context;
11717         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11718         if (wback)
11719         {
11720             uint32_t Rm = ReadCoreReg (m, &success);
11721             if (!success)
11722                 return false;
11723 
11724             uint32_t offset;
11725             if (register_index)
11726                 offset = Rm;
11727             else
11728                 offset = ebytes;
11729 
11730             uint32_t value = Rn + offset;
11731 
11732             context.type = eContextAdjustBaseRegister;
11733             context.SetRegisterPlusOffset (base_reg, offset);
11734 
11735             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11736                 return false;
11737         }
11738 
11739         // Elem[D[d],index,esize] = MemU[address,ebytes];
11740         uint32_t element = MemURead (context, address, esize, 0, &success);
11741         if (!success)
11742             return false;
11743 
11744         element = element << (index * esize);
11745 
11746         uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11747         if (!success)
11748             return false;
11749 
11750         uint64_t all_ones = -1;
11751         uint64_t mask = all_ones << ((index+1) * esize);  // mask is all 1's to left of where 'element' goes, & all 0's
11752                                                           // at element & to the right of element.
11753         if (index > 0)
11754             mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes.
11755                                                                      // now mask should be 0's where element goes & 1's
11756                                                                      // everywhere else.
11757 
11758         uint64_t masked_reg = reg_data & mask;  // Take original reg value & zero out 'element' bits
11759         reg_data = masked_reg & element;        // Put 'element' into those bits in reg_data.
11760 
11761         context.type = eContextRegisterLoad;
11762         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data))
11763             return false;
11764     }
11765     return true;
11766 }
11767 
11768 // A8.6.391 VST1 (multiple single elements)
11769 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four registers, without
11770 // interleaving.  Every element of each register is stored.
11771 bool
11772 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding)
11773 {
11774 #if 0
11775     if ConditionPassed() then
11776         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11777         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11778         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11779         for r = 0 to regs-1
11780             for e = 0 to elements-1
11781                 MemU[address,ebytes] = Elem[D[d+r],e,esize];
11782                 address = address + ebytes;
11783 #endif
11784 
11785     bool success = false;
11786 
11787     if (ConditionPassed (opcode))
11788     {
11789         uint32_t regs;
11790         uint32_t alignment;
11791         uint32_t ebytes;
11792         uint32_t esize;
11793         uint32_t elements;
11794         uint32_t d;
11795         uint32_t n;
11796         uint32_t m;
11797         bool wback;
11798         bool register_index;
11799 
11800         switch (encoding)
11801         {
11802             case eEncodingT1:
11803             case eEncodingA1:
11804             {
11805                 uint32_t type = Bits32 (opcode, 11, 8);
11806                 uint32_t align = Bits32 (opcode, 5, 4);
11807 
11808                 // case type of
11809                 if (type == 7)    // when �0111�
11810                 {
11811                     // regs = 1; if align<1> == �1� then UNDEFINED;
11812                     regs = 1;
11813                     if (BitIsSet (align, 1))
11814                         return false;
11815                 }
11816                 else if (type == 10) // when �1010�
11817                 {
11818                     // regs = 2; if align == �11� then UNDEFINED;
11819                     regs = 2;
11820                     if (align == 3)
11821                         return false;
11822                 }
11823                 else if (type == 6) // when �0110�
11824                 {
11825                     // regs = 3; if align<1> == �1� then UNDEFINED;
11826                     regs = 3;
11827                     if (BitIsSet (align, 1))
11828                         return false;
11829                 }
11830                 else if (type == 2) // when �0010�
11831                     // regs = 4;
11832                     regs = 4;
11833                 else // otherwise
11834                     // SEE �Related encodings�;
11835                     return false;
11836 
11837                 // alignment = if align == �00� then 1 else 4 << UInt(align);
11838                 if (align == 0)
11839                     alignment = 1;
11840                 else
11841                     alignment = 4 << align;
11842 
11843                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11844                 ebytes = 1 << Bits32 (opcode,7, 6);
11845                 esize = 8 * ebytes;
11846                 elements = 8 / ebytes;
11847 
11848                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11849                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11850                 n = Bits32 (opcode, 19, 16);
11851                 m = Bits32 (opcode, 3, 0);
11852 
11853                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11854                 wback = (m != 15);
11855                 register_index = ((m != 15) && (m != 13));
11856 
11857                 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11858                 if ((d + regs) > 32)
11859                     return false;
11860 
11861                 if (n == 15)
11862                     return false;
11863 
11864             }
11865                 break;
11866 
11867             default:
11868                 return false;
11869         }
11870 
11871         RegisterInfo base_reg;
11872         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11873 
11874         uint32_t Rn = ReadCoreReg (n, &success);
11875         if (!success)
11876             return false;
11877 
11878         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11879         addr_t address = Rn;
11880         if ((address % alignment) != 0)
11881             return false;
11882 
11883         EmulateInstruction::Context context;
11884         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11885         if (wback)
11886         {
11887             uint32_t Rm = ReadCoreReg (m, &success);
11888             if (!success)
11889                 return false;
11890 
11891             uint32_t offset;
11892             if (register_index)
11893                 offset = Rm;
11894             else
11895                 offset = 8 * regs;
11896 
11897             context.type = eContextAdjustBaseRegister;
11898             context.SetRegisterPlusOffset (base_reg, offset);
11899 
11900             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11901                 return false;
11902         }
11903 
11904         RegisterInfo data_reg;
11905         context.type = eContextRegisterStore;
11906         // for r = 0 to regs-1
11907         for (uint32_t r = 0; r < regs; ++r)
11908         {
11909             GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
11910             uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
11911             if (!success)
11912                 return false;
11913 
11914              // for e = 0 to elements-1
11915             for (uint32_t e = 0; e < elements; ++e)
11916             {
11917                 // MemU[address,ebytes] = Elem[D[d+r],e,esize];
11918                 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize);
11919 
11920                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11921                 if (!MemUWrite (context, address, word, ebytes))
11922                     return false;
11923 
11924                 // address = address + ebytes;
11925                 address = address + ebytes;
11926             }
11927         }
11928     }
11929     return true;
11930 }
11931 
11932 // A8.6.392 VST1 (single element from one lane)
11933 // This instruction stores one element to memory from one element of a register.
11934 bool
11935 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding)
11936 {
11937 #if 0
11938     if ConditionPassed() then
11939         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11940         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11941         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11942         MemU[address,ebytes] = Elem[D[d],index,esize];
11943 #endif
11944 
11945     bool success = false;
11946 
11947     if (ConditionPassed (opcode))
11948     {
11949         uint32_t ebytes;
11950         uint32_t esize;
11951         uint32_t index;
11952         uint32_t alignment;
11953         uint32_t d;
11954         uint32_t n;
11955         uint32_t m;
11956         bool wback;
11957         bool register_index;
11958 
11959         switch (encoding)
11960         {
11961             case eEncodingT1:
11962             case eEncodingA1:
11963             {
11964                 uint32_t size = Bits32 (opcode, 11, 10);
11965                 uint32_t index_align = Bits32 (opcode, 7, 4);
11966 
11967                 // if size == �11� then UNDEFINED;
11968                 if (size == 3)
11969                     return false;
11970 
11971                 // case size of
11972                 if (size == 0) // when �00�
11973                 {
11974                     // if index_align<0> != �0� then UNDEFINED;
11975                     if (BitIsClear (index_align, 0))
11976                         return false;
11977                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11978                     ebytes = 1;
11979                     esize = 8;
11980                     index = Bits32 (index_align, 3, 1);
11981                     alignment = 1;
11982                 }
11983                 else if (size == 1) // when �01�
11984                 {
11985                     // if index_align<1> != �0� then UNDEFINED;
11986                     if (BitIsClear (index_align, 1))
11987                         return false;
11988 
11989                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11990                     ebytes = 2;
11991                     esize = 16;
11992                     index = Bits32 (index_align, 3, 2);
11993 
11994                     // alignment = if index_align<0> == �0� then 1 else 2;
11995                     if (BitIsClear (index_align, 0))
11996                         alignment = 1;
11997                     else
11998                         alignment = 2;
11999                 }
12000                 else if (size == 2) // when �10�
12001                 {
12002                     // if index_align<2> != �0� then UNDEFINED;
12003                     if (BitIsClear (index_align, 2))
12004                         return false;
12005 
12006                     // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
12007                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
12008                         return false;
12009 
12010                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
12011                     ebytes = 4;
12012                     esize = 32;
12013                     index = Bit32 (index_align, 3);
12014 
12015                     // alignment = if index_align<1:0> == �00� then 1 else 4;
12016                     if (Bits32 (index_align, 1, 0) == 0)
12017                         alignment = 1;
12018                     else
12019                         alignment = 4;
12020                 }
12021                 else
12022                 {
12023                     return false;
12024                 }
12025                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12026                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
12027                 n = Bits32 (opcode, 19, 16);
12028                 m = Bits32 (opcode, 3, 0);
12029 
12030                 // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15 then UNPREDICTABLE;
12031                 wback = (m != 15);
12032                 register_index = ((m != 15) && (m != 13));
12033 
12034                 if (n == 15)
12035                     return false;
12036             }
12037                 break;
12038 
12039             default:
12040                 return false;
12041         }
12042 
12043         RegisterInfo base_reg;
12044         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12045 
12046         uint32_t Rn = ReadCoreReg (n, &success);
12047         if (!success)
12048             return false;
12049 
12050         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12051         addr_t address = Rn;
12052         if ((address % alignment) != 0)
12053             return false;
12054 
12055         EmulateInstruction::Context context;
12056         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12057         if (wback)
12058         {
12059             uint32_t Rm = ReadCoreReg (m, &success);
12060             if (!success)
12061                 return false;
12062 
12063             uint32_t offset;
12064             if (register_index)
12065                 offset = Rm;
12066             else
12067                 offset = ebytes;
12068 
12069             context.type = eContextAdjustBaseRegister;
12070             context.SetRegisterPlusOffset (base_reg, offset);
12071 
12072             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
12073                 return false;
12074         }
12075 
12076         // MemU[address,ebytes] = Elem[D[d],index,esize];
12077         uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12078         if (!success)
12079             return false;
12080 
12081         uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1,  index * esize);
12082 
12083         RegisterInfo data_reg;
12084         GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg);
12085         context.type = eContextRegisterStore;
12086         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
12087 
12088         if (!MemUWrite (context, address, word, ebytes))
12089             return false;
12090     }
12091     return true;
12092 }
12093 
12094 // A8.6.309 VLD1 (single element to all lanes)
12095 // This instruction loads one element from memory into every element of one or two vectors.
12096 bool
12097 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding)
12098 {
12099 #if 0
12100     if ConditionPassed() then
12101         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12102         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12103         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12104         replicated_element = Replicate(MemU[address,ebytes], elements);
12105         for r = 0 to regs-1
12106             D[d+r] = replicated_element;
12107 #endif
12108 
12109     bool success = false;
12110 
12111     if (ConditionPassed (opcode))
12112     {
12113         uint32_t ebytes;
12114         uint32_t elements;
12115         uint32_t regs;
12116         uint32_t alignment;
12117         uint32_t d;
12118         uint32_t n;
12119         uint32_t m;
12120         bool wback;
12121         bool register_index;
12122 
12123         switch (encoding)
12124         {
12125             case eEncodingT1:
12126             case eEncodingA1:
12127             {
12128                 //if size == �11� || (size == �00� && a == �1�) then UNDEFINED;
12129                 uint32_t size = Bits32 (opcode, 7, 6);
12130                 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4)))
12131                     return false;
12132 
12133                 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2;
12134                 ebytes = 1 << size;
12135                 elements = 8 / ebytes;
12136                 if (BitIsClear (opcode, 5))
12137                     regs = 1;
12138                 else
12139                     regs = 2;
12140 
12141                 //alignment = if a == �0� then 1 else ebytes;
12142                 if (BitIsClear (opcode, 4))
12143                     alignment = 1;
12144                 else
12145                     alignment = ebytes;
12146 
12147                 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12148                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
12149                 n = Bits32 (opcode, 19, 16);
12150                 m = Bits32 (opcode, 3, 0);
12151 
12152                 //wback = (m != 15); register_index = (m != 15 && m != 13);
12153                 wback = (m != 15);
12154                 register_index = ((m != 15) && (m != 13));
12155 
12156                 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12157                 if ((d + regs) > 32)
12158                     return false;
12159 
12160                 if (n == 15)
12161                     return false;
12162             }
12163             break;
12164 
12165             default:
12166                 return false;
12167         }
12168 
12169         RegisterInfo base_reg;
12170         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12171 
12172         uint32_t Rn = ReadCoreReg (n, &success);
12173         if (!success)
12174             return false;
12175 
12176         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12177         addr_t address = Rn;
12178         if ((address % alignment) != 0)
12179             return false;
12180 
12181         EmulateInstruction::Context context;
12182         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12183         if (wback)
12184         {
12185             uint32_t Rm = ReadCoreReg (m, &success);
12186             if (!success)
12187                 return false;
12188 
12189             uint32_t offset;
12190             if (register_index)
12191                 offset = Rm;
12192             else
12193                 offset = ebytes;
12194 
12195             context.type = eContextAdjustBaseRegister;
12196             context.SetRegisterPlusOffset (base_reg, offset);
12197 
12198             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
12199                 return false;
12200         }
12201 
12202         // replicated_element = Replicate(MemU[address,ebytes], elements);
12203 
12204         context.type = eContextRegisterLoad;
12205         uint64_t word = MemURead (context, address, ebytes, 0, &success);
12206         if (!success)
12207             return false;
12208 
12209         uint64_t replicated_element = 0;
12210         uint32_t esize = ebytes * 8;
12211         for (uint32_t e = 0; e < elements; ++e)
12212             replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0);
12213 
12214         // for r = 0 to regs-1
12215         for (uint32_t r = 0; r < regs; ++r)
12216         {
12217             // D[d+r] = replicated_element;
12218             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element))
12219                 return false;
12220         }
12221     }
12222     return true;
12223 }
12224 
12225 // B6.2.13 SUBS PC, LR and related instructions
12226 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack.  It subtracts the
12227 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR.
12228 bool
12229 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding)
12230 {
12231 #if 0
12232     if ConditionPassed() then
12233         EncodingSpecificOperations();
12234         if CurrentInstrSet() == InstrSet_ThumbEE then
12235             UNPREDICTABLE;
12236         operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12237         case opcode of
12238             when0000result = R[n] AND operand2; // AND
12239             when0001result = R[n] EOR operand2; // EOR
12240             when0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12241             when0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12242             when0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12243             when0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12244             when0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12245             when0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12246             when1100result = R[n] OR operand2; // ORR
12247             when1101result = operand2; // MOV
12248             when1110result = R[n] AND NOT(operand2); // BIC
12249             when1111result = NOT(operand2); // MVN
12250         CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12251         BranchWritePC(result);
12252 #endif
12253 
12254     bool success = false;
12255 
12256     if (ConditionPassed (opcode))
12257     {
12258         uint32_t n;
12259         uint32_t m;
12260         uint32_t imm32;
12261         bool register_form;
12262         ARM_ShifterType shift_t;
12263         uint32_t shift_n;
12264         uint32_t code;
12265 
12266         switch (encoding)
12267         {
12268             case eEncodingT1:
12269                 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
12270                 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB
12271                 n = 14;
12272                 imm32 = Bits32 (opcode, 7, 0);
12273                 register_form = false;
12274                 code = 2;
12275 
12276                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12277                 if (InITBlock() && !LastInITBlock())
12278                     return false;
12279 
12280                 break;
12281 
12282             case eEncodingA1:
12283                 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12284                 n = Bits32 (opcode, 19, 16);
12285                 imm32 = ARMExpandImm (opcode);
12286                 register_form = false;
12287                 code = Bits32 (opcode, 24, 21);
12288 
12289                 break;
12290 
12291             case eEncodingA2:
12292                 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12293                 n = Bits32 (opcode, 19, 16);
12294                 m = Bits32 (opcode, 3, 0);
12295                 register_form = true;
12296 
12297                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12298                 shift_n = DecodeImmShiftARM (opcode, shift_t);
12299 
12300                 break;
12301 
12302             default:
12303                 return false;
12304         }
12305 
12306         // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12307         uint32_t operand2;
12308         if (register_form)
12309         {
12310             uint32_t Rm = ReadCoreReg (m, &success);
12311             if (!success)
12312                 return false;
12313 
12314             operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success);
12315             if (!success)
12316                 return false;
12317         }
12318         else
12319         {
12320             operand2 = imm32;
12321         }
12322 
12323         uint32_t Rn = ReadCoreReg (n, &success);
12324         if (!success)
12325             return false;
12326 
12327         AddWithCarryResult result;
12328 
12329         // case opcode of
12330         switch (code)
12331         {
12332             case 0: // when �0000�
12333                 // result = R[n] AND operand2; // AND
12334                 result.result = Rn & operand2;
12335                 break;
12336 
12337             case 1: // when �0001�
12338                 // result = R[n] EOR operand2; // EOR
12339                 result.result = Rn ^ operand2;
12340                 break;
12341 
12342             case 2: // when �0010�
12343                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12344                 result = AddWithCarry (Rn, ~(operand2), 1);
12345                 break;
12346 
12347             case 3: // when �0011�
12348                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12349                 result = AddWithCarry (~(Rn), operand2, 1);
12350                 break;
12351 
12352             case 4: // when �0100�
12353                 // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12354                 result = AddWithCarry (Rn, operand2, 0);
12355                 break;
12356 
12357             case 5: // when �0101�
12358                 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12359                 result = AddWithCarry (Rn, operand2, APSR_C);
12360                 break;
12361 
12362             case 6: // when �0110�
12363                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12364                 result = AddWithCarry (Rn, ~(operand2), APSR_C);
12365                 break;
12366 
12367             case 7: // when �0111�
12368                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12369                 result = AddWithCarry (~(Rn), operand2, APSR_C);
12370                 break;
12371 
12372             case 10: // when �1100�
12373                 // result = R[n] OR operand2; // ORR
12374                 result.result = Rn | operand2;
12375                 break;
12376 
12377             case 11: // when �1101�
12378                 // result = operand2; // MOV
12379                 result.result = operand2;
12380                 break;
12381 
12382             case 12: // when �1110�
12383                 // result = R[n] AND NOT(operand2); // BIC
12384                 result.result = Rn & ~(operand2);
12385                 break;
12386 
12387             case 15: // when �1111�
12388                 // result = NOT(operand2); // MVN
12389                 result.result = ~(operand2);
12390                 break;
12391 
12392             default:
12393                 return false;
12394         }
12395         // CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12396 
12397         // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for
12398         // the best.
12399         uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12400         if (!success)
12401             return false;
12402 
12403         CPSRWriteByInstr (spsr, 15, true);
12404 
12405         // BranchWritePC(result);
12406         EmulateInstruction::Context context;
12407         context.type = eContextAdjustPC;
12408         context.SetImmediate (result.result);
12409 
12410         BranchWritePC (context, result.result);
12411     }
12412     return true;
12413 }
12414 
12415 EmulateInstructionARM::ARMOpcode*
12416 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12417 {
12418     static ARMOpcode
12419     g_arm_opcodes[] =
12420     {
12421         //----------------------------------------------------------------------
12422         // Prologue instructions
12423         //----------------------------------------------------------------------
12424 
12425         // push register(s)
12426         { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12427         { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
12428 
12429         // set r7 to point to a stack offset
12430         { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
12431         { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12432         // copy the stack pointer to ip
12433         { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
12434         { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
12435         { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12436 
12437         // adjust the stack pointer
12438         { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12439         { 0x0fef0010, 0x004d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12440 
12441         // push one register
12442         // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12443         { 0x0e5f0000, 0x040d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
12444 
12445         // vector push consecutive extension register(s)
12446         { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12447         { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12448 
12449         //----------------------------------------------------------------------
12450         // Epilogue instructions
12451         //----------------------------------------------------------------------
12452 
12453         { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12454         { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12455         { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12456         { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12457 
12458         //----------------------------------------------------------------------
12459         // Supervisor Call (previously Software Interrupt)
12460         //----------------------------------------------------------------------
12461         { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12462 
12463         //----------------------------------------------------------------------
12464         // Branch instructions
12465         //----------------------------------------------------------------------
12466         // To resolve ambiguity, "blx <label>" should come before "b #imm24" and "bl <label>".
12467         { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12468         { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
12469         { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12470         { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12471         // for example, "bx lr"
12472         { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12473         // bxj
12474         { 0x0ffffff0, 0x012fff20, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12475 
12476         //----------------------------------------------------------------------
12477         // Data-processing instructions
12478         //----------------------------------------------------------------------
12479         // adc (immediate)
12480         { 0x0fe00000, 0x02a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12481         // adc (register)
12482         { 0x0fe00010, 0x00a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12483         // add (immediate)
12484         { 0x0fe00000, 0x02800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
12485         // add (register)
12486         { 0x0fe00010, 0x00800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12487         // add (register-shifted register)
12488         { 0x0fe00090, 0x00800010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12489         // adr
12490         { 0x0fff0000, 0x028f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12491         { 0x0fff0000, 0x024f0000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12492         // and (immediate)
12493         { 0x0fe00000, 0x02000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12494         // and (register)
12495         { 0x0fe00010, 0x00000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12496         // bic (immediate)
12497         { 0x0fe00000, 0x03c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12498         // bic (register)
12499         { 0x0fe00010, 0x01c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12500         // eor (immediate)
12501         { 0x0fe00000, 0x02200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12502         // eor (register)
12503         { 0x0fe00010, 0x00200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12504         // orr (immediate)
12505         { 0x0fe00000, 0x03800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12506         // orr (register)
12507         { 0x0fe00010, 0x01800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12508         // rsb (immediate)
12509         { 0x0fe00000, 0x02600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12510         // rsb (register)
12511         { 0x0fe00010, 0x00600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12512         // rsc (immediate)
12513         { 0x0fe00000, 0x02e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12514         // rsc (register)
12515         { 0x0fe00010, 0x00e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12516         // sbc (immediate)
12517         { 0x0fe00000, 0x02c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12518         // sbc (register)
12519         { 0x0fe00010, 0x00c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12520         // sub (immediate, ARM)
12521         { 0x0fe00000, 0x02400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
12522         // sub (sp minus immediate)
12523         { 0x0fef0000, 0x024d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12524         // sub (register)
12525         { 0x0fe00010, 0x00400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12526         // teq (immediate)
12527         { 0x0ff0f000, 0x03300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12528         // teq (register)
12529         { 0x0ff0f010, 0x01300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12530         // tst (immediate)
12531         { 0x0ff0f000, 0x03100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12532         // tst (register)
12533         { 0x0ff0f010, 0x01100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12534 
12535         // mov (immediate)
12536         { 0x0fef0000, 0x03a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12537         { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
12538         // mov (register)
12539         { 0x0fef0ff0, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12540         // mvn (immediate)
12541         { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12542         // mvn (register)
12543         { 0x0fef0010, 0x01e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12544         // cmn (immediate)
12545         { 0x0ff0f000, 0x03700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12546         // cmn (register)
12547         { 0x0ff0f010, 0x01700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12548         // cmp (immediate)
12549         { 0x0ff0f000, 0x03500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
12550         // cmp (register)
12551         { 0x0ff0f010, 0x01500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
12552         // asr (immediate)
12553         { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
12554         // asr (register)
12555         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
12556         // lsl (immediate)
12557         { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
12558         // lsl (register)
12559         { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
12560         // lsr (immediate)
12561         { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
12562         // lsr (register)
12563         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
12564         // rrx is a special case encoding of ror (immediate)
12565         { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
12566         // ror (immediate)
12567         { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
12568         // ror (register)
12569         { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
12570         // mul
12571         { 0x0fe000f0, 0x00000090, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
12572 
12573         // subs pc, lr and related instructions
12574         { 0x0e10f000, 0x0210f000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" },
12575         { 0x0e10f010, 0x0010f000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" },
12576 
12577         //----------------------------------------------------------------------
12578         // Load instructions
12579         //----------------------------------------------------------------------
12580         { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12581         { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
12582         { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12583         { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
12584         { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
12585         { 0x0e500010, 0x06100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
12586         { 0x0e5f0000, 0x045f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
12587         { 0xfe500010, 0x06500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
12588         { 0x0e5f00f0, 0x005f00b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12589         { 0x0e5000f0, 0x001000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"  },
12590         { 0x0e5000f0, 0x005000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
12591         { 0x0e5f00f0, 0x005f00d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
12592         { 0x0e5000f0, 0x001000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12593         { 0x0e5000f0, 0x005000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
12594         { 0x0e5f00f0, 0x005f00f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12595         { 0x0e5000f0, 0x001000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12596         { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
12597         { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12598         { 0x0e100f00, 0x0c100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12599         { 0x0e100f00, 0x0c100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12600         { 0x0f300f00, 0x0d100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12601         { 0x0f300f00, 0x0d100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12602         { 0xffb00000, 0xf4200000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12603         { 0xffb00300, 0xf4a00000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12604         { 0xffb00f00, 0xf4a00c00, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12605 
12606         //----------------------------------------------------------------------
12607         // Store instructions
12608         //----------------------------------------------------------------------
12609         { 0x0fd00000, 0x08800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12610         { 0x0fd00000, 0x08000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
12611         { 0x0fd00000, 0x09000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12612         { 0x0fd00000, 0x09800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
12613         { 0x0e500010, 0x06000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
12614         { 0x0e5000f0, 0x000000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
12615         { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
12616         { 0x0e500000, 0x04400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12617         { 0x0e500000, 0x04000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12618         { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
12619         { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12620         { 0x0e100f00, 0x0c000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12621         { 0x0e100f00, 0x0c000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12622         { 0x0f300f00, 0x0d000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
12623         { 0x0f300f00, 0x0d000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
12624         { 0xffb00000, 0xf4000000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12625         { 0xffb00300, 0xf4800000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12626 
12627         //----------------------------------------------------------------------
12628         // Other instructions
12629         //----------------------------------------------------------------------
12630         { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
12631         { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
12632         { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
12633         { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
12634         { 0xfe500000, 0xf8100000, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
12635 
12636     };
12637     static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes);
12638 
12639     for (size_t i=0; i<k_num_arm_opcodes; ++i)
12640     {
12641         if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
12642             (g_arm_opcodes[i].variants & arm_isa) != 0)
12643             return &g_arm_opcodes[i];
12644     }
12645     return NULL;
12646 }
12647 
12648 
12649 EmulateInstructionARM::ARMOpcode*
12650 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12651 {
12652 
12653     static ARMOpcode
12654     g_thumb_opcodes[] =
12655     {
12656         //----------------------------------------------------------------------
12657         // Prologue instructions
12658         //----------------------------------------------------------------------
12659 
12660         // push register(s)
12661         { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12662         { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
12663         { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
12664 
12665         // set r7 to point to a stack offset
12666         { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
12667         // copy the stack pointer to r7
12668         { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
12669         // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
12670         { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
12671 
12672         // PC-relative load into register (see also EmulateADDSPRm)
12673         { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
12674 
12675         // adjust the stack pointer
12676         { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
12677         { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
12678         { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
12679         { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
12680         { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12681 
12682         // vector push consecutive extension register(s)
12683         { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12684         { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12685 
12686         //----------------------------------------------------------------------
12687         // Epilogue instructions
12688         //----------------------------------------------------------------------
12689 
12690         { 0xfffff800, 0x0000a800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
12691         { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
12692         { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12693         { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
12694         { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
12695         { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12696         { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12697 
12698         //----------------------------------------------------------------------
12699         // Supervisor Call (previously Software Interrupt)
12700         //----------------------------------------------------------------------
12701         { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
12702 
12703         //----------------------------------------------------------------------
12704         // If Then makes up to four following instructions conditional.
12705         //----------------------------------------------------------------------
12706         // The next 5 opcode _must_ come before the if then instruction
12707         { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"},
12708         { 0xffffffff, 0x0000bf10, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
12709         { 0xffffffff, 0x0000bf20, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
12710         { 0xffffffff, 0x0000bf30, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
12711         { 0xffffffff, 0x0000bf40, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
12712         { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
12713 
12714         //----------------------------------------------------------------------
12715         // Branch instructions
12716         //----------------------------------------------------------------------
12717         // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
12718         { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
12719         { 0xfffff800, 0x0000e000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
12720         { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
12721         { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
12722         // J1 == J2 == 1
12723         { 0xf800d000, 0xf000d000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12724         // J1 == J2 == 1
12725         { 0xf800d001, 0xf000c000, ARMV5_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12726         { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12727         // for example, "bx lr"
12728         { 0xffffff87, 0x00004700, ARMvAll,       eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12729         // bxj
12730         { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12731         // compare and branch
12732         { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
12733         // table branch byte
12734         { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
12735         // table branch halfword
12736         { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
12737 
12738         //----------------------------------------------------------------------
12739         // Data-processing instructions
12740         //----------------------------------------------------------------------
12741         // adc (immediate)
12742         { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
12743         // adc (register)
12744         { 0xffffffc0, 0x00004140, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
12745         { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12746         // add (register)
12747         { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
12748         // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
12749         { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
12750         // adr
12751         { 0xfffff800, 0x0000a000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12752         { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12753         { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12754         // and (immediate)
12755         { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
12756         // and (register)
12757         { 0xffffffc0, 0x00004000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
12758         { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12759         // bic (immediate)
12760         { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
12761         // bic (register)
12762         { 0xffffffc0, 0x00004380, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
12763         { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12764         // eor (immediate)
12765         { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
12766         // eor (register)
12767         { 0xffffffc0, 0x00004040, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
12768         { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12769         // orr (immediate)
12770         { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
12771         // orr (register)
12772         { 0xffffffc0, 0x00004300, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
12773         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12774         // rsb (immediate)
12775         { 0xffffffc0, 0x00004240, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
12776         { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
12777         // rsb (register)
12778         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12779         // sbc (immediate)
12780         { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12781         // sbc (register)
12782         { 0xffffffc0, 0x00004180, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
12783         { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12784         // add (immediate, Thumb)
12785         { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
12786         { 0xfffff800, 0x00003000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
12787         { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
12788         { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
12789         // sub (immediate, Thumb)
12790         { 0xfffffe00, 0x00001e00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
12791         { 0xfffff800, 0x00003800, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
12792         { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
12793         { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
12794         // sub (sp minus immediate)
12795         { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
12796         { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
12797         // sub (register)
12798         { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
12799         { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
12800         // teq (immediate)
12801         { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
12802         // teq (register)
12803         { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12804         // tst (immediate)
12805         { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
12806         // tst (register)
12807         { 0xffffffc0, 0x00004200, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
12808         { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
12809 
12810 
12811         // move from high register to high register
12812         { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
12813         // move from low register to low register
12814         { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
12815         // mov{s}<c>.w <Rd>, <Rm>
12816         { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
12817         // move immediate
12818         { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
12819         { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
12820         { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
12821         // mvn (immediate)
12822         { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
12823         // mvn (register)
12824         { 0xffffffc0, 0x000043c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
12825         { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
12826         // cmn (immediate)
12827         { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12828         // cmn (register)
12829         { 0xffffffc0, 0x000042c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
12830         { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12831         // cmp (immediate)
12832         { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
12833         { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
12834         // cmp (register) (Rn and Rm both from r0-r7)
12835         { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12836         // cmp (register) (Rn and Rm not both from r0-r7)
12837         { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12838         { 0xfff08f00, 0xebb00f00, ARMvAll,       eEncodingT3, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c>.w <Rn>, <Rm> {, <shift>}"},
12839         // asr (immediate)
12840         { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
12841         { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
12842         // asr (register)
12843         { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
12844         { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12845         // lsl (immediate)
12846         { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
12847         { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
12848         // lsl (register)
12849         { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
12850         { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
12851         // lsr (immediate)
12852         { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
12853         { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
12854         // lsr (register)
12855         { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
12856         { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12857         // rrx is a special case encoding of ror (immediate)
12858         { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
12859         // ror (immediate)
12860         { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
12861         // ror (register)
12862         { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
12863         { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
12864         // mul
12865         { 0xffffffc0, 0x00004340, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
12866         // mul
12867         { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
12868 
12869         // subs pc, lr and related instructions
12870         { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" },
12871 
12872         //----------------------------------------------------------------------
12873         // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table;
12874         // otherwise the wrong instructions will be selected.
12875         //----------------------------------------------------------------------
12876 
12877         { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
12878         { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
12879 
12880         //----------------------------------------------------------------------
12881         // Load instructions
12882         //----------------------------------------------------------------------
12883         { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12884         { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
12885         { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12886         { 0xfffff800, 0x00006800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
12887         { 0xfffff800, 0x00009800, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
12888         { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
12889         { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
12890                   // Thumb2 PC-relative load into register
12891         { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
12892         { 0xfffffe00, 0x00005800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
12893         { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
12894         { 0xfffff800, 0x00007800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
12895         { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12896         { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" },
12897         { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
12898         { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
12899         { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
12900         { 0xfffff800, 0x00008800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"  },
12901         { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12902         { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"  },
12903         { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12904         { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
12905         { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12906         { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
12907         { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12908         { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
12909         { 0xfffffe00, 0x00005600, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
12910         { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"  },
12911         { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
12912         { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12913         { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12914         { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
12915         { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12916         { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
12917         { 0xfe100f00, 0xec100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12918         { 0xfe100f00, 0xec100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
12919         { 0xffe00f00, 0xed100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12920         { 0xff300f00, 0xed100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
12921         { 0xffb00000, 0xf9200000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12922         { 0xffb00300, 0xf9a00000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12923         { 0xffb00f00, 0xf9a00c00, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12924 
12925         //----------------------------------------------------------------------
12926         // Store instructions
12927         //----------------------------------------------------------------------
12928         { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12929         { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
12930         { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12931         { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
12932         { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
12933         { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
12934         { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
12935         { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
12936         { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
12937         { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
12938         { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
12939         { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
12940         { 0xfffffe00, 0x00005200, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
12941         { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12942         { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
12943         { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
12944         { 0xfe100f00, 0xec000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12945         { 0xfea00f00, 0xec000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12946         { 0xff300f00, 0xed000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12947         { 0xff300f00, 0xed000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12948         { 0xffb00000, 0xf9000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12949         { 0xffb00300, 0xf9800000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12950 
12951         //----------------------------------------------------------------------
12952         // Other instructions
12953         //----------------------------------------------------------------------
12954         { 0xffffffc0, 0x0000b240, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
12955         { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12956         { 0xffffffc0, 0x0000b200, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
12957         { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12958         { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
12959         { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12960         { 0xffffffc0, 0x0000b280, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
12961         { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12962     };
12963 
12964     const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes);
12965     for (size_t i=0; i<k_num_thumb_opcodes; ++i)
12966     {
12967         if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
12968             (g_thumb_opcodes[i].variants & arm_isa) != 0)
12969             return &g_thumb_opcodes[i];
12970     }
12971     return NULL;
12972 }
12973 
12974 bool
12975 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
12976 {
12977     m_arch = arch;
12978     m_arm_isa = 0;
12979     const char *arch_cstr = arch.GetArchitectureName ();
12980     if (arch_cstr)
12981     {
12982         if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
12983         else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
12984         else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
12985         else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
12986         else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
12987         else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
12988         else if (0 == ::strcasecmp(arch_cstr, "armv7s"))    m_arm_isa = ARMv7S;
12989         else if (0 == ::strcasecmp(arch_cstr, "arm"))       m_arm_isa = ARMvAll;
12990         else if (0 == ::strcasecmp(arch_cstr, "thumb"))     m_arm_isa = ARMvAll;
12991         else if (0 == ::strncasecmp(arch_cstr,"armv4", 5))  m_arm_isa = ARMv4;
12992         else if (0 == ::strncasecmp(arch_cstr,"armv6", 5))  m_arm_isa = ARMv6;
12993         else if (0 == ::strncasecmp(arch_cstr,"armv7", 5))  m_arm_isa = ARMv7;
12994         else if (0 == ::strncasecmp(arch_cstr,"armv8", 5))  m_arm_isa = ARMv8;
12995     }
12996     return m_arm_isa != 0;
12997 }
12998 
12999 bool
13000 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
13001 {
13002     if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
13003     {
13004         if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
13005             m_opcode_mode = eModeThumb;
13006         else
13007         {
13008             AddressClass addr_class = inst_addr.GetAddressClass();
13009 
13010             if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
13011                 m_opcode_mode = eModeARM;
13012             else if (addr_class == eAddressClassCodeAlternateISA)
13013                 m_opcode_mode = eModeThumb;
13014             else
13015                 return false;
13016         }
13017         if (m_opcode_mode == eModeThumb)
13018             m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
13019         else
13020             m_opcode_cpsr = CPSR_MODE_USR;
13021         return true;
13022     }
13023     return false;
13024 }
13025 
13026 bool
13027 EmulateInstructionARM::ReadInstruction ()
13028 {
13029     bool success = false;
13030     m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
13031     if (success)
13032     {
13033         addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
13034         if (success)
13035         {
13036             Context read_inst_context;
13037             read_inst_context.type = eContextReadOpcode;
13038             read_inst_context.SetNoArgs ();
13039 
13040             if (m_opcode_cpsr & MASK_CPSR_T)
13041             {
13042                 m_opcode_mode = eModeThumb;
13043                 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
13044 
13045                 if (success)
13046                 {
13047                     if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
13048                     {
13049                         m_opcode.SetOpcode16 (thumb_opcode, GetByteOrder());
13050                     }
13051                     else
13052                     {
13053                         m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success), GetByteOrder());
13054                     }
13055                 }
13056             }
13057             else
13058             {
13059                 m_opcode_mode = eModeARM;
13060                 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success), GetByteOrder());
13061             }
13062         }
13063     }
13064     if (!success)
13065     {
13066         m_opcode_mode = eModeInvalid;
13067         m_addr = LLDB_INVALID_ADDRESS;
13068     }
13069     return success;
13070 }
13071 
13072 uint32_t
13073 EmulateInstructionARM::ArchVersion ()
13074 {
13075     return m_arm_isa;
13076 }
13077 
13078 bool
13079 EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional)
13080 {
13081    // If we are ignoring conditions, then always return true.
13082    // this allows us to iterate over disassembly code and still
13083    // emulate an instruction even if we don't have all the right
13084    // bits set in the CPSR register...
13085     if (m_ignore_conditions)
13086         return true;
13087 
13088     if (is_conditional)
13089         *is_conditional = true;
13090 
13091     const uint32_t cond = CurrentCond (opcode);
13092 
13093     if (cond == UINT32_MAX)
13094         return false;
13095 
13096     bool result = false;
13097     switch (UnsignedBits(cond, 3, 1))
13098     {
13099     case 0:
13100 		if (m_opcode_cpsr == 0)
13101 			result = true;
13102         else
13103             result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
13104 		break;
13105     case 1:
13106         if (m_opcode_cpsr == 0)
13107             result = true;
13108         else
13109             result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
13110 		break;
13111     case 2:
13112         if (m_opcode_cpsr == 0)
13113             result = true;
13114         else
13115             result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
13116 		break;
13117     case 3:
13118         if (m_opcode_cpsr == 0)
13119             result = true;
13120         else
13121             result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
13122 		break;
13123     case 4:
13124         if (m_opcode_cpsr == 0)
13125             result = true;
13126         else
13127             result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13128 		break;
13129     case 5:
13130         if (m_opcode_cpsr == 0)
13131             result = true;
13132         else
13133 		{
13134             bool n = (m_opcode_cpsr & MASK_CPSR_N);
13135             bool v = (m_opcode_cpsr & MASK_CPSR_V);
13136             result = n == v;
13137         }
13138         break;
13139     case 6:
13140         if (m_opcode_cpsr == 0)
13141             result = true;
13142         else
13143 		{
13144             bool n = (m_opcode_cpsr & MASK_CPSR_N);
13145             bool v = (m_opcode_cpsr & MASK_CPSR_V);
13146             result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13147         }
13148         break;
13149     case 7:
13150         // Always execute (cond == 0b1110, or the special 0b1111 which gives
13151         // opcodes different meanings, but always means execution happens.
13152         if (is_conditional)
13153             *is_conditional = false;
13154         return true;
13155     }
13156 
13157     if (cond & 1)
13158         result = !result;
13159     return result;
13160 }
13161 
13162 uint32_t
13163 EmulateInstructionARM::CurrentCond (const uint32_t opcode)
13164 {
13165     switch (m_opcode_mode)
13166     {
13167     case eModeInvalid:
13168         break;
13169 
13170     case eModeARM:
13171         return UnsignedBits(opcode, 31, 28);
13172 
13173     case eModeThumb:
13174         // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
13175         // 'cond' field of the encoding.
13176         {
13177             const uint32_t byte_size = m_opcode.GetByteSize();
13178             if (byte_size == 2)
13179             {
13180                 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f)
13181                     return Bits32(opcode, 11, 8);
13182             }
13183             else if (byte_size == 4)
13184             {
13185                 if (Bits32(opcode, 31, 27) == 0x1e &&
13186                     Bits32(opcode, 15, 14) == 0x02 &&
13187                     Bits32(opcode, 12, 12) == 0x00 &&
13188                     Bits32(opcode, 25, 22) <= 0x0d)
13189                 {
13190                     return Bits32(opcode, 25, 22);
13191                 }
13192             }
13193             else
13194                 // We have an invalid thumb instruction, let's bail out.
13195                 break;
13196 
13197             return m_it_session.GetCond();
13198         }
13199     }
13200     return UINT32_MAX;  // Return invalid value
13201 }
13202 
13203 bool
13204 EmulateInstructionARM::InITBlock()
13205 {
13206     return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13207 }
13208 
13209 bool
13210 EmulateInstructionARM::LastInITBlock()
13211 {
13212     return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13213 }
13214 
13215 bool
13216 EmulateInstructionARM::BadMode (uint32_t mode)
13217 {
13218 
13219     switch (mode)
13220     {
13221         case 16: return false; // '10000'
13222         case 17: return false; // '10001'
13223         case 18: return false; // '10010'
13224         case 19: return false; // '10011'
13225         case 22: return false; // '10110'
13226         case 23: return false; // '10111'
13227         case 27: return false; // '11011'
13228         case 31: return false; // '11111'
13229         default: return true;
13230     }
13231     return true;
13232 }
13233 
13234 bool
13235 EmulateInstructionARM::CurrentModeIsPrivileged ()
13236 {
13237     uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
13238 
13239     if (BadMode (mode))
13240         return false;
13241 
13242     if (mode == 16)
13243         return false;
13244 
13245     return true;
13246 }
13247 
13248 void
13249 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
13250 {
13251     bool privileged = CurrentModeIsPrivileged();
13252 
13253     uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20;
13254 
13255     if (BitIsSet (bytemask, 3))
13256     {
13257         tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
13258         if (affect_execstate)
13259             tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
13260     }
13261 
13262     if (BitIsSet (bytemask, 2))
13263     {
13264         tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
13265     }
13266 
13267     if (BitIsSet (bytemask, 1))
13268     {
13269         if (affect_execstate)
13270             tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
13271         tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
13272         if (privileged)
13273             tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
13274     }
13275 
13276     if (BitIsSet (bytemask, 0))
13277     {
13278         if (privileged)
13279             tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
13280         if (affect_execstate)
13281             tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
13282         if (privileged)
13283             tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
13284     }
13285 
13286     m_opcode_cpsr = tmp_cpsr;
13287 }
13288 
13289 
13290 bool
13291 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
13292 {
13293     addr_t target;
13294 
13295     // Check the current instruction set.
13296     if (CurrentInstrSet() == eModeARM)
13297         target = addr & 0xfffffffc;
13298     else
13299         target = addr & 0xfffffffe;
13300 
13301     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13302         return false;
13303 
13304     return true;
13305 }
13306 
13307 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
13308 bool
13309 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
13310 {
13311     addr_t target;
13312     // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
13313     // we want to record it and issue a WriteRegister callback so the clients
13314     // can track the mode changes accordingly.
13315     bool cpsr_changed = false;
13316 
13317     if (BitIsSet(addr, 0))
13318     {
13319         if (CurrentInstrSet() != eModeThumb)
13320         {
13321             SelectInstrSet(eModeThumb);
13322             cpsr_changed = true;
13323         }
13324         target = addr & 0xfffffffe;
13325         context.SetISA (eModeThumb);
13326     }
13327     else if (BitIsClear(addr, 1))
13328     {
13329         if (CurrentInstrSet() != eModeARM)
13330         {
13331             SelectInstrSet(eModeARM);
13332             cpsr_changed = true;
13333         }
13334         target = addr & 0xfffffffc;
13335         context.SetISA (eModeARM);
13336     }
13337     else
13338         return false; // address<1:0> == '10' => UNPREDICTABLE
13339 
13340     if (cpsr_changed)
13341     {
13342         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13343             return false;
13344     }
13345     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13346         return false;
13347 
13348     return true;
13349 }
13350 
13351 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
13352 bool
13353 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
13354 {
13355     if (ArchVersion() >= ARMv5T)
13356         return BXWritePC(context, addr);
13357     else
13358         return BranchWritePC((const Context)context, addr);
13359 }
13360 
13361 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
13362 bool
13363 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
13364 {
13365     if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
13366         return BXWritePC(context, addr);
13367     else
13368         return BranchWritePC((const Context)context, addr);
13369 }
13370 
13371 EmulateInstructionARM::Mode
13372 EmulateInstructionARM::CurrentInstrSet ()
13373 {
13374     return m_opcode_mode;
13375 }
13376 
13377 // Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
13378 // ReadInstruction() is performed.  This function has a side effect of updating
13379 // the m_new_inst_cpsr member variable if necessary.
13380 bool
13381 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
13382 {
13383     m_new_inst_cpsr = m_opcode_cpsr;
13384     switch (arm_or_thumb)
13385     {
13386     default:
13387         return false;
13388     case eModeARM:
13389         // Clear the T bit.
13390         m_new_inst_cpsr &= ~MASK_CPSR_T;
13391         break;
13392     case eModeThumb:
13393         // Set the T bit.
13394         m_new_inst_cpsr |= MASK_CPSR_T;
13395         break;
13396     }
13397     return true;
13398 }
13399 
13400 // This function returns TRUE if the processor currently provides support for
13401 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
13402 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
13403 bool
13404 EmulateInstructionARM::UnalignedSupport()
13405 {
13406     return (ArchVersion() >= ARMv7);
13407 }
13408 
13409 // The main addition and subtraction instructions can produce status information
13410 // about both unsigned carry and signed overflow conditions.  This status
13411 // information can be used to synthesize multi-word additions and subtractions.
13412 EmulateInstructionARM::AddWithCarryResult
13413 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
13414 {
13415     uint32_t result;
13416     uint8_t carry_out;
13417     uint8_t overflow;
13418 
13419     uint64_t unsigned_sum = x + y + carry_in;
13420     int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
13421 
13422     result = UnsignedBits(unsigned_sum, 31, 0);
13423 //    carry_out = (result == unsigned_sum ? 0 : 1);
13424     overflow = ((int32_t)result == signed_sum ? 0 : 1);
13425 
13426     if (carry_in)
13427         carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0;
13428     else
13429         carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0;
13430 
13431     AddWithCarryResult res = { result, carry_out, overflow };
13432     return res;
13433 }
13434 
13435 uint32_t
13436 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
13437 {
13438     lldb::RegisterKind reg_kind;
13439     uint32_t reg_num;
13440     switch (num)
13441     {
13442     case SP_REG:
13443         reg_kind = eRegisterKindGeneric;
13444         reg_num  = LLDB_REGNUM_GENERIC_SP;
13445         break;
13446     case LR_REG:
13447         reg_kind = eRegisterKindGeneric;
13448         reg_num  = LLDB_REGNUM_GENERIC_RA;
13449         break;
13450     case PC_REG:
13451         reg_kind = eRegisterKindGeneric;
13452         reg_num  = LLDB_REGNUM_GENERIC_PC;
13453         break;
13454     default:
13455         if (num < SP_REG)
13456         {
13457             reg_kind = eRegisterKindDWARF;
13458             reg_num  = dwarf_r0 + num;
13459         }
13460         else
13461         {
13462             //assert(0 && "Invalid register number");
13463             *success = false;
13464             return UINT32_MAX;
13465         }
13466         break;
13467     }
13468 
13469     // Read our register.
13470     uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
13471 
13472     // When executing an ARM instruction , PC reads as the address of the current
13473     // instruction plus 8.
13474     // When executing a Thumb instruction , PC reads as the address of the current
13475     // instruction plus 4.
13476     if (num == 15)
13477     {
13478         if (CurrentInstrSet() == eModeARM)
13479             val += 8;
13480         else
13481             val += 4;
13482     }
13483 
13484     return val;
13485 }
13486 
13487 // Write the result to the ARM core register Rd, and optionally update the
13488 // condition flags based on the result.
13489 //
13490 // This helper method tries to encapsulate the following pseudocode from the
13491 // ARM Architecture Reference Manual:
13492 //
13493 // if d == 15 then         // Can only occur for encoding A1
13494 //     ALUWritePC(result); // setflags is always FALSE here
13495 // else
13496 //     R[d] = result;
13497 //     if setflags then
13498 //         APSR.N = result<31>;
13499 //         APSR.Z = IsZeroBit(result);
13500 //         APSR.C = carry;
13501 //         // APSR.V unchanged
13502 //
13503 // In the above case, the API client does not pass in the overflow arg, which
13504 // defaults to ~0u.
13505 bool
13506 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
13507                                                   const uint32_t result,
13508                                                   const uint32_t Rd,
13509                                                   bool setflags,
13510                                                   const uint32_t carry,
13511                                                   const uint32_t overflow)
13512 {
13513     if (Rd == 15)
13514     {
13515         if (!ALUWritePC (context, result))
13516             return false;
13517     }
13518     else
13519     {
13520         lldb::RegisterKind reg_kind;
13521         uint32_t reg_num;
13522         switch (Rd)
13523         {
13524         case SP_REG:
13525             reg_kind = eRegisterKindGeneric;
13526             reg_num  = LLDB_REGNUM_GENERIC_SP;
13527             break;
13528         case LR_REG:
13529             reg_kind = eRegisterKindGeneric;
13530             reg_num  = LLDB_REGNUM_GENERIC_RA;
13531             break;
13532         default:
13533             reg_kind = eRegisterKindDWARF;
13534             reg_num  = dwarf_r0 + Rd;
13535         }
13536         if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
13537             return false;
13538         if (setflags)
13539             return WriteFlags (context, result, carry, overflow);
13540     }
13541     return true;
13542 }
13543 
13544 // This helper method tries to encapsulate the following pseudocode from the
13545 // ARM Architecture Reference Manual:
13546 //
13547 // APSR.N = result<31>;
13548 // APSR.Z = IsZeroBit(result);
13549 // APSR.C = carry;
13550 // APSR.V = overflow
13551 //
13552 // Default arguments can be specified for carry and overflow parameters, which means
13553 // not to update the respective flags.
13554 bool
13555 EmulateInstructionARM::WriteFlags (Context &context,
13556                                    const uint32_t result,
13557                                    const uint32_t carry,
13558                                    const uint32_t overflow)
13559 {
13560     m_new_inst_cpsr = m_opcode_cpsr;
13561     SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
13562     SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
13563     if (carry != ~0u)
13564         SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
13565     if (overflow != ~0u)
13566         SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
13567     if (m_new_inst_cpsr != m_opcode_cpsr)
13568     {
13569         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13570             return false;
13571     }
13572     return true;
13573 }
13574 
13575 bool
13576 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
13577 {
13578     // Advance the ITSTATE bits to their values for the next instruction.
13579     if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
13580         m_it_session.ITAdvance();
13581 
13582     ARMOpcode *opcode_data = NULL;
13583 
13584     if (m_opcode_mode == eModeThumb)
13585         opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13586     else if (m_opcode_mode == eModeARM)
13587         opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13588 
13589     if (opcode_data == NULL)
13590         return false;
13591 
13592     const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
13593     m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
13594 
13595     bool success = false;
13596     if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
13597     {
13598         m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF,
13599                                                 dwarf_cpsr,
13600                                                 0,
13601                                                 &success);
13602     }
13603 
13604     // Only return false if we are unable to read the CPSR if we care about conditions
13605     if (success == false && m_ignore_conditions == false)
13606         return false;
13607 
13608     uint32_t orig_pc_value = 0;
13609     if (auto_advance_pc)
13610     {
13611         orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13612         if (!success)
13613             return false;
13614     }
13615 
13616     // Call the Emulate... function.
13617     success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
13618     if (!success)
13619         return false;
13620 
13621     if (auto_advance_pc)
13622     {
13623         uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13624         if (!success)
13625             return false;
13626 
13627         if (auto_advance_pc && (after_pc_value == orig_pc_value))
13628         {
13629             if (opcode_data->size == eSize32)
13630                 after_pc_value += 4;
13631             else if (opcode_data->size == eSize16)
13632                 after_pc_value += 2;
13633 
13634             EmulateInstruction::Context context;
13635             context.type = eContextAdvancePC;
13636             context.SetNoArgs();
13637             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
13638                 return false;
13639 
13640         }
13641     }
13642     return true;
13643 }
13644 
13645 bool
13646 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data)
13647 {
13648     if (!test_data)
13649     {
13650         out_stream->Printf ("TestEmulation: Missing test data.\n");
13651         return false;
13652     }
13653 
13654     static ConstString opcode_key ("opcode");
13655     static ConstString before_key ("before_state");
13656     static ConstString after_key ("after_state");
13657 
13658     OptionValueSP value_sp = test_data->GetValueForKey (opcode_key);
13659 
13660     uint32_t test_opcode;
13661     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64))
13662     {
13663         out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n");
13664         return false;
13665     }
13666     test_opcode = value_sp->GetUInt64Value ();
13667 
13668     if (arch.GetTriple().getArch() == llvm::Triple::arm)
13669     {
13670         m_opcode_mode = eModeARM;
13671         m_opcode.SetOpcode32 (test_opcode, GetByteOrder());
13672     }
13673     else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
13674     {
13675         m_opcode_mode = eModeThumb;
13676         if (test_opcode < 0x10000)
13677             m_opcode.SetOpcode16 (test_opcode, GetByteOrder());
13678         else
13679             m_opcode.SetOpcode32 (test_opcode, GetByteOrder());
13680 
13681     }
13682     else
13683     {
13684         out_stream->Printf ("TestEmulation:  Invalid arch.\n");
13685         return false;
13686     }
13687 
13688     EmulationStateARM before_state;
13689     EmulationStateARM after_state;
13690 
13691     value_sp = test_data->GetValueForKey (before_key);
13692     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13693     {
13694         out_stream->Printf ("TestEmulation:  Failed to find 'before' state.\n");
13695         return false;
13696     }
13697 
13698     OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary ();
13699     if (!before_state.LoadStateFromDictionary (state_dictionary))
13700     {
13701         out_stream->Printf ("TestEmulation:  Failed loading 'before' state.\n");
13702         return false;
13703     }
13704 
13705     value_sp = test_data->GetValueForKey (after_key);
13706     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13707     {
13708         out_stream->Printf ("TestEmulation:  Failed to find 'after' state.\n");
13709         return false;
13710     }
13711 
13712     state_dictionary = value_sp->GetAsDictionary ();
13713     if (!after_state.LoadStateFromDictionary (state_dictionary))
13714     {
13715         out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n");
13716         return false;
13717     }
13718 
13719     SetBaton ((void *) &before_state);
13720     SetCallbacks (&EmulationStateARM::ReadPseudoMemory,
13721                   &EmulationStateARM::WritePseudoMemory,
13722                   &EmulationStateARM::ReadPseudoRegister,
13723                   &EmulationStateARM::WritePseudoRegister);
13724 
13725     bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC);
13726     if (!success)
13727     {
13728         out_stream->Printf ("TestEmulation:  EvaluateInstruction() failed.\n");
13729         return false;
13730     }
13731 
13732     success = before_state.CompareState (after_state);
13733     if (!success)
13734         out_stream->Printf ("TestEmulation:  'before' and 'after' states do not match.\n");
13735 
13736     return success;
13737 }
13738 //
13739 //
13740 //const char *
13741 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
13742 //{
13743 //    if (reg_kind == eRegisterKindGeneric)
13744 //    {
13745 //        switch (reg_num)
13746 //        {
13747 //        case LLDB_REGNUM_GENERIC_PC:    return "pc";
13748 //        case LLDB_REGNUM_GENERIC_SP:    return "sp";
13749 //        case LLDB_REGNUM_GENERIC_FP:    return "fp";
13750 //        case LLDB_REGNUM_GENERIC_RA:    return "lr";
13751 //        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
13752 //        default: return NULL;
13753 //        }
13754 //    }
13755 //    else if (reg_kind == eRegisterKindDWARF)
13756 //    {
13757 //        return GetARMDWARFRegisterName (reg_num);
13758 //    }
13759 //    return NULL;
13760 //}
13761 //
13762 bool
13763 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
13764 {
13765     unwind_plan.Clear();
13766     unwind_plan.SetRegisterKind (eRegisterKindDWARF);
13767 
13768     UnwindPlan::RowSP row(new UnwindPlan::Row);
13769 
13770     // Our previous Call Frame Address is the stack pointer
13771     row->GetCFAValue().SetIsRegisterPlusOffset (dwarf_sp, 0);
13772 
13773     unwind_plan.AppendRow (row);
13774     unwind_plan.SetSourceName ("EmulateInstructionARM");
13775     unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
13776     unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
13777     unwind_plan.SetReturnAddressRegister (dwarf_lr);
13778     return true;
13779 }
13780