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/Symbol/UnwindPlan.h"
20 
21 #include "Plugins/Process/Utility/ARMDefines.h"
22 #include "Plugins/Process/Utility/ARMUtils.h"
23 #include "Utility/ARM_DWARF_Registers.h"
24 
25 #include "llvm/Support/MathExtras.h" // for SignExtend32 template function
26                                      // and CountTrailingZeros_32 function
27 
28 using namespace lldb;
29 using namespace lldb_private;
30 
31 // Convenient macro definitions.
32 #define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS)
33 #define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS)
34 
35 #define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
36 
37 //----------------------------------------------------------------------
38 //
39 // ITSession implementation
40 //
41 //----------------------------------------------------------------------
42 
43 // A8.6.50
44 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
45 static uint32_t
46 CountITSize (uint32_t ITMask) {
47     // First count the trailing zeros of the IT mask.
48     uint32_t TZ = llvm::CountTrailingZeros_32(ITMask);
49     if (TZ > 3)
50     {
51         printf("Encoding error: IT Mask '0000'\n");
52         return 0;
53     }
54     return (4 - TZ);
55 }
56 
57 // Init ITState.  Note that at least one bit is always 1 in mask.
58 bool ITSession::InitIT(uint32_t bits7_0)
59 {
60     ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
61     if (ITCounter == 0)
62         return false;
63 
64     // A8.6.50 IT
65     unsigned short FirstCond = Bits32(bits7_0, 7, 4);
66     if (FirstCond == 0xF)
67     {
68         printf("Encoding error: IT FirstCond '1111'\n");
69         return false;
70     }
71     if (FirstCond == 0xE && ITCounter != 1)
72     {
73         printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
74         return false;
75     }
76 
77     ITState = bits7_0;
78     return true;
79 }
80 
81 // Update ITState if necessary.
82 void ITSession::ITAdvance()
83 {
84     //assert(ITCounter);
85     --ITCounter;
86     if (ITCounter == 0)
87         ITState = 0;
88     else
89     {
90         unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
91         SetBits32(ITState, 4, 0, NewITState4_0);
92     }
93 }
94 
95 // Return true if we're inside an IT Block.
96 bool ITSession::InITBlock()
97 {
98     return ITCounter != 0;
99 }
100 
101 // Return true if we're the last instruction inside an IT Block.
102 bool ITSession::LastInITBlock()
103 {
104     return ITCounter == 1;
105 }
106 
107 // Get condition bits for the current thumb instruction.
108 uint32_t ITSession::GetCond()
109 {
110     if (InITBlock())
111         return Bits32(ITState, 7, 4);
112     else
113         return COND_AL;
114 }
115 
116 // ARM constants used during decoding
117 #define REG_RD          0
118 #define LDM_REGLIST     1
119 #define SP_REG          13
120 #define LR_REG          14
121 #define PC_REG          15
122 #define PC_REGLIST_BIT  0x8000
123 
124 #define ARMv4     (1u << 0)
125 #define ARMv4T    (1u << 1)
126 #define ARMv5T    (1u << 2)
127 #define ARMv5TE   (1u << 3)
128 #define ARMv5TEJ  (1u << 4)
129 #define ARMv6     (1u << 5)
130 #define ARMv6K    (1u << 6)
131 #define ARMv6T2   (1u << 7)
132 #define ARMv7     (1u << 8)
133 #define ARMv8     (1u << 9)
134 #define ARMvAll   (0xffffffffu)
135 
136 #define ARMV4T_ABOVE  (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
137 #define ARMV5_ABOVE   (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
138 #define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
139 #define ARMV5J_ABOVE  (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
140 #define ARMV6_ABOVE   (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
141 #define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv8)
142 #define ARMV7_ABOVE   (ARMv7|ARMv8)
143 
144 #define No_VFP  0
145 #define VFPv1   (1u << 1)
146 #define VFPv2   (1u << 2)
147 #define VFPv3   (1u << 3)
148 #define AdvancedSIMD (1u << 4)
149 
150 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
151 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
152 #define VFPv2v3     (VFPv2 | VFPv3)
153 
154 //----------------------------------------------------------------------
155 //
156 // EmulateInstructionARM implementation
157 //
158 //----------------------------------------------------------------------
159 
160 void
161 EmulateInstructionARM::Initialize ()
162 {
163     PluginManager::RegisterPlugin (GetPluginNameStatic (),
164                                    GetPluginDescriptionStatic (),
165                                    CreateInstance);
166 }
167 
168 void
169 EmulateInstructionARM::Terminate ()
170 {
171     PluginManager::UnregisterPlugin (CreateInstance);
172 }
173 
174 const char *
175 EmulateInstructionARM::GetPluginNameStatic ()
176 {
177     return "lldb.emulate-instruction.arm";
178 }
179 
180 const char *
181 EmulateInstructionARM::GetPluginDescriptionStatic ()
182 {
183     return "Emulate instructions for the ARM architecture.";
184 }
185 
186 EmulateInstruction *
187 EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type)
188 {
189     if (EmulateInstructionARM::SupportsEmulatingIntructionsOfTypeStatic(inst_type))
190     {
191         if (arch.GetTriple().getArch() == llvm::Triple::arm)
192         {
193             std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
194 
195             if (emulate_insn_ap.get())
196                 return emulate_insn_ap.release();
197         }
198         else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
199         {
200             std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
201 
202             if (emulate_insn_ap.get())
203                 return emulate_insn_ap.release();
204         }
205     }
206 
207     return NULL;
208 }
209 
210 bool
211 EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch)
212 {
213     if (arch.GetTriple().getArch () == llvm::Triple::arm)
214         return true;
215     else if (arch.GetTriple().getArch () == llvm::Triple::thumb)
216         return true;
217 
218     return false;
219 }
220 
221 // Write "bits (32) UNKNOWN" to memory address "address".  Helper function for many ARM instructions.
222 bool
223 EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address)
224 {
225     EmulateInstruction::Context context;
226     context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
227     context.SetNoArgs ();
228 
229     uint32_t random_data = rand ();
230     const uint32_t addr_byte_size = GetAddressByteSize();
231 
232     if (!MemAWrite (context, address, random_data, addr_byte_size))
233         return false;
234 
235     return true;
236 }
237 
238 // Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM instructions.
239 bool
240 EmulateInstructionARM::WriteBits32Unknown (int n)
241 {
242     EmulateInstruction::Context context;
243     context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
244     context.SetNoArgs ();
245 
246     bool success;
247     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
248 
249     if (!success)
250         return false;
251 
252     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
253         return false;
254 
255     return true;
256 }
257 
258 bool
259 EmulateInstructionARM::GetRegisterInfo (uint32_t reg_kind, uint32_t reg_num, RegisterInfo &reg_info)
260 {
261     if (reg_kind == eRegisterKindGeneric)
262     {
263         switch (reg_num)
264         {
265             case LLDB_REGNUM_GENERIC_PC:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break;
266             case LLDB_REGNUM_GENERIC_SP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break;
267             case LLDB_REGNUM_GENERIC_FP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break;
268             case LLDB_REGNUM_GENERIC_RA:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break;
269             case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break;
270             default: return false;
271         }
272     }
273 
274     if (reg_kind == eRegisterKindDWARF)
275         return GetARMDWARFRegisterInfo(reg_num, reg_info);
276     return false;
277 }
278 
279 uint32_t
280 EmulateInstructionARM::GetFramePointerRegisterNumber () const
281 {
282     if (m_opcode_mode == eModeThumb || m_arch.GetTriple().getOS() == llvm::Triple::Darwin)
283         return 7;
284     else
285         return 11;
286 }
287 
288 uint32_t
289 EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const
290 {
291     if (m_opcode_mode == eModeThumb || m_arch.GetTriple().getOS() == llvm::Triple::Darwin)
292         return dwarf_r7;
293     else
294         return dwarf_r11;
295 }
296 
297 // Push Multiple Registers stores multiple registers to the stack, storing to
298 // consecutive memory locations ending just below the address in SP, and updates
299 // SP to point to the start of the stored data.
300 bool
301 EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding)
302 {
303 #if 0
304     // ARM pseudo code...
305     if (ConditionPassed())
306     {
307         EncodingSpecificOperations();
308         NullCheckIfThumbEE(13);
309         address = SP - 4*BitCount(registers);
310 
311         for (i = 0 to 14)
312         {
313             if (registers<i> == '1')
314             {
315                 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
316                     MemA[address,4] = bits(32) UNKNOWN;
317                 else
318                     MemA[address,4] = R[i];
319                 address = address + 4;
320             }
321         }
322 
323         if (registers<15> == '1') // Only possible for encoding A1 or A2
324             MemA[address,4] = PCStoreValue();
325 
326         SP = SP - 4*BitCount(registers);
327     }
328 #endif
329 
330     bool conditional = false;
331     bool success = false;
332     if (ConditionPassed(opcode, &conditional))
333     {
334         const uint32_t addr_byte_size = GetAddressByteSize();
335         const addr_t sp = ReadCoreReg (SP_REG, &success);
336         if (!success)
337             return false;
338         uint32_t registers = 0;
339         uint32_t Rt; // the source register
340         switch (encoding) {
341         case eEncodingT1:
342             registers = Bits32(opcode, 7, 0);
343             // The M bit represents LR.
344             if (Bit32(opcode, 8))
345                 registers |= (1u << 14);
346             // if BitCount(registers) < 1 then UNPREDICTABLE;
347             if (BitCount(registers) < 1)
348                 return false;
349             break;
350         case eEncodingT2:
351             // Ignore bits 15 & 13.
352             registers = Bits32(opcode, 15, 0) & ~0xa000;
353             // if BitCount(registers) < 2 then UNPREDICTABLE;
354             if (BitCount(registers) < 2)
355                 return false;
356             break;
357         case eEncodingT3:
358             Rt = Bits32(opcode, 15, 12);
359             // if BadReg(t) then UNPREDICTABLE;
360             if (BadReg(Rt))
361                 return false;
362             registers = (1u << Rt);
363             break;
364         case eEncodingA1:
365             registers = Bits32(opcode, 15, 0);
366             // Instead of return false, let's handle the following case as well,
367             // which amounts to pushing one reg onto the full descending stacks.
368             // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
369             break;
370         case eEncodingA2:
371             Rt = Bits32(opcode, 15, 12);
372             // if t == 13 then UNPREDICTABLE;
373             if (Rt == dwarf_sp)
374                 return false;
375             registers = (1u << Rt);
376             break;
377         default:
378             return false;
379         }
380         addr_t sp_offset = addr_byte_size * BitCount (registers);
381         addr_t addr = sp - sp_offset;
382         uint32_t i;
383 
384         EmulateInstruction::Context context;
385         if (conditional)
386             context.type = EmulateInstruction::eContextRegisterStore;
387         else
388             context.type = EmulateInstruction::eContextPushRegisterOnStack;
389         RegisterInfo reg_info;
390         RegisterInfo sp_reg;
391         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
392         for (i=0; i<15; ++i)
393         {
394             if (BitIsSet (registers, i))
395             {
396                 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info);
397                 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
398                 uint32_t reg_value = ReadCoreReg(i, &success);
399                 if (!success)
400                     return false;
401                 if (!MemAWrite (context, addr, reg_value, addr_byte_size))
402                     return false;
403                 addr += addr_byte_size;
404             }
405         }
406 
407         if (BitIsSet (registers, 15))
408         {
409             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info);
410             context.SetRegisterPlusOffset (reg_info, addr - sp);
411             const uint32_t pc = ReadCoreReg(PC_REG, &success);
412             if (!success)
413                 return false;
414             if (!MemAWrite (context, addr, pc, addr_byte_size))
415                 return false;
416         }
417 
418         context.type = EmulateInstruction::eContextAdjustStackPointer;
419         context.SetImmediateSigned (-sp_offset);
420 
421         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
422             return false;
423     }
424     return true;
425 }
426 
427 // Pop Multiple Registers loads multiple registers from the stack, loading from
428 // consecutive memory locations staring at the address in SP, and updates
429 // SP to point just above the loaded data.
430 bool
431 EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding)
432 {
433 #if 0
434     // ARM pseudo code...
435     if (ConditionPassed())
436     {
437         EncodingSpecificOperations(); NullCheckIfThumbEE(13);
438         address = SP;
439         for i = 0 to 14
440             if registers<i> == '1' then
441                 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
442         if registers<15> == '1' then
443             if UnalignedAllowed then
444                 LoadWritePC(MemU[address,4]);
445             else
446                 LoadWritePC(MemA[address,4]);
447         if registers<13> == '0' then SP = SP + 4*BitCount(registers);
448         if registers<13> == '1' then SP = bits(32) UNKNOWN;
449     }
450 #endif
451 
452     bool success = false;
453 
454     bool conditional = false;
455     if (ConditionPassed(opcode, &conditional))
456     {
457         const uint32_t addr_byte_size = GetAddressByteSize();
458         const addr_t sp = ReadCoreReg (SP_REG, &success);
459         if (!success)
460             return false;
461         uint32_t registers = 0;
462         uint32_t Rt; // the destination register
463         switch (encoding) {
464         case eEncodingT1:
465             registers = Bits32(opcode, 7, 0);
466             // The P bit represents PC.
467             if (Bit32(opcode, 8))
468                 registers |= (1u << 15);
469             // if BitCount(registers) < 1 then UNPREDICTABLE;
470             if (BitCount(registers) < 1)
471                 return false;
472             break;
473         case eEncodingT2:
474             // Ignore bit 13.
475             registers = Bits32(opcode, 15, 0) & ~0x2000;
476             // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
477             if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
478                 return false;
479             // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
480             if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
481                 return false;
482             break;
483         case eEncodingT3:
484             Rt = Bits32(opcode, 15, 12);
485             // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
486             if (Rt == 13)
487                 return false;
488             if (Rt == 15 && InITBlock() && !LastInITBlock())
489                 return false;
490             registers = (1u << Rt);
491             break;
492         case eEncodingA1:
493             registers = Bits32(opcode, 15, 0);
494             // Instead of return false, let's handle the following case as well,
495             // which amounts to popping one reg from the full descending stacks.
496             // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
497 
498             // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
499             if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
500                 return false;
501             break;
502         case eEncodingA2:
503             Rt = Bits32(opcode, 15, 12);
504             // if t == 13 then UNPREDICTABLE;
505             if (Rt == dwarf_sp)
506                 return false;
507             registers = (1u << Rt);
508             break;
509         default:
510             return false;
511         }
512         addr_t sp_offset = addr_byte_size * BitCount (registers);
513         addr_t addr = sp;
514         uint32_t i, data;
515 
516         EmulateInstruction::Context context;
517         if (conditional)
518             context.type = EmulateInstruction::eContextRegisterLoad;
519         else
520             context.type = EmulateInstruction::eContextPopRegisterOffStack;
521 
522         RegisterInfo sp_reg;
523         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
524 
525         for (i=0; i<15; ++i)
526         {
527             if (BitIsSet (registers, i))
528             {
529                 context.SetRegisterPlusOffset (sp_reg, addr - sp);
530                 data = MemARead(context, addr, 4, 0, &success);
531                 if (!success)
532                     return false;
533                 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data))
534                     return false;
535                 addr += addr_byte_size;
536             }
537         }
538 
539         if (BitIsSet (registers, 15))
540         {
541             context.SetRegisterPlusOffset (sp_reg, addr - sp);
542             data = MemARead(context, addr, 4, 0, &success);
543             if (!success)
544                 return false;
545             // In ARMv5T and above, this is an interworking branch.
546             if (!LoadWritePC(context, data))
547                 return false;
548             addr += addr_byte_size;
549         }
550 
551         context.type = EmulateInstruction::eContextAdjustStackPointer;
552         context.SetImmediateSigned (sp_offset);
553 
554         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
555             return false;
556     }
557     return true;
558 }
559 
560 // Set r7 or ip to point to saved value residing within the stack.
561 // ADD (SP plus immediate)
562 bool
563 EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding)
564 {
565 #if 0
566     // ARM pseudo code...
567     if (ConditionPassed())
568     {
569         EncodingSpecificOperations();
570         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
571         if d == 15 then
572            ALUWritePC(result); // setflags is always FALSE here
573         else
574             R[d] = result;
575             if setflags then
576                 APSR.N = result<31>;
577                 APSR.Z = IsZeroBit(result);
578                 APSR.C = carry;
579                 APSR.V = overflow;
580     }
581 #endif
582 
583     bool success = false;
584 
585     if (ConditionPassed(opcode))
586     {
587         const addr_t sp = ReadCoreReg (SP_REG, &success);
588         if (!success)
589             return false;
590         uint32_t Rd; // the destination register
591         uint32_t imm32;
592         switch (encoding) {
593         case eEncodingT1:
594             Rd = 7;
595             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
596             break;
597         case eEncodingA1:
598             Rd = Bits32(opcode, 15, 12);
599             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
600             break;
601         default:
602             return false;
603         }
604         addr_t sp_offset = imm32;
605         addr_t addr = sp + sp_offset; // a pointer to the stack area
606 
607         EmulateInstruction::Context context;
608         context.type = eContextSetFramePointer;
609         RegisterInfo sp_reg;
610         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
611         context.SetRegisterPlusOffset (sp_reg, sp_offset);
612 
613         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
614             return false;
615     }
616     return true;
617 }
618 
619 // Set r7 or ip to the current stack pointer.
620 // MOV (register)
621 bool
622 EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding)
623 {
624 #if 0
625     // ARM pseudo code...
626     if (ConditionPassed())
627     {
628         EncodingSpecificOperations();
629         result = R[m];
630         if d == 15 then
631             ALUWritePC(result); // setflags is always FALSE here
632         else
633             R[d] = result;
634             if setflags then
635                 APSR.N = result<31>;
636                 APSR.Z = IsZeroBit(result);
637                 // APSR.C unchanged
638                 // APSR.V unchanged
639     }
640 #endif
641 
642     bool success = false;
643 
644     if (ConditionPassed(opcode))
645     {
646         const addr_t sp = ReadCoreReg (SP_REG, &success);
647         if (!success)
648             return false;
649         uint32_t Rd; // the destination register
650         switch (encoding) {
651         case eEncodingT1:
652             Rd = 7;
653             break;
654         case eEncodingA1:
655             Rd = 12;
656             break;
657         default:
658             return false;
659         }
660 
661         EmulateInstruction::Context context;
662         if (Rd == GetFramePointerRegisterNumber())
663             context.type = EmulateInstruction::eContextSetFramePointer;
664         else
665             context.type = EmulateInstruction::eContextRegisterPlusOffset;
666         RegisterInfo sp_reg;
667         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
668         context.SetRegisterPlusOffset (sp_reg, 0);
669 
670         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
671             return false;
672     }
673     return true;
674 }
675 
676 // Move from high register (r8-r15) to low register (r0-r7).
677 // MOV (register)
678 bool
679 EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding)
680 {
681     return EmulateMOVRdRm (opcode, encoding);
682 }
683 
684 // Move from register to register.
685 // MOV (register)
686 bool
687 EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding)
688 {
689 #if 0
690     // ARM pseudo code...
691     if (ConditionPassed())
692     {
693         EncodingSpecificOperations();
694         result = R[m];
695         if d == 15 then
696             ALUWritePC(result); // setflags is always FALSE here
697         else
698             R[d] = result;
699             if setflags then
700                 APSR.N = result<31>;
701                 APSR.Z = IsZeroBit(result);
702                 // APSR.C unchanged
703                 // APSR.V unchanged
704     }
705 #endif
706 
707     bool success = false;
708 
709     if (ConditionPassed(opcode))
710     {
711         uint32_t Rm; // the source register
712         uint32_t Rd; // the destination register
713         bool setflags;
714         switch (encoding) {
715         case eEncodingT1:
716             Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
717             Rm = Bits32(opcode, 6, 3);
718             setflags = false;
719             if (Rd == 15 && InITBlock() && !LastInITBlock())
720                 return false;
721             break;
722         case eEncodingT2:
723             Rd = Bits32(opcode, 2, 0);
724             Rm = Bits32(opcode, 5, 3);
725             setflags = true;
726             if (InITBlock())
727                 return false;
728             break;
729         case eEncodingT3:
730             Rd = Bits32(opcode, 11, 8);
731             Rm = Bits32(opcode, 3, 0);
732             setflags = BitIsSet(opcode, 20);
733             // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
734             if (setflags && (BadReg(Rd) || BadReg(Rm)))
735                 return false;
736             // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE;
737             if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
738                 return false;
739             break;
740         case eEncodingA1:
741             Rd = Bits32(opcode, 15, 12);
742             Rm = Bits32(opcode, 3, 0);
743             setflags = BitIsSet(opcode, 20);
744 
745             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
746             if (Rd == 15 && setflags)
747                 return EmulateSUBSPcLrEtc (opcode, encoding);
748             break;
749         default:
750             return false;
751         }
752         uint32_t result = ReadCoreReg(Rm, &success);
753         if (!success)
754             return false;
755 
756         // The context specifies that Rm is to be moved into Rd.
757         EmulateInstruction::Context context;
758         context.type = EmulateInstruction::eContextRegisterLoad;
759         RegisterInfo dwarf_reg;
760         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
761         context.SetRegister (dwarf_reg);
762 
763         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
764             return false;
765     }
766     return true;
767 }
768 
769 // Move (immediate) writes an immediate value to the destination register.  It
770 // can optionally update the condition flags based on the value.
771 // MOV (immediate)
772 bool
773 EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding)
774 {
775 #if 0
776     // ARM pseudo code...
777     if (ConditionPassed())
778     {
779         EncodingSpecificOperations();
780         result = imm32;
781         if d == 15 then         // Can only occur for ARM encoding
782             ALUWritePC(result); // setflags is always FALSE here
783         else
784             R[d] = result;
785             if setflags then
786                 APSR.N = result<31>;
787                 APSR.Z = IsZeroBit(result);
788                 APSR.C = carry;
789                 // APSR.V unchanged
790     }
791 #endif
792 
793     if (ConditionPassed(opcode))
794     {
795         uint32_t Rd; // the destination register
796         uint32_t imm32; // the immediate value to be written to Rd
797         uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
798                             // for setflags == false, this value is a don't care
799                             // initialized to 0 to silence the static analyzer
800         bool setflags;
801         switch (encoding) {
802             case eEncodingT1:
803                 Rd = Bits32(opcode, 10, 8);
804                 setflags = !InITBlock();
805                 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
806                 carry = APSR_C;
807 
808                 break;
809 
810             case eEncodingT2:
811                 Rd = Bits32(opcode, 11, 8);
812                 setflags = BitIsSet(opcode, 20);
813                 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
814                 if (BadReg(Rd))
815                   return false;
816 
817                 break;
818 
819             case eEncodingT3:
820             {
821                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32);
822                 Rd = Bits32 (opcode, 11, 8);
823                 setflags = false;
824                 uint32_t imm4 = Bits32 (opcode, 19, 16);
825                 uint32_t imm3 = Bits32 (opcode, 14, 12);
826                 uint32_t i = Bit32 (opcode, 26);
827                 uint32_t imm8 = Bits32 (opcode, 7, 0);
828                 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
829 
830                 // if BadReg(d) then UNPREDICTABLE;
831                 if (BadReg (Rd))
832                     return false;
833             }
834                 break;
835 
836             case eEncodingA1:
837                 // d = UInt(Rd); setflags = (S == �1�); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C);
838                 Rd = Bits32 (opcode, 15, 12);
839                 setflags = BitIsSet (opcode, 20);
840                 imm32 = ARMExpandImm_C (opcode, APSR_C, carry);
841 
842                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
843                 if ((Rd == 15) && setflags)
844                     return EmulateSUBSPcLrEtc (opcode, encoding);
845 
846                 break;
847 
848             case eEncodingA2:
849             {
850                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
851                 Rd = Bits32 (opcode, 15, 12);
852                 setflags = false;
853                 uint32_t imm4 = Bits32 (opcode, 19, 16);
854                 uint32_t imm12 = Bits32 (opcode, 11, 0);
855                 imm32 = (imm4 << 12) | imm12;
856 
857                 // if d == 15 then UNPREDICTABLE;
858                 if (Rd == 15)
859                     return false;
860             }
861                 break;
862 
863             default:
864                 return false;
865         }
866         uint32_t result = imm32;
867 
868         // The context specifies that an immediate is to be moved into Rd.
869         EmulateInstruction::Context context;
870         context.type = EmulateInstruction::eContextImmediate;
871         context.SetNoArgs ();
872 
873         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
874             return false;
875     }
876     return true;
877 }
878 
879 // MUL multiplies two register values.  The least significant 32 bits of the result are written to the destination
880 // register.  These 32 bits do not depend on whether the source register values are considered to be signed values or
881 // unsigned values.
882 //
883 // Optionally, it can update the condition flags based on the result.  In the Thumb instruction set, this option is
884 // limited to only a few forms of the instruction.
885 bool
886 EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding)
887 {
888 #if 0
889     if ConditionPassed() then
890         EncodingSpecificOperations();
891         operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
892         operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
893         result = operand1 * operand2;
894         R[d] = result<31:0>;
895         if setflags then
896             APSR.N = result<31>;
897             APSR.Z = IsZeroBit(result);
898             if ArchVersion() == 4 then
899                 APSR.C = bit UNKNOWN;
900             // else APSR.C unchanged
901             // APSR.V always unchanged
902 #endif
903 
904     if (ConditionPassed(opcode))
905     {
906         uint32_t d;
907         uint32_t n;
908         uint32_t m;
909         bool setflags;
910 
911         // EncodingSpecificOperations();
912         switch (encoding)
913         {
914             case eEncodingT1:
915                 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
916                 d = Bits32 (opcode, 2, 0);
917                 n = Bits32 (opcode, 5, 3);
918                 m = Bits32 (opcode, 2, 0);
919                 setflags = !InITBlock();
920 
921                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
922                 if ((ArchVersion() < ARMv6) && (d == n))
923                     return false;
924 
925                 break;
926 
927             case eEncodingT2:
928                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
929                 d = Bits32 (opcode, 11, 8);
930                 n = Bits32 (opcode, 19, 16);
931                 m = Bits32 (opcode, 3, 0);
932                 setflags = false;
933 
934                 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
935                 if (BadReg (d) || BadReg (n) || BadReg (m))
936                     return false;
937 
938                 break;
939 
940             case eEncodingA1:
941                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
942                 d = Bits32 (opcode, 19, 16);
943                 n = Bits32 (opcode, 3, 0);
944                 m = Bits32 (opcode, 11, 8);
945                 setflags = BitIsSet (opcode, 20);
946 
947                 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
948                 if ((d == 15) ||  (n == 15) || (m == 15))
949                     return false;
950 
951                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
952                 if ((ArchVersion() < ARMv6) && (d == n))
953                     return false;
954 
955                 break;
956 
957             default:
958                 return false;
959         }
960 
961         bool success = false;
962 
963         // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
964         uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
965         if (!success)
966             return false;
967 
968         // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
969         uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
970         if (!success)
971             return false;
972 
973         // result = operand1 * operand2;
974         uint64_t result = operand1 * operand2;
975 
976         // R[d] = result<31:0>;
977         RegisterInfo op1_reg;
978         RegisterInfo op2_reg;
979         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
980         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
981 
982         EmulateInstruction::Context context;
983         context.type = eContextArithmetic;
984         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
985 
986         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result)))
987             return false;
988 
989         // if setflags then
990         if (setflags)
991         {
992             // APSR.N = result<31>;
993             // APSR.Z = IsZeroBit(result);
994             m_new_inst_cpsr = m_opcode_cpsr;
995             SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31));
996             SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
997             if (m_new_inst_cpsr != m_opcode_cpsr)
998             {
999                 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1000                     return false;
1001             }
1002 
1003             // if ArchVersion() == 4 then
1004                 // APSR.C = bit UNKNOWN;
1005         }
1006     }
1007     return true;
1008 }
1009 
1010 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register.
1011 // It can optionally update the condition flags based on the value.
1012 bool
1013 EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding)
1014 {
1015 #if 0
1016     // ARM pseudo code...
1017     if (ConditionPassed())
1018     {
1019         EncodingSpecificOperations();
1020         result = NOT(imm32);
1021         if d == 15 then         // Can only occur for ARM encoding
1022             ALUWritePC(result); // setflags is always FALSE here
1023         else
1024             R[d] = result;
1025             if setflags then
1026                 APSR.N = result<31>;
1027                 APSR.Z = IsZeroBit(result);
1028                 APSR.C = carry;
1029                 // APSR.V unchanged
1030     }
1031 #endif
1032 
1033     if (ConditionPassed(opcode))
1034     {
1035         uint32_t Rd; // the destination register
1036         uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1037         uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1038         bool setflags;
1039         switch (encoding) {
1040         case eEncodingT1:
1041             Rd = Bits32(opcode, 11, 8);
1042             setflags = BitIsSet(opcode, 20);
1043             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1044             break;
1045         case eEncodingA1:
1046             Rd = Bits32(opcode, 15, 12);
1047             setflags = BitIsSet(opcode, 20);
1048             imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1049 
1050             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1051             if (Rd == 15 && setflags)
1052                 return EmulateSUBSPcLrEtc (opcode, encoding);
1053             break;
1054         default:
1055             return false;
1056         }
1057         uint32_t result = ~imm32;
1058 
1059         // The context specifies that an immediate is to be moved into Rd.
1060         EmulateInstruction::Context context;
1061         context.type = EmulateInstruction::eContextImmediate;
1062         context.SetNoArgs ();
1063 
1064         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1065             return false;
1066     }
1067     return true;
1068 }
1069 
1070 // Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register.
1071 // It can optionally update the condition flags based on the result.
1072 bool
1073 EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding)
1074 {
1075 #if 0
1076     // ARM pseudo code...
1077     if (ConditionPassed())
1078     {
1079         EncodingSpecificOperations();
1080         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1081         result = NOT(shifted);
1082         if d == 15 then         // Can only occur for ARM encoding
1083             ALUWritePC(result); // setflags is always FALSE here
1084         else
1085             R[d] = result;
1086             if setflags then
1087                 APSR.N = result<31>;
1088                 APSR.Z = IsZeroBit(result);
1089                 APSR.C = carry;
1090                 // APSR.V unchanged
1091     }
1092 #endif
1093 
1094     if (ConditionPassed(opcode))
1095     {
1096         uint32_t Rm; // the source register
1097         uint32_t Rd; // the destination register
1098         ARM_ShifterType shift_t;
1099         uint32_t shift_n; // the shift applied to the value read from Rm
1100         bool setflags;
1101         uint32_t carry; // the carry bit after the shift operation
1102         switch (encoding) {
1103         case eEncodingT1:
1104             Rd = Bits32(opcode, 2, 0);
1105             Rm = Bits32(opcode, 5, 3);
1106             setflags = !InITBlock();
1107             shift_t = SRType_LSL;
1108             shift_n = 0;
1109             if (InITBlock())
1110                 return false;
1111             break;
1112         case eEncodingT2:
1113             Rd = Bits32(opcode, 11, 8);
1114             Rm = Bits32(opcode, 3, 0);
1115             setflags = BitIsSet(opcode, 20);
1116             shift_n = DecodeImmShiftThumb(opcode, shift_t);
1117             // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1118             if (BadReg(Rd) || BadReg(Rm))
1119                 return false;
1120             break;
1121         case eEncodingA1:
1122             Rd = Bits32(opcode, 15, 12);
1123             Rm = Bits32(opcode, 3, 0);
1124             setflags = BitIsSet(opcode, 20);
1125             shift_n = DecodeImmShiftARM(opcode, shift_t);
1126             break;
1127         default:
1128             return false;
1129         }
1130         bool success = false;
1131         uint32_t value = ReadCoreReg(Rm, &success);
1132         if (!success)
1133             return false;
1134 
1135         uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1136         if (!success)
1137             return false;
1138         uint32_t result = ~shifted;
1139 
1140         // The context specifies that an immediate is to be moved into Rd.
1141         EmulateInstruction::Context context;
1142         context.type = EmulateInstruction::eContextImmediate;
1143         context.SetNoArgs ();
1144 
1145         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1146             return false;
1147     }
1148     return true;
1149 }
1150 
1151 // PC relative immediate load into register, possibly followed by ADD (SP plus register).
1152 // LDR (literal)
1153 bool
1154 EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding)
1155 {
1156 #if 0
1157     // ARM pseudo code...
1158     if (ConditionPassed())
1159     {
1160         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1161         base = Align(PC,4);
1162         address = if add then (base + imm32) else (base - imm32);
1163         data = MemU[address,4];
1164         if t == 15 then
1165             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1166         elsif UnalignedSupport() || address<1:0> = '00' then
1167             R[t] = data;
1168         else // Can only apply before ARMv7
1169             if CurrentInstrSet() == InstrSet_ARM then
1170                 R[t] = ROR(data, 8*UInt(address<1:0>));
1171             else
1172                 R[t] = bits(32) UNKNOWN;
1173     }
1174 #endif
1175 
1176     if (ConditionPassed(opcode))
1177     {
1178         bool success = false;
1179         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1180         if (!success)
1181             return false;
1182 
1183         // PC relative immediate load context
1184         EmulateInstruction::Context context;
1185         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1186         RegisterInfo pc_reg;
1187         GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
1188         context.SetRegisterPlusOffset (pc_reg, 0);
1189 
1190         uint32_t Rt;    // the destination register
1191         uint32_t imm32; // immediate offset from the PC
1192         bool add;       // +imm32 or -imm32?
1193         addr_t base;    // the base address
1194         addr_t address; // the PC relative address
1195         uint32_t data;  // the literal data value from the PC relative load
1196         switch (encoding) {
1197         case eEncodingT1:
1198             Rt = Bits32(opcode, 10, 8);
1199             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1200             add = true;
1201             break;
1202         case eEncodingT2:
1203             Rt = Bits32(opcode, 15, 12);
1204             imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1205             add = BitIsSet(opcode, 23);
1206             if (Rt == 15 && InITBlock() && !LastInITBlock())
1207                 return false;
1208             break;
1209         default:
1210             return false;
1211         }
1212 
1213         base = Align(pc, 4);
1214         if (add)
1215             address = base + imm32;
1216         else
1217             address = base - imm32;
1218 
1219         context.SetRegisterPlusOffset(pc_reg, address - base);
1220         data = MemURead(context, address, 4, 0, &success);
1221         if (!success)
1222             return false;
1223 
1224         if (Rt == 15)
1225         {
1226             if (Bits32(address, 1, 0) == 0)
1227             {
1228                 // In ARMv5T and above, this is an interworking branch.
1229                 if (!LoadWritePC(context, data))
1230                     return false;
1231             }
1232             else
1233                 return false;
1234         }
1235         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
1236         {
1237             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
1238                 return false;
1239         }
1240         else // We don't handle ARM for now.
1241             return false;
1242 
1243     }
1244     return true;
1245 }
1246 
1247 // An add operation to adjust the SP.
1248 // ADD (SP plus immediate)
1249 bool
1250 EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding)
1251 {
1252 #if 0
1253     // ARM pseudo code...
1254     if (ConditionPassed())
1255     {
1256         EncodingSpecificOperations();
1257         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1258         if d == 15 then // Can only occur for ARM encoding
1259             ALUWritePC(result); // setflags is always FALSE here
1260         else
1261             R[d] = result;
1262             if setflags then
1263                 APSR.N = result<31>;
1264                 APSR.Z = IsZeroBit(result);
1265                 APSR.C = carry;
1266                 APSR.V = overflow;
1267     }
1268 #endif
1269 
1270     bool success = false;
1271 
1272     if (ConditionPassed(opcode))
1273     {
1274         const addr_t sp = ReadCoreReg (SP_REG, &success);
1275         if (!success)
1276             return false;
1277         uint32_t imm32; // the immediate operand
1278         uint32_t d;
1279         bool setflags;
1280         switch (encoding)
1281         {
1282             case eEncodingT1:
1283                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1284                 d = Bits32 (opcode, 10, 8);
1285                 setflags = false;
1286                 imm32 = (Bits32 (opcode, 7, 0) << 2);
1287 
1288                 break;
1289 
1290             case eEncodingT2:
1291                 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1292                 d = 13;
1293                 setflags = false;
1294                 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1295 
1296                 break;
1297 
1298             default:
1299                 return false;
1300         }
1301         addr_t sp_offset = imm32;
1302         addr_t addr = sp + sp_offset; // the adjusted stack pointer value
1303 
1304         EmulateInstruction::Context context;
1305         context.type = EmulateInstruction::eContextAdjustStackPointer;
1306         RegisterInfo sp_reg;
1307         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1308         context.SetRegisterPlusOffset (sp_reg, sp_offset);
1309 
1310         if (d == 15)
1311         {
1312             if (!ALUWritePC (context, addr))
1313                 return false;
1314         }
1315         else
1316         {
1317             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr))
1318                 return false;
1319         }
1320     }
1321     return true;
1322 }
1323 
1324 // An add operation to adjust the SP.
1325 // ADD (SP plus register)
1326 bool
1327 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding)
1328 {
1329 #if 0
1330     // ARM pseudo code...
1331     if (ConditionPassed())
1332     {
1333         EncodingSpecificOperations();
1334         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1335         (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1336         if d == 15 then
1337             ALUWritePC(result); // setflags is always FALSE here
1338         else
1339             R[d] = result;
1340             if setflags then
1341                 APSR.N = result<31>;
1342                 APSR.Z = IsZeroBit(result);
1343                 APSR.C = carry;
1344                 APSR.V = overflow;
1345     }
1346 #endif
1347 
1348     bool success = false;
1349 
1350     if (ConditionPassed(opcode))
1351     {
1352         const addr_t sp = ReadCoreReg (SP_REG, &success);
1353         if (!success)
1354             return false;
1355         uint32_t Rm; // the second operand
1356         switch (encoding) {
1357         case eEncodingT2:
1358             Rm = Bits32(opcode, 6, 3);
1359             break;
1360         default:
1361             return false;
1362         }
1363         int32_t reg_value = ReadCoreReg(Rm, &success);
1364         if (!success)
1365             return false;
1366 
1367         addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1368 
1369         EmulateInstruction::Context context;
1370         context.type = eContextArithmetic;
1371         RegisterInfo sp_reg;
1372         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1373 
1374         RegisterInfo other_reg;
1375         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1376         context.SetRegisterRegisterOperands (sp_reg, other_reg);
1377 
1378         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
1379             return false;
1380     }
1381     return true;
1382 }
1383 
1384 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
1385 // at a PC-relative address, and changes instruction set from ARM to Thumb, or
1386 // from Thumb to ARM.
1387 // BLX (immediate)
1388 bool
1389 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding)
1390 {
1391 #if 0
1392     // ARM pseudo code...
1393     if (ConditionPassed())
1394     {
1395         EncodingSpecificOperations();
1396         if CurrentInstrSet() == InstrSet_ARM then
1397             LR = PC - 4;
1398         else
1399             LR = PC<31:1> : '1';
1400         if targetInstrSet == InstrSet_ARM then
1401             targetAddress = Align(PC,4) + imm32;
1402         else
1403             targetAddress = PC + imm32;
1404         SelectInstrSet(targetInstrSet);
1405         BranchWritePC(targetAddress);
1406     }
1407 #endif
1408 
1409     bool success = true;
1410 
1411     if (ConditionPassed(opcode))
1412     {
1413         EmulateInstruction::Context context;
1414         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1415         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1416         if (!success)
1417             return false;
1418         addr_t lr; // next instruction address
1419         addr_t target; // target address
1420         int32_t imm32; // PC-relative offset
1421         switch (encoding) {
1422         case eEncodingT1:
1423             {
1424             lr = pc | 1u; // return address
1425             uint32_t S = Bit32(opcode, 26);
1426             uint32_t imm10 = Bits32(opcode, 25, 16);
1427             uint32_t J1 = Bit32(opcode, 13);
1428             uint32_t J2 = Bit32(opcode, 11);
1429             uint32_t imm11 = Bits32(opcode, 10, 0);
1430             uint32_t I1 = !(J1 ^ S);
1431             uint32_t I2 = !(J2 ^ S);
1432             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1433             imm32 = llvm::SignExtend32<25>(imm25);
1434             target = pc + imm32;
1435             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
1436             if (InITBlock() && !LastInITBlock())
1437                 return false;
1438             break;
1439             }
1440         case eEncodingT2:
1441             {
1442             lr = pc | 1u; // return address
1443             uint32_t S = Bit32(opcode, 26);
1444             uint32_t imm10H = Bits32(opcode, 25, 16);
1445             uint32_t J1 = Bit32(opcode, 13);
1446             uint32_t J2 = Bit32(opcode, 11);
1447             uint32_t imm10L = Bits32(opcode, 10, 1);
1448             uint32_t I1 = !(J1 ^ S);
1449             uint32_t I2 = !(J2 ^ S);
1450             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
1451             imm32 = llvm::SignExtend32<25>(imm25);
1452             target = Align(pc, 4) + imm32;
1453             context.SetISAAndImmediateSigned (eModeARM, 4 + imm32);
1454             if (InITBlock() && !LastInITBlock())
1455                 return false;
1456             break;
1457             }
1458         case eEncodingA1:
1459             lr = pc - 4; // return address
1460             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1461             target = Align(pc, 4) + imm32;
1462             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
1463             break;
1464         case eEncodingA2:
1465             lr = pc - 4; // return address
1466             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
1467             target = pc + imm32;
1468             context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32);
1469             break;
1470         default:
1471             return false;
1472         }
1473         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1474             return false;
1475         if (!BranchWritePC(context, target))
1476             return false;
1477     }
1478     return true;
1479 }
1480 
1481 // Branch with Link and Exchange (register) calls a subroutine at an address and
1482 // instruction set specified by a register.
1483 // BLX (register)
1484 bool
1485 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding)
1486 {
1487 #if 0
1488     // ARM pseudo code...
1489     if (ConditionPassed())
1490     {
1491         EncodingSpecificOperations();
1492         target = R[m];
1493         if CurrentInstrSet() == InstrSet_ARM then
1494             next_instr_addr = PC - 4;
1495             LR = next_instr_addr;
1496         else
1497             next_instr_addr = PC - 2;
1498             LR = next_instr_addr<31:1> : '1';
1499         BXWritePC(target);
1500     }
1501 #endif
1502 
1503     bool success = false;
1504 
1505     if (ConditionPassed(opcode))
1506     {
1507         EmulateInstruction::Context context;
1508         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1509         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1510         addr_t lr; // next instruction address
1511         if (!success)
1512             return false;
1513         uint32_t Rm; // the register with the target address
1514         switch (encoding) {
1515         case eEncodingT1:
1516             lr = (pc - 2) | 1u; // return address
1517             Rm = Bits32(opcode, 6, 3);
1518             // if m == 15 then UNPREDICTABLE;
1519             if (Rm == 15)
1520                 return false;
1521             if (InITBlock() && !LastInITBlock())
1522                 return false;
1523             break;
1524         case eEncodingA1:
1525             lr = pc - 4; // return address
1526             Rm = Bits32(opcode, 3, 0);
1527             // if m == 15 then UNPREDICTABLE;
1528             if (Rm == 15)
1529                 return false;
1530             break;
1531         default:
1532             return false;
1533         }
1534         addr_t target = ReadCoreReg (Rm, &success);
1535         if (!success)
1536             return false;
1537         RegisterInfo dwarf_reg;
1538         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1539         context.SetRegister (dwarf_reg);
1540         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1541             return false;
1542         if (!BXWritePC(context, target))
1543             return false;
1544     }
1545     return true;
1546 }
1547 
1548 // Branch and Exchange causes a branch to an address and instruction set specified by a register.
1549 bool
1550 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding)
1551 {
1552 #if 0
1553     // ARM pseudo code...
1554     if (ConditionPassed())
1555     {
1556         EncodingSpecificOperations();
1557         BXWritePC(R[m]);
1558     }
1559 #endif
1560 
1561     if (ConditionPassed(opcode))
1562     {
1563         EmulateInstruction::Context context;
1564         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1565         uint32_t Rm; // the register with the target address
1566         switch (encoding) {
1567         case eEncodingT1:
1568             Rm = Bits32(opcode, 6, 3);
1569             if (InITBlock() && !LastInITBlock())
1570                 return false;
1571             break;
1572         case eEncodingA1:
1573             Rm = Bits32(opcode, 3, 0);
1574             break;
1575         default:
1576             return false;
1577         }
1578         bool success = false;
1579         addr_t target = ReadCoreReg (Rm, &success);
1580         if (!success)
1581             return false;
1582 
1583         RegisterInfo dwarf_reg;
1584         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1585         context.SetRegister (dwarf_reg);
1586         if (!BXWritePC(context, target))
1587             return false;
1588     }
1589     return true;
1590 }
1591 
1592 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an
1593 // address and instruction set specified by a register as though it were a BX instruction.
1594 //
1595 // TODO: Emulate Jazelle architecture?
1596 //       We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation.
1597 bool
1598 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding)
1599 {
1600 #if 0
1601     // ARM pseudo code...
1602     if (ConditionPassed())
1603     {
1604         EncodingSpecificOperations();
1605         if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
1606             BXWritePC(R[m]);
1607         else
1608             if JazelleAcceptsExecution() then
1609                 SwitchToJazelleExecution();
1610             else
1611                 SUBARCHITECTURE_DEFINED handler call;
1612     }
1613 #endif
1614 
1615     if (ConditionPassed(opcode))
1616     {
1617         EmulateInstruction::Context context;
1618         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1619         uint32_t Rm; // the register with the target address
1620         switch (encoding) {
1621         case eEncodingT1:
1622             Rm = Bits32(opcode, 19, 16);
1623             if (BadReg(Rm))
1624                 return false;
1625             if (InITBlock() && !LastInITBlock())
1626                 return false;
1627             break;
1628         case eEncodingA1:
1629             Rm = Bits32(opcode, 3, 0);
1630             if (Rm == 15)
1631                 return false;
1632             break;
1633         default:
1634             return false;
1635         }
1636         bool success = false;
1637         addr_t target = ReadCoreReg (Rm, &success);
1638         if (!success)
1639             return false;
1640 
1641         RegisterInfo dwarf_reg;
1642         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1643         context.SetRegister (dwarf_reg);
1644         if (!BXWritePC(context, target))
1645             return false;
1646     }
1647     return true;
1648 }
1649 
1650 // Set r7 to point to some ip offset.
1651 // SUB (immediate)
1652 bool
1653 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding)
1654 {
1655 #if 0
1656     // ARM pseudo code...
1657     if (ConditionPassed())
1658     {
1659         EncodingSpecificOperations();
1660         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1661         if d == 15 then // Can only occur for ARM encoding
1662            ALUWritePC(result); // setflags is always FALSE here
1663         else
1664             R[d] = result;
1665             if setflags then
1666                 APSR.N = result<31>;
1667                 APSR.Z = IsZeroBit(result);
1668                 APSR.C = carry;
1669                 APSR.V = overflow;
1670     }
1671 #endif
1672 
1673     if (ConditionPassed(opcode))
1674     {
1675         bool success = false;
1676         const addr_t ip = ReadCoreReg (12, &success);
1677         if (!success)
1678             return false;
1679         uint32_t imm32;
1680         switch (encoding) {
1681         case eEncodingA1:
1682             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1683             break;
1684         default:
1685             return false;
1686         }
1687         addr_t ip_offset = imm32;
1688         addr_t addr = ip - ip_offset; // the adjusted ip value
1689 
1690         EmulateInstruction::Context context;
1691         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1692         RegisterInfo dwarf_reg;
1693         GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg);
1694         context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
1695 
1696         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
1697             return false;
1698     }
1699     return true;
1700 }
1701 
1702 // Set ip to point to some stack offset.
1703 // SUB (SP minus immediate)
1704 bool
1705 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding)
1706 {
1707 #if 0
1708     // ARM pseudo code...
1709     if (ConditionPassed())
1710     {
1711         EncodingSpecificOperations();
1712         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1713         if d == 15 then // Can only occur for ARM encoding
1714            ALUWritePC(result); // setflags is always FALSE here
1715         else
1716             R[d] = result;
1717             if setflags then
1718                 APSR.N = result<31>;
1719                 APSR.Z = IsZeroBit(result);
1720                 APSR.C = carry;
1721                 APSR.V = overflow;
1722     }
1723 #endif
1724 
1725     if (ConditionPassed(opcode))
1726     {
1727         bool success = false;
1728         const addr_t sp = ReadCoreReg (SP_REG, &success);
1729         if (!success)
1730             return false;
1731         uint32_t imm32;
1732         switch (encoding) {
1733         case eEncodingA1:
1734             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1735             break;
1736         default:
1737             return false;
1738         }
1739         addr_t sp_offset = imm32;
1740         addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1741 
1742         EmulateInstruction::Context context;
1743         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1744         RegisterInfo dwarf_reg;
1745         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
1746         context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
1747 
1748         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
1749             return false;
1750     }
1751     return true;
1752 }
1753 
1754 // This instruction subtracts an immediate value from the SP value, and writes
1755 // the result to the destination register.
1756 //
1757 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage.
1758 bool
1759 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding)
1760 {
1761 #if 0
1762     // ARM pseudo code...
1763     if (ConditionPassed())
1764     {
1765         EncodingSpecificOperations();
1766         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1767         if d == 15 then        // Can only occur for ARM encoding
1768            ALUWritePC(result); // setflags is always FALSE here
1769         else
1770             R[d] = result;
1771             if setflags then
1772                 APSR.N = result<31>;
1773                 APSR.Z = IsZeroBit(result);
1774                 APSR.C = carry;
1775                 APSR.V = overflow;
1776     }
1777 #endif
1778 
1779     bool success = false;
1780     if (ConditionPassed(opcode))
1781     {
1782         const addr_t sp = ReadCoreReg (SP_REG, &success);
1783         if (!success)
1784             return false;
1785 
1786         uint32_t Rd;
1787         bool setflags;
1788         uint32_t imm32;
1789         switch (encoding) {
1790         case eEncodingT1:
1791             Rd = 13;
1792             setflags = false;
1793             imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1794             break;
1795         case eEncodingT2:
1796             Rd = Bits32(opcode, 11, 8);
1797             setflags = BitIsSet(opcode, 20);
1798             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1799             if (Rd == 15 && setflags)
1800                 return EmulateCMPImm(opcode, eEncodingT2);
1801             if (Rd == 15 && !setflags)
1802                 return false;
1803             break;
1804         case eEncodingT3:
1805             Rd = Bits32(opcode, 11, 8);
1806             setflags = false;
1807             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
1808             if (Rd == 15)
1809                 return false;
1810             break;
1811         case eEncodingA1:
1812             Rd = Bits32(opcode, 15, 12);
1813             setflags = BitIsSet(opcode, 20);
1814             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1815 
1816             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1817             if (Rd == 15 && setflags)
1818                 return EmulateSUBSPcLrEtc (opcode, encoding);
1819             break;
1820         default:
1821             return false;
1822         }
1823         AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
1824 
1825         EmulateInstruction::Context context;
1826         if (Rd == 13)
1827         {
1828             uint64_t imm64 = imm32;  // Need to expand it to 64 bits before attempting to negate it, or the wrong
1829                                      // value gets passed down to context.SetImmediateSigned.
1830             context.type = EmulateInstruction::eContextAdjustStackPointer;
1831             context.SetImmediateSigned (-imm64); // the stack pointer offset
1832         }
1833         else
1834         {
1835             context.type = EmulateInstruction::eContextImmediate;
1836             context.SetNoArgs ();
1837         }
1838 
1839         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
1840             return false;
1841     }
1842     return true;
1843 }
1844 
1845 // A store operation to the stack that also updates the SP.
1846 bool
1847 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding)
1848 {
1849 #if 0
1850     // ARM pseudo code...
1851     if (ConditionPassed())
1852     {
1853         EncodingSpecificOperations();
1854         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1855         address = if index then offset_addr else R[n];
1856         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1857         if wback then R[n] = offset_addr;
1858     }
1859 #endif
1860 
1861     bool conditional = false;
1862     bool success = false;
1863     if (ConditionPassed(opcode, &conditional))
1864     {
1865         const uint32_t addr_byte_size = GetAddressByteSize();
1866         const addr_t sp = ReadCoreReg (SP_REG, &success);
1867         if (!success)
1868             return false;
1869         uint32_t Rt; // the source register
1870         uint32_t imm12;
1871         uint32_t Rn;  // This function assumes Rn is the SP, but we should verify that.
1872 
1873         bool index;
1874         bool add;
1875         bool wback;
1876         switch (encoding) {
1877         case eEncodingA1:
1878             Rt = Bits32(opcode, 15, 12);
1879             imm12 = Bits32(opcode, 11, 0);
1880             Rn = Bits32 (opcode, 19, 16);
1881 
1882             if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
1883                 return false;
1884 
1885             index = BitIsSet (opcode, 24);
1886             add = BitIsSet (opcode, 23);
1887             wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
1888 
1889             if (wback && ((Rn == 15) || (Rn == Rt)))
1890                 return false;
1891             break;
1892         default:
1893             return false;
1894         }
1895         addr_t offset_addr;
1896         if (add)
1897             offset_addr = sp + imm12;
1898         else
1899             offset_addr = sp - imm12;
1900 
1901         addr_t addr;
1902         if (index)
1903             addr = offset_addr;
1904         else
1905             addr = sp;
1906 
1907         EmulateInstruction::Context context;
1908         if (conditional)
1909             context.type = EmulateInstruction::eContextRegisterStore;
1910         else
1911             context.type = EmulateInstruction::eContextPushRegisterOnStack;
1912         RegisterInfo sp_reg;
1913         RegisterInfo dwarf_reg;
1914 
1915         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1916         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
1917         context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
1918         if (Rt != 15)
1919         {
1920             uint32_t reg_value = ReadCoreReg(Rt, &success);
1921             if (!success)
1922                 return false;
1923             if (!MemUWrite (context, addr, reg_value, addr_byte_size))
1924                 return false;
1925         }
1926         else
1927         {
1928             const uint32_t pc = ReadCoreReg(PC_REG, &success);
1929             if (!success)
1930                 return false;
1931             if (!MemUWrite (context, addr, pc, addr_byte_size))
1932                 return false;
1933         }
1934 
1935 
1936         if (wback)
1937         {
1938             context.type = EmulateInstruction::eContextAdjustStackPointer;
1939             context.SetImmediateSigned (addr - sp);
1940             if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr))
1941                 return false;
1942         }
1943     }
1944     return true;
1945 }
1946 
1947 // Vector Push stores multiple extension registers to the stack.
1948 // It also updates SP to point to the start of the stored data.
1949 bool
1950 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding)
1951 {
1952 #if 0
1953     // ARM pseudo code...
1954     if (ConditionPassed())
1955     {
1956         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1957         address = SP - imm32;
1958         SP = SP - imm32;
1959         if single_regs then
1960             for r = 0 to regs-1
1961                 MemA[address,4] = S[d+r]; address = address+4;
1962         else
1963             for r = 0 to regs-1
1964                 // Store as two word-aligned words in the correct order for current endianness.
1965                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
1966                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
1967                 address = address+8;
1968     }
1969 #endif
1970 
1971     bool success = false;
1972     bool conditional = false;
1973     if (ConditionPassed(opcode, &conditional))
1974     {
1975         const uint32_t addr_byte_size = GetAddressByteSize();
1976         const addr_t sp = ReadCoreReg (SP_REG, &success);
1977         if (!success)
1978             return false;
1979         bool single_regs;
1980         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
1981         uint32_t imm32; // stack offset
1982         uint32_t regs;  // number of registers
1983         switch (encoding) {
1984         case eEncodingT1:
1985         case eEncodingA1:
1986             single_regs = false;
1987             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
1988             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1989             // If UInt(imm8) is odd, see "FSTMX".
1990             regs = Bits32(opcode, 7, 0) / 2;
1991             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1992             if (regs == 0 || regs > 16 || (d + regs) > 32)
1993                 return false;
1994             break;
1995         case eEncodingT2:
1996         case eEncodingA2:
1997             single_regs = true;
1998             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
1999             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2000             regs = Bits32(opcode, 7, 0);
2001             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2002             if (regs == 0 || regs > 16 || (d + regs) > 32)
2003                 return false;
2004             break;
2005         default:
2006             return false;
2007         }
2008         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2009         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2010         addr_t sp_offset = imm32;
2011         addr_t addr = sp - sp_offset;
2012         uint32_t i;
2013 
2014         EmulateInstruction::Context context;
2015         if (conditional)
2016             context.type = EmulateInstruction::eContextRegisterStore;
2017         else
2018             context.type = EmulateInstruction::eContextPushRegisterOnStack;
2019         RegisterInfo dwarf_reg;
2020         RegisterInfo sp_reg;
2021         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2022         for (i=0; i<regs; ++i)
2023         {
2024             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2025             context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
2026             // uint64_t to accommodate 64-bit registers.
2027             uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success);
2028             if (!success)
2029                 return false;
2030             if (!MemAWrite (context, addr, reg_value, reg_byte_size))
2031                 return false;
2032             addr += reg_byte_size;
2033         }
2034 
2035         context.type = EmulateInstruction::eContextAdjustStackPointer;
2036         context.SetImmediateSigned (-sp_offset);
2037 
2038         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2039             return false;
2040     }
2041     return true;
2042 }
2043 
2044 // Vector Pop loads multiple extension registers from the stack.
2045 // It also updates SP to point just above the loaded data.
2046 bool
2047 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding)
2048 {
2049 #if 0
2050     // ARM pseudo code...
2051     if (ConditionPassed())
2052     {
2053         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2054         address = SP;
2055         SP = SP + imm32;
2056         if single_regs then
2057             for r = 0 to regs-1
2058                 S[d+r] = MemA[address,4]; address = address+4;
2059         else
2060             for r = 0 to regs-1
2061                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2062                 // Combine the word-aligned words in the correct order for current endianness.
2063                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2064     }
2065 #endif
2066 
2067     bool success = false;
2068     bool conditional = false;
2069     if (ConditionPassed(opcode, &conditional))
2070     {
2071         const uint32_t addr_byte_size = GetAddressByteSize();
2072         const addr_t sp = ReadCoreReg (SP_REG, &success);
2073         if (!success)
2074             return false;
2075         bool single_regs;
2076         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2077         uint32_t imm32; // stack offset
2078         uint32_t regs;  // number of registers
2079         switch (encoding) {
2080         case eEncodingT1:
2081         case eEncodingA1:
2082             single_regs = false;
2083             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2084             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2085             // If UInt(imm8) is odd, see "FLDMX".
2086             regs = Bits32(opcode, 7, 0) / 2;
2087             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2088             if (regs == 0 || regs > 16 || (d + regs) > 32)
2089                 return false;
2090             break;
2091         case eEncodingT2:
2092         case eEncodingA2:
2093             single_regs = true;
2094             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2095             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2096             regs = Bits32(opcode, 7, 0);
2097             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2098             if (regs == 0 || regs > 16 || (d + regs) > 32)
2099                 return false;
2100             break;
2101         default:
2102             return false;
2103         }
2104         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2105         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2106         addr_t sp_offset = imm32;
2107         addr_t addr = sp;
2108         uint32_t i;
2109         uint64_t data; // uint64_t to accomodate 64-bit registers.
2110 
2111         EmulateInstruction::Context context;
2112         if (conditional)
2113             context.type = EmulateInstruction::eContextRegisterLoad;
2114         else
2115             context.type = EmulateInstruction::eContextPopRegisterOffStack;
2116         RegisterInfo dwarf_reg;
2117         RegisterInfo sp_reg;
2118         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2119         for (i=0; i<regs; ++i)
2120         {
2121             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2122             context.SetRegisterPlusOffset (sp_reg, addr - sp);
2123             data = MemARead(context, addr, reg_byte_size, 0, &success);
2124             if (!success)
2125                 return false;
2126             if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2127                 return false;
2128             addr += reg_byte_size;
2129         }
2130 
2131         context.type = EmulateInstruction::eContextAdjustStackPointer;
2132         context.SetImmediateSigned (sp_offset);
2133 
2134         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2135             return false;
2136     }
2137     return true;
2138 }
2139 
2140 // SVC (previously SWI)
2141 bool
2142 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding)
2143 {
2144 #if 0
2145     // ARM pseudo code...
2146     if (ConditionPassed())
2147     {
2148         EncodingSpecificOperations();
2149         CallSupervisor();
2150     }
2151 #endif
2152 
2153     bool success = false;
2154 
2155     if (ConditionPassed(opcode))
2156     {
2157         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2158         addr_t lr; // next instruction address
2159         if (!success)
2160             return false;
2161         uint32_t imm32; // the immediate constant
2162         uint32_t mode;  // ARM or Thumb mode
2163         switch (encoding) {
2164         case eEncodingT1:
2165             lr = (pc + 2) | 1u; // return address
2166             imm32 = Bits32(opcode, 7, 0);
2167             mode = eModeThumb;
2168             break;
2169         case eEncodingA1:
2170             lr = pc + 4; // return address
2171             imm32 = Bits32(opcode, 23, 0);
2172             mode = eModeARM;
2173             break;
2174         default:
2175             return false;
2176         }
2177 
2178         EmulateInstruction::Context context;
2179         context.type = EmulateInstruction::eContextSupervisorCall;
2180         context.SetISAAndImmediate (mode, imm32);
2181         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
2182             return false;
2183     }
2184     return true;
2185 }
2186 
2187 // If Then makes up to four following instructions (the IT block) conditional.
2188 bool
2189 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding)
2190 {
2191 #if 0
2192     // ARM pseudo code...
2193     EncodingSpecificOperations();
2194     ITSTATE.IT<7:0> = firstcond:mask;
2195 #endif
2196 
2197     m_it_session.InitIT(Bits32(opcode, 7, 0));
2198     return true;
2199 }
2200 
2201 bool
2202 EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding)
2203 {
2204     // NOP, nothing to do...
2205     return true;
2206 }
2207 
2208 // Branch causes a branch to a target address.
2209 bool
2210 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding)
2211 {
2212 #if 0
2213     // ARM pseudo code...
2214     if (ConditionPassed())
2215     {
2216         EncodingSpecificOperations();
2217         BranchWritePC(PC + imm32);
2218     }
2219 #endif
2220 
2221     bool success = false;
2222 
2223     if (ConditionPassed(opcode))
2224     {
2225         EmulateInstruction::Context context;
2226         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2227         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2228         if (!success)
2229             return false;
2230         addr_t target; // target address
2231         int32_t imm32; // PC-relative offset
2232         switch (encoding) {
2233         case eEncodingT1:
2234             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2235             imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2236             target = pc + imm32;
2237             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2238             break;
2239         case eEncodingT2:
2240             imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0));
2241             target = pc + imm32;
2242             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2243             break;
2244         case eEncodingT3:
2245             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2246             {
2247             uint32_t S = Bit32(opcode, 26);
2248             uint32_t imm6 = Bits32(opcode, 21, 16);
2249             uint32_t J1 = Bit32(opcode, 13);
2250             uint32_t J2 = Bit32(opcode, 11);
2251             uint32_t imm11 = Bits32(opcode, 10, 0);
2252             uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2253             imm32 = llvm::SignExtend32<21>(imm21);
2254             target = pc + imm32;
2255             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2256             break;
2257             }
2258         case eEncodingT4:
2259             {
2260             uint32_t S = Bit32(opcode, 26);
2261             uint32_t imm10 = Bits32(opcode, 25, 16);
2262             uint32_t J1 = Bit32(opcode, 13);
2263             uint32_t J2 = Bit32(opcode, 11);
2264             uint32_t imm11 = Bits32(opcode, 10, 0);
2265             uint32_t I1 = !(J1 ^ S);
2266             uint32_t I2 = !(J2 ^ S);
2267             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2268             imm32 = llvm::SignExtend32<25>(imm25);
2269             target = pc + imm32;
2270             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2271             break;
2272             }
2273         case eEncodingA1:
2274             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2275             target = pc + imm32;
2276             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
2277             break;
2278         default:
2279             return false;
2280         }
2281         if (!BranchWritePC(context, target))
2282             return false;
2283     }
2284     return true;
2285 }
2286 
2287 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
2288 // zero and conditionally branch forward a constant value.  They do not affect the condition flags.
2289 // CBNZ, CBZ
2290 bool
2291 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding)
2292 {
2293 #if 0
2294     // ARM pseudo code...
2295     EncodingSpecificOperations();
2296     if nonzero ^ IsZero(R[n]) then
2297         BranchWritePC(PC + imm32);
2298 #endif
2299 
2300     bool success = false;
2301 
2302     // Read the register value from the operand register Rn.
2303     uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2304     if (!success)
2305         return false;
2306 
2307     EmulateInstruction::Context context;
2308     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2309     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2310     if (!success)
2311         return false;
2312 
2313     addr_t target;  // target address
2314     uint32_t imm32; // PC-relative offset to branch forward
2315     bool nonzero;
2316     switch (encoding) {
2317     case eEncodingT1:
2318         imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2319         nonzero = BitIsSet(opcode, 11);
2320         target = pc + imm32;
2321         context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2322         break;
2323     default:
2324         return false;
2325     }
2326     if (nonzero ^ (reg_val == 0))
2327         if (!BranchWritePC(context, target))
2328             return false;
2329 
2330     return true;
2331 }
2332 
2333 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
2334 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2335 // The branch length is twice the value of the byte returned from the table.
2336 //
2337 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
2338 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2339 // The branch length is twice the value of the halfword returned from the table.
2340 // TBB, TBH
2341 bool
2342 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding)
2343 {
2344 #if 0
2345     // ARM pseudo code...
2346     EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2347     if is_tbh then
2348         halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2349     else
2350         halfwords = UInt(MemU[R[n]+R[m], 1]);
2351     BranchWritePC(PC + 2*halfwords);
2352 #endif
2353 
2354     bool success = false;
2355 
2356     uint32_t Rn;     // the base register which contains the address of the table of branch lengths
2357     uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
2358     bool is_tbh;     // true if table branch halfword
2359     switch (encoding) {
2360     case eEncodingT1:
2361         Rn = Bits32(opcode, 19, 16);
2362         Rm = Bits32(opcode, 3, 0);
2363         is_tbh = BitIsSet(opcode, 4);
2364         if (Rn == 13 || BadReg(Rm))
2365             return false;
2366         if (InITBlock() && !LastInITBlock())
2367             return false;
2368         break;
2369     default:
2370         return false;
2371     }
2372 
2373     // Read the address of the table from the operand register Rn.
2374     // The PC can be used, in which case the table immediately follows this instruction.
2375     uint32_t base = ReadCoreReg(Rm, &success);
2376     if (!success)
2377         return false;
2378 
2379     // the table index
2380     uint32_t index = ReadCoreReg(Rm, &success);
2381     if (!success)
2382         return false;
2383 
2384     // the offsetted table address
2385     addr_t addr = base + (is_tbh ? index*2 : index);
2386 
2387     // PC-relative offset to branch forward
2388     EmulateInstruction::Context context;
2389     context.type = EmulateInstruction::eContextTableBranchReadMemory;
2390     uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2391     if (!success)
2392         return false;
2393 
2394     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2395     if (!success)
2396         return false;
2397 
2398     // target address
2399     addr_t target = pc + offset;
2400     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2401     context.SetISAAndImmediateSigned (eModeThumb, 4 + offset);
2402 
2403     if (!BranchWritePC(context, target))
2404         return false;
2405 
2406     return true;
2407 }
2408 
2409 // This instruction adds an immediate value to a register value, and writes the result to the destination register.
2410 // It can optionally update the condition flags based on the result.
2411 bool
2412 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding)
2413 {
2414 #if 0
2415     if ConditionPassed() then
2416         EncodingSpecificOperations();
2417         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2418         R[d] = result;
2419         if setflags then
2420             APSR.N = result<31>;
2421             APSR.Z = IsZeroBit(result);
2422             APSR.C = carry;
2423             APSR.V = overflow;
2424 #endif
2425 
2426     bool success = false;
2427 
2428     if (ConditionPassed(opcode))
2429     {
2430         uint32_t d;
2431         uint32_t n;
2432         bool setflags;
2433         uint32_t imm32;
2434         uint32_t carry_out;
2435 
2436         //EncodingSpecificOperations();
2437         switch (encoding)
2438         {
2439             case eEncodingT1:
2440                 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32);
2441                 d = Bits32 (opcode, 2, 0);
2442                 n = Bits32 (opcode, 5, 3);
2443                 setflags = !InITBlock();
2444                 imm32 = Bits32 (opcode, 8,6);
2445 
2446                 break;
2447 
2448             case eEncodingT2:
2449                 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32);
2450                 d = Bits32 (opcode, 10, 8);
2451                 n = Bits32 (opcode, 10, 8);
2452                 setflags = !InITBlock();
2453                 imm32 = Bits32 (opcode, 7, 0);
2454 
2455                 break;
2456 
2457             case eEncodingT3:
2458                 // if Rd == '1111' && S == '1' then SEE CMN (immediate);
2459                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2460                 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8);
2461                 d = Bits32 (opcode, 11, 8);
2462                 n = Bits32 (opcode, 19, 16);
2463                 setflags = BitIsSet (opcode, 20);
2464                 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out);
2465 
2466                 // if BadReg(d) || n == 15 then UNPREDICTABLE;
2467                 if (BadReg (d) || (n == 15))
2468                     return false;
2469 
2470                 break;
2471 
2472             case eEncodingT4:
2473             {
2474                 // if Rn == '1111' then SEE ADR;
2475                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2476                 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
2477                 d = Bits32 (opcode, 11, 8);
2478                 n = Bits32 (opcode, 19, 16);
2479                 setflags = false;
2480                 uint32_t i = Bit32 (opcode, 26);
2481                 uint32_t imm3 = Bits32 (opcode, 14, 12);
2482                 uint32_t imm8 = Bits32 (opcode, 7, 0);
2483                 imm32 = (i << 11) | (imm3 << 8) | imm8;
2484 
2485                 // if BadReg(d) then UNPREDICTABLE;
2486                 if (BadReg (d))
2487                     return false;
2488 
2489                 break;
2490             }
2491             default:
2492                 return false;
2493         }
2494 
2495         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2496         if (!success)
2497             return false;
2498 
2499         //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2500         AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
2501 
2502         RegisterInfo reg_n;
2503         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
2504 
2505         EmulateInstruction::Context context;
2506         context.type = eContextArithmetic;
2507         context.SetRegisterPlusOffset (reg_n, imm32);
2508 
2509         //R[d] = result;
2510         //if setflags then
2511             //APSR.N = result<31>;
2512             //APSR.Z = IsZeroBit(result);
2513             //APSR.C = carry;
2514             //APSR.V = overflow;
2515         if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
2516             return false;
2517 
2518     }
2519     return true;
2520 }
2521 
2522 // This instruction adds an immediate value to a register value, and writes the result to the destination
2523 // register.  It can optionally update the condition flags based on the result.
2524 bool
2525 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding)
2526 {
2527 #if 0
2528     // ARM pseudo code...
2529     if ConditionPassed() then
2530         EncodingSpecificOperations();
2531         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2532         if d == 15 then
2533             ALUWritePC(result); // setflags is always FALSE here
2534         else
2535             R[d] = result;
2536             if setflags then
2537                 APSR.N = result<31>;
2538                 APSR.Z = IsZeroBit(result);
2539                 APSR.C = carry;
2540                 APSR.V = overflow;
2541 #endif
2542 
2543     bool success = false;
2544 
2545     if (ConditionPassed(opcode))
2546     {
2547         uint32_t Rd, Rn;
2548         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
2549         bool setflags;
2550         switch (encoding)
2551         {
2552         case eEncodingA1:
2553             Rd = Bits32(opcode, 15, 12);
2554             Rn = Bits32(opcode, 19, 16);
2555             setflags = BitIsSet(opcode, 20);
2556             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2557             break;
2558         default:
2559             return false;
2560         }
2561 
2562         // Read the first operand.
2563         uint32_t val1 = ReadCoreReg(Rn, &success);
2564         if (!success)
2565             return false;
2566 
2567         AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
2568 
2569         EmulateInstruction::Context context;
2570         context.type = eContextArithmetic;
2571         RegisterInfo dwarf_reg;
2572         GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
2573         context.SetRegisterPlusOffset (dwarf_reg, imm32);
2574 
2575         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2576             return false;
2577     }
2578     return true;
2579 }
2580 
2581 // This instruction adds a register value and an optionally-shifted register value, and writes the result
2582 // to the destination register. It can optionally update the condition flags based on the result.
2583 bool
2584 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding)
2585 {
2586 #if 0
2587     // ARM pseudo code...
2588     if ConditionPassed() then
2589         EncodingSpecificOperations();
2590         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2591         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2592         if d == 15 then
2593             ALUWritePC(result); // setflags is always FALSE here
2594         else
2595             R[d] = result;
2596             if setflags then
2597                 APSR.N = result<31>;
2598                 APSR.Z = IsZeroBit(result);
2599                 APSR.C = carry;
2600                 APSR.V = overflow;
2601 #endif
2602 
2603     bool success = false;
2604 
2605     if (ConditionPassed(opcode))
2606     {
2607         uint32_t Rd, Rn, Rm;
2608         ARM_ShifterType shift_t;
2609         uint32_t shift_n; // the shift applied to the value read from Rm
2610         bool setflags;
2611         switch (encoding)
2612         {
2613         case eEncodingT1:
2614             Rd = Bits32(opcode, 2, 0);
2615             Rn = Bits32(opcode, 5, 3);
2616             Rm = Bits32(opcode, 8, 6);
2617             setflags = !InITBlock();
2618             shift_t = SRType_LSL;
2619             shift_n = 0;
2620             break;
2621         case eEncodingT2:
2622             Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2623             Rm = Bits32(opcode, 6, 3);
2624             setflags = false;
2625             shift_t = SRType_LSL;
2626             shift_n = 0;
2627             if (Rn == 15 && Rm == 15)
2628                 return false;
2629             if (Rd == 15 && InITBlock() && !LastInITBlock())
2630                 return false;
2631             break;
2632         case eEncodingA1:
2633             Rd = Bits32(opcode, 15, 12);
2634             Rn = Bits32(opcode, 19, 16);
2635             Rm = Bits32(opcode, 3, 0);
2636             setflags = BitIsSet(opcode, 20);
2637             shift_n = DecodeImmShiftARM(opcode, shift_t);
2638             break;
2639         default:
2640             return false;
2641         }
2642 
2643         // Read the first operand.
2644         uint32_t val1 = ReadCoreReg(Rn, &success);
2645         if (!success)
2646             return false;
2647 
2648         // Read the second operand.
2649         uint32_t val2 = ReadCoreReg(Rm, &success);
2650         if (!success)
2651             return false;
2652 
2653         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2654         if (!success)
2655             return false;
2656         AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2657 
2658         EmulateInstruction::Context context;
2659         context.type = eContextArithmetic;
2660         RegisterInfo op1_reg;
2661         RegisterInfo op2_reg;
2662         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
2663         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
2664         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
2665 
2666         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2667             return false;
2668     }
2669     return true;
2670 }
2671 
2672 // Compare Negative (immediate) adds a register value and an immediate value.
2673 // It updates the condition flags based on the result, and discards the result.
2674 bool
2675 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding)
2676 {
2677 #if 0
2678     // ARM pseudo code...
2679     if ConditionPassed() then
2680         EncodingSpecificOperations();
2681         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2682         APSR.N = result<31>;
2683         APSR.Z = IsZeroBit(result);
2684         APSR.C = carry;
2685         APSR.V = overflow;
2686 #endif
2687 
2688     bool success = false;
2689 
2690     uint32_t Rn; // the first operand
2691     uint32_t imm32; // the immediate value to be compared with
2692     switch (encoding) {
2693     case eEncodingT1:
2694         Rn = Bits32(opcode, 19, 16);
2695         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2696         if (Rn == 15)
2697             return false;
2698         break;
2699     case eEncodingA1:
2700         Rn = Bits32(opcode, 19, 16);
2701         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2702         break;
2703     default:
2704         return false;
2705     }
2706     // Read the register value from the operand register Rn.
2707     uint32_t reg_val = ReadCoreReg(Rn, &success);
2708     if (!success)
2709         return false;
2710 
2711     AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
2712 
2713     EmulateInstruction::Context context;
2714     context.type = EmulateInstruction::eContextImmediate;
2715     context.SetNoArgs ();
2716     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2717         return false;
2718 
2719     return true;
2720 }
2721 
2722 // Compare Negative (register) adds a register value and an optionally-shifted register value.
2723 // It updates the condition flags based on the result, and discards the result.
2724 bool
2725 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding)
2726 {
2727 #if 0
2728     // ARM pseudo code...
2729     if ConditionPassed() then
2730         EncodingSpecificOperations();
2731         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2732         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2733         APSR.N = result<31>;
2734         APSR.Z = IsZeroBit(result);
2735         APSR.C = carry;
2736         APSR.V = overflow;
2737 #endif
2738 
2739     bool success = false;
2740 
2741     uint32_t Rn; // the first operand
2742     uint32_t Rm; // the second operand
2743     ARM_ShifterType shift_t;
2744     uint32_t shift_n; // the shift applied to the value read from Rm
2745     switch (encoding) {
2746     case eEncodingT1:
2747         Rn = Bits32(opcode, 2, 0);
2748         Rm = Bits32(opcode, 5, 3);
2749         shift_t = SRType_LSL;
2750         shift_n = 0;
2751         break;
2752     case eEncodingT2:
2753         Rn = Bits32(opcode, 19, 16);
2754         Rm = Bits32(opcode, 3, 0);
2755         shift_n = DecodeImmShiftThumb(opcode, shift_t);
2756         // if n == 15 || BadReg(m) then UNPREDICTABLE;
2757         if (Rn == 15 || BadReg(Rm))
2758             return false;
2759         break;
2760     case eEncodingA1:
2761         Rn = Bits32(opcode, 19, 16);
2762         Rm = Bits32(opcode, 3, 0);
2763         shift_n = DecodeImmShiftARM(opcode, shift_t);
2764         break;
2765     default:
2766         return false;
2767     }
2768     // Read the register value from register Rn.
2769     uint32_t val1 = ReadCoreReg(Rn, &success);
2770     if (!success)
2771         return false;
2772 
2773     // Read the register value from register Rm.
2774     uint32_t val2 = ReadCoreReg(Rm, &success);
2775     if (!success)
2776         return false;
2777 
2778     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2779     if (!success)
2780         return false;
2781     AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2782 
2783     EmulateInstruction::Context context;
2784     context.type = EmulateInstruction::eContextImmediate;
2785     context.SetNoArgs();
2786     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2787         return false;
2788 
2789     return true;
2790 }
2791 
2792 // Compare (immediate) subtracts an immediate value from a register value.
2793 // It updates the condition flags based on the result, and discards the result.
2794 bool
2795 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding)
2796 {
2797 #if 0
2798     // ARM pseudo code...
2799     if ConditionPassed() then
2800         EncodingSpecificOperations();
2801         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2802         APSR.N = result<31>;
2803         APSR.Z = IsZeroBit(result);
2804         APSR.C = carry;
2805         APSR.V = overflow;
2806 #endif
2807 
2808     bool success = false;
2809 
2810     uint32_t Rn; // the first operand
2811     uint32_t imm32; // the immediate value to be compared with
2812     switch (encoding) {
2813     case eEncodingT1:
2814         Rn = Bits32(opcode, 10, 8);
2815         imm32 = Bits32(opcode, 7, 0);
2816         break;
2817     case eEncodingT2:
2818         Rn = Bits32(opcode, 19, 16);
2819         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2820         if (Rn == 15)
2821             return false;
2822         break;
2823     case eEncodingA1:
2824         Rn = Bits32(opcode, 19, 16);
2825         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2826         break;
2827     default:
2828         return false;
2829     }
2830     // Read the register value from the operand register Rn.
2831     uint32_t reg_val = ReadCoreReg(Rn, &success);
2832     if (!success)
2833         return false;
2834 
2835     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
2836 
2837     EmulateInstruction::Context context;
2838     context.type = EmulateInstruction::eContextImmediate;
2839     context.SetNoArgs ();
2840     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2841         return false;
2842 
2843     return true;
2844 }
2845 
2846 // Compare (register) subtracts an optionally-shifted register value from a register value.
2847 // It updates the condition flags based on the result, and discards the result.
2848 bool
2849 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding)
2850 {
2851 #if 0
2852     // ARM pseudo code...
2853     if ConditionPassed() then
2854         EncodingSpecificOperations();
2855         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2856         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2857         APSR.N = result<31>;
2858         APSR.Z = IsZeroBit(result);
2859         APSR.C = carry;
2860         APSR.V = overflow;
2861 #endif
2862 
2863     bool success = false;
2864 
2865     uint32_t Rn; // the first operand
2866     uint32_t Rm; // the second operand
2867     ARM_ShifterType shift_t;
2868     uint32_t shift_n; // the shift applied to the value read from Rm
2869     switch (encoding) {
2870     case eEncodingT1:
2871         Rn = Bits32(opcode, 2, 0);
2872         Rm = Bits32(opcode, 5, 3);
2873         shift_t = SRType_LSL;
2874         shift_n = 0;
2875         break;
2876     case eEncodingT2:
2877         Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2878         Rm = Bits32(opcode, 6, 3);
2879         shift_t = SRType_LSL;
2880         shift_n = 0;
2881         if (Rn < 8 && Rm < 8)
2882             return false;
2883         if (Rn == 15 || Rm == 15)
2884             return false;
2885         break;
2886     case eEncodingA1:
2887         Rn = Bits32(opcode, 19, 16);
2888         Rm = Bits32(opcode, 3, 0);
2889         shift_n = DecodeImmShiftARM(opcode, shift_t);
2890         break;
2891     default:
2892         return false;
2893     }
2894     // Read the register value from register Rn.
2895     uint32_t val1 = ReadCoreReg(Rn, &success);
2896     if (!success)
2897         return false;
2898 
2899     // Read the register value from register Rm.
2900     uint32_t val2 = ReadCoreReg(Rm, &success);
2901     if (!success)
2902         return false;
2903 
2904     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2905     if (!success)
2906         return false;
2907     AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
2908 
2909     EmulateInstruction::Context context;
2910     context.type = EmulateInstruction::eContextImmediate;
2911     context.SetNoArgs();
2912     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2913         return false;
2914 
2915     return true;
2916 }
2917 
2918 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
2919 // shifting in copies of its sign bit, and writes the result to the destination register.  It can
2920 // optionally update the condition flags based on the result.
2921 bool
2922 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding)
2923 {
2924 #if 0
2925     // ARM pseudo code...
2926     if ConditionPassed() then
2927         EncodingSpecificOperations();
2928         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2929         if d == 15 then         // Can only occur for ARM encoding
2930             ALUWritePC(result); // setflags is always FALSE here
2931         else
2932             R[d] = result;
2933             if setflags then
2934                 APSR.N = result<31>;
2935                 APSR.Z = IsZeroBit(result);
2936                 APSR.C = carry;
2937                 // APSR.V unchanged
2938 #endif
2939 
2940     return EmulateShiftImm (opcode, encoding, SRType_ASR);
2941 }
2942 
2943 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
2944 // shifting in copies of its sign bit, and writes the result to the destination register.
2945 // The variable number of bits is read from the bottom byte of a register. It can optionally update
2946 // the condition flags based on the result.
2947 bool
2948 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding)
2949 {
2950 #if 0
2951     // ARM pseudo code...
2952     if ConditionPassed() then
2953         EncodingSpecificOperations();
2954         shift_n = UInt(R[m]<7:0>);
2955         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2956         R[d] = result;
2957         if setflags then
2958             APSR.N = result<31>;
2959             APSR.Z = IsZeroBit(result);
2960             APSR.C = carry;
2961             // APSR.V unchanged
2962 #endif
2963 
2964     return EmulateShiftReg (opcode, encoding, SRType_ASR);
2965 }
2966 
2967 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
2968 // shifting in zeros, and writes the result to the destination register.  It can optionally
2969 // update the condition flags based on the result.
2970 bool
2971 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding)
2972 {
2973 #if 0
2974     // ARM pseudo code...
2975     if ConditionPassed() then
2976         EncodingSpecificOperations();
2977         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
2978         if d == 15 then         // Can only occur for ARM encoding
2979             ALUWritePC(result); // setflags is always FALSE here
2980         else
2981             R[d] = result;
2982             if setflags then
2983                 APSR.N = result<31>;
2984                 APSR.Z = IsZeroBit(result);
2985                 APSR.C = carry;
2986                 // APSR.V unchanged
2987 #endif
2988 
2989     return EmulateShiftImm (opcode, encoding, SRType_LSL);
2990 }
2991 
2992 // Logical Shift Left (register) shifts a register value left by a variable number of bits,
2993 // shifting in zeros, and writes the result to the destination register.  The variable number
2994 // of bits is read from the bottom byte of a register. It can optionally update the condition
2995 // flags based on the result.
2996 bool
2997 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding)
2998 {
2999 #if 0
3000     // ARM pseudo code...
3001     if ConditionPassed() then
3002         EncodingSpecificOperations();
3003         shift_n = UInt(R[m]<7:0>);
3004         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3005         R[d] = result;
3006         if setflags then
3007             APSR.N = result<31>;
3008             APSR.Z = IsZeroBit(result);
3009             APSR.C = carry;
3010             // APSR.V unchanged
3011 #endif
3012 
3013     return EmulateShiftReg (opcode, encoding, SRType_LSL);
3014 }
3015 
3016 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
3017 // shifting in zeros, and writes the result to the destination register.  It can optionally
3018 // update the condition flags based on the result.
3019 bool
3020 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding)
3021 {
3022 #if 0
3023     // ARM pseudo code...
3024     if ConditionPassed() then
3025         EncodingSpecificOperations();
3026         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3027         if d == 15 then         // Can only occur for ARM encoding
3028             ALUWritePC(result); // setflags is always FALSE here
3029         else
3030             R[d] = result;
3031             if setflags then
3032                 APSR.N = result<31>;
3033                 APSR.Z = IsZeroBit(result);
3034                 APSR.C = carry;
3035                 // APSR.V unchanged
3036 #endif
3037 
3038     return EmulateShiftImm (opcode, encoding, SRType_LSR);
3039 }
3040 
3041 // Logical Shift Right (register) shifts a register value right by a variable number of bits,
3042 // shifting in zeros, and writes the result to the destination register.  The variable number
3043 // of bits is read from the bottom byte of a register. It can optionally update the condition
3044 // flags based on the result.
3045 bool
3046 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding)
3047 {
3048 #if 0
3049     // ARM pseudo code...
3050     if ConditionPassed() then
3051         EncodingSpecificOperations();
3052         shift_n = UInt(R[m]<7:0>);
3053         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3054         R[d] = result;
3055         if setflags then
3056             APSR.N = result<31>;
3057             APSR.Z = IsZeroBit(result);
3058             APSR.C = carry;
3059             // APSR.V unchanged
3060 #endif
3061 
3062     return EmulateShiftReg (opcode, encoding, SRType_LSR);
3063 }
3064 
3065 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
3066 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3067 // It can optionally update the condition flags based on the result.
3068 bool
3069 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding)
3070 {
3071 #if 0
3072     // ARM pseudo code...
3073     if ConditionPassed() then
3074         EncodingSpecificOperations();
3075         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3076         if d == 15 then         // Can only occur for ARM encoding
3077             ALUWritePC(result); // setflags is always FALSE here
3078         else
3079             R[d] = result;
3080             if setflags then
3081                 APSR.N = result<31>;
3082                 APSR.Z = IsZeroBit(result);
3083                 APSR.C = carry;
3084                 // APSR.V unchanged
3085 #endif
3086 
3087     return EmulateShiftImm (opcode, encoding, SRType_ROR);
3088 }
3089 
3090 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
3091 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3092 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
3093 // flags based on the result.
3094 bool
3095 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding)
3096 {
3097 #if 0
3098     // ARM pseudo code...
3099     if ConditionPassed() then
3100         EncodingSpecificOperations();
3101         shift_n = UInt(R[m]<7:0>);
3102         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3103         R[d] = result;
3104         if setflags then
3105             APSR.N = result<31>;
3106             APSR.Z = IsZeroBit(result);
3107             APSR.C = carry;
3108             // APSR.V unchanged
3109 #endif
3110 
3111     return EmulateShiftReg (opcode, encoding, SRType_ROR);
3112 }
3113 
3114 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
3115 // with the carry flag shifted into bit [31].
3116 //
3117 // RRX can optionally update the condition flags based on the result.
3118 // In that case, bit [0] is shifted into the carry flag.
3119 bool
3120 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding)
3121 {
3122 #if 0
3123     // ARM pseudo code...
3124     if ConditionPassed() then
3125         EncodingSpecificOperations();
3126         (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3127         if d == 15 then         // Can only occur for ARM encoding
3128             ALUWritePC(result); // setflags is always FALSE here
3129         else
3130             R[d] = result;
3131             if setflags then
3132                 APSR.N = result<31>;
3133                 APSR.Z = IsZeroBit(result);
3134                 APSR.C = carry;
3135                 // APSR.V unchanged
3136 #endif
3137 
3138     return EmulateShiftImm (opcode, encoding, SRType_RRX);
3139 }
3140 
3141 bool
3142 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3143 {
3144 //    assert(shift_type == SRType_ASR
3145 //           || shift_type == SRType_LSL
3146 //           || shift_type == SRType_LSR
3147 //           || shift_type == SRType_ROR
3148 //           || shift_type == SRType_RRX);
3149 
3150     bool success = false;
3151 
3152     if (ConditionPassed(opcode))
3153     {
3154         uint32_t Rd;    // the destination register
3155         uint32_t Rm;    // the first operand register
3156         uint32_t imm5;  // encoding for the shift amount
3157         uint32_t carry; // the carry bit after the shift operation
3158         bool setflags;
3159 
3160         // Special case handling!
3161         // A8.6.139 ROR (immediate) -- Encoding T1
3162         ARMEncoding use_encoding = encoding;
3163         if (shift_type == SRType_ROR && use_encoding == eEncodingT1)
3164         {
3165             // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
3166             // have the same decoding of bit fields as the other Thumb2 shift operations.
3167             use_encoding = eEncodingT2;
3168         }
3169 
3170         switch (use_encoding) {
3171         case eEncodingT1:
3172             // Due to the above special case handling!
3173             if (shift_type == SRType_ROR)
3174                 return false;
3175 
3176             Rd = Bits32(opcode, 2, 0);
3177             Rm = Bits32(opcode, 5, 3);
3178             setflags = !InITBlock();
3179             imm5 = Bits32(opcode, 10, 6);
3180             break;
3181         case eEncodingT2:
3182             // A8.6.141 RRX
3183             // There's no imm form of RRX instructions.
3184             if (shift_type == SRType_RRX)
3185                 return false;
3186 
3187             Rd = Bits32(opcode, 11, 8);
3188             Rm = Bits32(opcode, 3, 0);
3189             setflags = BitIsSet(opcode, 20);
3190             imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3191             if (BadReg(Rd) || BadReg(Rm))
3192                 return false;
3193             break;
3194         case eEncodingA1:
3195             Rd = Bits32(opcode, 15, 12);
3196             Rm = Bits32(opcode, 3, 0);
3197             setflags = BitIsSet(opcode, 20);
3198             imm5 = Bits32(opcode, 11, 7);
3199             break;
3200         default:
3201             return false;
3202         }
3203 
3204         // A8.6.139 ROR (immediate)
3205         if (shift_type == SRType_ROR && imm5 == 0)
3206             shift_type = SRType_RRX;
3207 
3208         // Get the first operand.
3209         uint32_t value = ReadCoreReg (Rm, &success);
3210         if (!success)
3211             return false;
3212 
3213         // Decode the shift amount if not RRX.
3214         uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3215 
3216         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3217         if (!success)
3218             return false;
3219 
3220         // The context specifies that an immediate is to be moved into Rd.
3221         EmulateInstruction::Context context;
3222         context.type = EmulateInstruction::eContextImmediate;
3223         context.SetNoArgs ();
3224 
3225         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3226             return false;
3227     }
3228     return true;
3229 }
3230 
3231 bool
3232 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3233 {
3234     // assert(shift_type == SRType_ASR
3235     //        || shift_type == SRType_LSL
3236     //        || shift_type == SRType_LSR
3237     //        || shift_type == SRType_ROR);
3238 
3239     bool success = false;
3240 
3241     if (ConditionPassed(opcode))
3242     {
3243         uint32_t Rd;    // the destination register
3244         uint32_t Rn;    // the first operand register
3245         uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
3246         uint32_t carry; // the carry bit after the shift operation
3247         bool setflags;
3248         switch (encoding) {
3249         case eEncodingT1:
3250             Rd = Bits32(opcode, 2, 0);
3251             Rn = Rd;
3252             Rm = Bits32(opcode, 5, 3);
3253             setflags = !InITBlock();
3254             break;
3255         case eEncodingT2:
3256             Rd = Bits32(opcode, 11, 8);
3257             Rn = Bits32(opcode, 19, 16);
3258             Rm = Bits32(opcode, 3, 0);
3259             setflags = BitIsSet(opcode, 20);
3260             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3261                 return false;
3262             break;
3263         case eEncodingA1:
3264             Rd = Bits32(opcode, 15, 12);
3265             Rn = Bits32(opcode, 3, 0);
3266             Rm = Bits32(opcode, 11, 8);
3267             setflags = BitIsSet(opcode, 20);
3268             if (Rd == 15 || Rn == 15 || Rm == 15)
3269                 return false;
3270             break;
3271         default:
3272             return false;
3273         }
3274 
3275         // Get the first operand.
3276         uint32_t value = ReadCoreReg (Rn, &success);
3277         if (!success)
3278             return false;
3279         // Get the Rm register content.
3280         uint32_t val = ReadCoreReg (Rm, &success);
3281         if (!success)
3282             return false;
3283 
3284         // Get the shift amount.
3285         uint32_t amt = Bits32(val, 7, 0);
3286 
3287         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3288         if (!success)
3289             return false;
3290 
3291         // The context specifies that an immediate is to be moved into Rd.
3292         EmulateInstruction::Context context;
3293         context.type = EmulateInstruction::eContextImmediate;
3294         context.SetNoArgs ();
3295 
3296         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3297             return false;
3298     }
3299     return true;
3300 }
3301 
3302 // LDM loads multiple registers from consecutive memory locations, using an
3303 // address from a base register.  Optionally the address just above the highest of those locations
3304 // can be written back to the base register.
3305 bool
3306 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding)
3307 {
3308 #if 0
3309     // ARM pseudo code...
3310     if ConditionPassed()
3311         EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3312         address = R[n];
3313 
3314         for i = 0 to 14
3315             if registers<i> == '1' then
3316                 R[i] = MemA[address, 4]; address = address + 4;
3317         if registers<15> == '1' then
3318             LoadWritePC (MemA[address, 4]);
3319 
3320         if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3321         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3322 
3323 #endif
3324 
3325     bool success = false;
3326     bool conditional = false;
3327     if (ConditionPassed(opcode, &conditional))
3328     {
3329         uint32_t n;
3330         uint32_t registers = 0;
3331         bool wback;
3332         const uint32_t addr_byte_size = GetAddressByteSize();
3333         switch (encoding)
3334         {
3335             case eEncodingT1:
3336                 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0');
3337                 n = Bits32 (opcode, 10, 8);
3338                 registers = Bits32 (opcode, 7, 0);
3339                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3340                 wback = BitIsClear (registers, n);
3341                 // if BitCount(registers) < 1 then UNPREDICTABLE;
3342                 if (BitCount(registers) < 1)
3343                     return false;
3344                 break;
3345             case eEncodingT2:
3346                 // if W == '1' && Rn == '1101' then SEE POP;
3347                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3348                 n = Bits32 (opcode, 19, 16);
3349                 registers = Bits32 (opcode, 15, 0);
3350                 registers = registers & 0xdfff; // Make sure bit 13 is zero.
3351                 wback = BitIsSet (opcode, 21);
3352 
3353                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3354                 if ((n == 15)
3355                     || (BitCount (registers) < 2)
3356                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3357                     return false;
3358 
3359                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3360                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3361                     return false;
3362 
3363                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3364                 if (wback
3365                     && BitIsSet (registers, n))
3366                     return false;
3367                 break;
3368 
3369             case eEncodingA1:
3370                 n = Bits32 (opcode, 19, 16);
3371                 registers = Bits32 (opcode, 15, 0);
3372                 wback = BitIsSet (opcode, 21);
3373                 if ((n == 15)
3374                     || (BitCount (registers) < 1))
3375                     return false;
3376                 break;
3377             default:
3378                 return false;
3379         }
3380 
3381         int32_t offset = 0;
3382         const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3383         if (!success)
3384             return false;
3385 
3386         EmulateInstruction::Context context;
3387         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3388         RegisterInfo dwarf_reg;
3389         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3390         context.SetRegisterPlusOffset (dwarf_reg, offset);
3391 
3392         for (int i = 0; i < 14; ++i)
3393         {
3394             if (BitIsSet (registers, i))
3395             {
3396                 context.type = EmulateInstruction::eContextRegisterPlusOffset;
3397                 context.SetRegisterPlusOffset (dwarf_reg, offset);
3398                 if (wback && (n == 13)) // Pop Instruction
3399                 {
3400                     if (conditional)
3401                         context.type = EmulateInstruction::eContextRegisterLoad;
3402                     else
3403                         context.type = EmulateInstruction::eContextPopRegisterOffStack;
3404                 }
3405 
3406                 // R[i] = MemA [address, 4]; address = address + 4;
3407                 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3408                 if (!success)
3409                     return false;
3410 
3411                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3412                     return false;
3413 
3414                 offset += addr_byte_size;
3415             }
3416         }
3417 
3418         if (BitIsSet (registers, 15))
3419         {
3420             //LoadWritePC (MemA [address, 4]);
3421             context.type = EmulateInstruction::eContextRegisterPlusOffset;
3422             context.SetRegisterPlusOffset (dwarf_reg, offset);
3423             uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3424             if (!success)
3425                 return false;
3426             // In ARMv5T and above, this is an interworking branch.
3427             if (!LoadWritePC(context, data))
3428                 return false;
3429         }
3430 
3431         if (wback && BitIsClear (registers, n))
3432         {
3433             // R[n] = R[n] + 4 * BitCount (registers)
3434             int32_t offset = addr_byte_size * BitCount (registers);
3435             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3436             context.SetRegisterPlusOffset (dwarf_reg, offset);
3437 
3438             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
3439                 return false;
3440         }
3441         if (wback && BitIsSet (registers, n))
3442             // R[n] bits(32) UNKNOWN;
3443             return WriteBits32Unknown (n);
3444     }
3445     return true;
3446 }
3447 
3448 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register.
3449 // The consecutive memory locations end at this address and the address just below the lowest of those locations
3450 // can optionally be written back to the base register.
3451 bool
3452 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding)
3453 {
3454 #if 0
3455     // ARM pseudo code...
3456     if ConditionPassed() then
3457         EncodingSpecificOperations();
3458         address = R[n] - 4*BitCount(registers) + 4;
3459 
3460         for i = 0 to 14
3461             if registers<i> == '1' then
3462                   R[i] = MemA[address,4]; address = address + 4;
3463 
3464         if registers<15> == '1' then
3465             LoadWritePC(MemA[address,4]);
3466 
3467         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3468         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3469 #endif
3470 
3471     bool success = false;
3472 
3473     if (ConditionPassed(opcode))
3474     {
3475         uint32_t n;
3476         uint32_t registers = 0;
3477         bool wback;
3478         const uint32_t addr_byte_size = GetAddressByteSize();
3479 
3480         // EncodingSpecificOperations();
3481         switch (encoding)
3482         {
3483             case eEncodingA1:
3484                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3485                 n = Bits32 (opcode, 19, 16);
3486                 registers = Bits32 (opcode, 15, 0);
3487                 wback = BitIsSet (opcode, 21);
3488 
3489                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3490                 if ((n == 15) || (BitCount (registers) < 1))
3491                     return false;
3492 
3493                 break;
3494 
3495             default:
3496                 return false;
3497         }
3498         // address = R[n] - 4*BitCount(registers) + 4;
3499 
3500         int32_t offset = 0;
3501         addr_t Rn = ReadCoreReg (n, &success);
3502 
3503         if (!success)
3504             return false;
3505 
3506         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size;
3507 
3508         EmulateInstruction::Context context;
3509         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3510         RegisterInfo dwarf_reg;
3511         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3512         context.SetRegisterPlusOffset (dwarf_reg, offset);
3513 
3514         // for i = 0 to 14
3515         for (int i = 0; i < 14; ++i)
3516         {
3517             // if registers<i> == '1' then
3518             if (BitIsSet (registers, i))
3519             {
3520                   // R[i] = MemA[address,4]; address = address + 4;
3521                   context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3522                   uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3523                   if (!success)
3524                       return false;
3525                   if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3526                       return false;
3527                   offset += addr_byte_size;
3528             }
3529         }
3530 
3531         // if registers<15> == '1' then
3532         //     LoadWritePC(MemA[address,4]);
3533         if (BitIsSet (registers, 15))
3534         {
3535             context.SetRegisterPlusOffset (dwarf_reg, offset);
3536             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3537             if (!success)
3538                 return false;
3539             // In ARMv5T and above, this is an interworking branch.
3540             if (!LoadWritePC(context, data))
3541                 return false;
3542         }
3543 
3544         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3545         if (wback && BitIsClear (registers, n))
3546         {
3547             if (!success)
3548                 return false;
3549 
3550             offset = (addr_byte_size * BitCount (registers)) * -1;
3551             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3552             context.SetImmediateSigned (offset);
3553             addr_t addr = Rn + offset;
3554             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3555                 return false;
3556         }
3557 
3558         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3559         if (wback && BitIsSet (registers, n))
3560             return WriteBits32Unknown (n);
3561     }
3562     return true;
3563 }
3564 
3565 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
3566 // consecutive memory lcoations end just below this address, and the address of the lowest of those locations can
3567 // be optionally written back to the base register.
3568 bool
3569 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding)
3570 {
3571 #if 0
3572     // ARM pseudo code...
3573     if ConditionPassed() then
3574         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3575         address = R[n] - 4*BitCount(registers);
3576 
3577         for i = 0 to 14
3578             if registers<i> == '1' then
3579                   R[i] = MemA[address,4]; address = address + 4;
3580         if registers<15> == '1' then
3581                   LoadWritePC(MemA[address,4]);
3582 
3583         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3584         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3585 #endif
3586 
3587     bool success = false;
3588 
3589     if (ConditionPassed(opcode))
3590     {
3591         uint32_t n;
3592         uint32_t registers = 0;
3593         bool wback;
3594         const uint32_t addr_byte_size = GetAddressByteSize();
3595         switch (encoding)
3596         {
3597             case eEncodingT1:
3598                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3599                 n = Bits32 (opcode, 19, 16);
3600                 registers = Bits32 (opcode, 15, 0);
3601                 registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
3602                 wback = BitIsSet (opcode, 21);
3603 
3604                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3605                 if ((n == 15)
3606                     || (BitCount (registers) < 2)
3607                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3608                     return false;
3609 
3610                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3611                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3612                     return false;
3613 
3614                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3615                 if (wback && BitIsSet (registers, n))
3616                     return false;
3617 
3618                 break;
3619 
3620             case eEncodingA1:
3621                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3622                 n = Bits32 (opcode, 19, 16);
3623                 registers = Bits32 (opcode, 15, 0);
3624                 wback = BitIsSet (opcode, 21);
3625 
3626                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3627                 if ((n == 15) || (BitCount (registers) < 1))
3628                     return false;
3629 
3630                 break;
3631 
3632             default:
3633                 return false;
3634         }
3635 
3636         // address = R[n] - 4*BitCount(registers);
3637 
3638         int32_t offset = 0;
3639         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3640 
3641         if (!success)
3642             return false;
3643 
3644         addr_t address = Rn - (addr_byte_size * BitCount (registers));
3645         EmulateInstruction::Context context;
3646         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3647         RegisterInfo dwarf_reg;
3648         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3649         context.SetRegisterPlusOffset (dwarf_reg, Rn - address);
3650 
3651         for (int i = 0; i < 14; ++i)
3652         {
3653             if (BitIsSet (registers, i))
3654             {
3655                 // R[i] = MemA[address,4]; address = address + 4;
3656                 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3657                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3658                 if (!success)
3659                     return false;
3660 
3661                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3662                     return false;
3663 
3664                 offset += addr_byte_size;
3665             }
3666         }
3667 
3668         // if registers<15> == '1' then
3669         //     LoadWritePC(MemA[address,4]);
3670         if (BitIsSet (registers, 15))
3671         {
3672             context.SetRegisterPlusOffset (dwarf_reg, offset);
3673             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3674             if (!success)
3675                 return false;
3676             // In ARMv5T and above, this is an interworking branch.
3677             if (!LoadWritePC(context, data))
3678                 return false;
3679         }
3680 
3681         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3682         if (wback && BitIsClear (registers, n))
3683         {
3684             if (!success)
3685                 return false;
3686 
3687             offset = (addr_byte_size * BitCount (registers)) * -1;
3688             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3689             context.SetImmediateSigned (offset);
3690             addr_t addr = Rn + offset;
3691             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3692                 return false;
3693         }
3694 
3695         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3696         if (wback && BitIsSet (registers, n))
3697             return WriteBits32Unknown (n);
3698     }
3699     return true;
3700 }
3701 
3702 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
3703 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can
3704 // optinoally be written back to the base register.
3705 bool
3706 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding)
3707 {
3708 #if 0
3709     if ConditionPassed() then
3710         EncodingSpecificOperations();
3711         address = R[n] + 4;
3712 
3713         for i = 0 to 14
3714             if registers<i> == '1' then
3715                   R[i] = MemA[address,4]; address = address + 4;
3716         if registers<15> == '1' then
3717             LoadWritePC(MemA[address,4]);
3718 
3719         if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3720         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3721 #endif
3722 
3723     bool success = false;
3724 
3725     if (ConditionPassed(opcode))
3726     {
3727         uint32_t n;
3728         uint32_t registers = 0;
3729         bool wback;
3730         const uint32_t addr_byte_size = GetAddressByteSize();
3731         switch (encoding)
3732         {
3733             case eEncodingA1:
3734                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3735                 n = Bits32 (opcode, 19, 16);
3736                 registers = Bits32 (opcode, 15, 0);
3737                 wback = BitIsSet (opcode, 21);
3738 
3739                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3740                 if ((n == 15) || (BitCount (registers) < 1))
3741                     return false;
3742 
3743                 break;
3744             default:
3745                 return false;
3746         }
3747         // address = R[n] + 4;
3748 
3749         int32_t offset = 0;
3750         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3751 
3752         if (!success)
3753             return false;
3754 
3755         addr_t address = Rn + addr_byte_size;
3756 
3757         EmulateInstruction::Context context;
3758         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3759         RegisterInfo dwarf_reg;
3760         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3761         context.SetRegisterPlusOffset (dwarf_reg, offset);
3762 
3763         for (int i = 0; i < 14; ++i)
3764         {
3765             if (BitIsSet (registers, i))
3766             {
3767                 // R[i] = MemA[address,4]; address = address + 4;
3768 
3769                 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size);
3770                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3771                 if (!success)
3772                     return false;
3773 
3774                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3775                     return false;
3776 
3777                 offset += addr_byte_size;
3778             }
3779         }
3780 
3781         // if registers<15> == '1' then
3782         //     LoadWritePC(MemA[address,4]);
3783         if (BitIsSet (registers, 15))
3784         {
3785             context.SetRegisterPlusOffset (dwarf_reg, offset);
3786             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3787             if (!success)
3788                 return false;
3789             // In ARMv5T and above, this is an interworking branch.
3790             if (!LoadWritePC(context, data))
3791                 return false;
3792         }
3793 
3794         // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3795         if (wback && BitIsClear (registers, n))
3796         {
3797             if (!success)
3798                 return false;
3799 
3800             offset = addr_byte_size * BitCount (registers);
3801             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3802             context.SetImmediateSigned (offset);
3803             addr_t addr = Rn + offset;
3804             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3805                 return false;
3806         }
3807 
3808         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3809         if (wback && BitIsSet (registers, n))
3810             return WriteBits32Unknown (n);
3811     }
3812     return true;
3813 }
3814 
3815 // Load Register (immediate) calculates an address from a base register value and
3816 // an immediate offset, loads a word from memory, and writes to a register.
3817 // LDR (immediate, Thumb)
3818 bool
3819 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding)
3820 {
3821 #if 0
3822     // ARM pseudo code...
3823     if (ConditionPassed())
3824     {
3825         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3826         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3827         address = if index then offset_addr else R[n];
3828         data = MemU[address,4];
3829         if wback then R[n] = offset_addr;
3830         if t == 15 then
3831             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3832         elsif UnalignedSupport() || address<1:0> = '00' then
3833             R[t] = data;
3834         else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3835     }
3836 #endif
3837 
3838     bool success = false;
3839 
3840     if (ConditionPassed(opcode))
3841     {
3842         uint32_t Rt; // the destination register
3843         uint32_t Rn; // the base register
3844         uint32_t imm32; // the immediate offset used to form the address
3845         addr_t offset_addr; // the offset address
3846         addr_t address; // the calculated address
3847         uint32_t data; // the literal data value from memory load
3848         bool add, index, wback;
3849         switch (encoding) {
3850             case eEncodingT1:
3851                 Rt = Bits32(opcode, 2, 0);
3852                 Rn = Bits32(opcode, 5, 3);
3853                 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3854                 // index = TRUE; add = TRUE; wback = FALSE
3855                 add = true;
3856                 index = true;
3857                 wback = false;
3858 
3859                 break;
3860 
3861             case eEncodingT2:
3862                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
3863                 Rt = Bits32 (opcode, 10, 8);
3864                 Rn = 13;
3865                 imm32 = Bits32 (opcode, 7, 0) << 2;
3866 
3867                 // index = TRUE; add = TRUE; wback = FALSE;
3868                 index = true;
3869                 add = true;
3870                 wback = false;
3871 
3872                 break;
3873 
3874             case eEncodingT3:
3875                 // if Rn == '1111' then SEE LDR (literal);
3876                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
3877                 Rt = Bits32 (opcode, 15, 12);
3878                 Rn = Bits32 (opcode, 19, 16);
3879                 imm32 = Bits32 (opcode, 11, 0);
3880 
3881                 // index = TRUE; add = TRUE; wback = FALSE;
3882                 index = true;
3883                 add = true;
3884                 wback = false;
3885 
3886                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3887                 if ((Rt == 15) && InITBlock() && !LastInITBlock())
3888                     return false;
3889 
3890                 break;
3891 
3892             case eEncodingT4:
3893                 // if Rn == '1111' then SEE LDR (literal);
3894                 // if P == '1' && U == '1' && W == '0' then SEE LDRT;
3895                 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
3896                 // if P == '0' && W == '0' then UNDEFINED;
3897                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
3898                     return false;
3899 
3900                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
3901                 Rt = Bits32 (opcode, 15, 12);
3902                 Rn = Bits32 (opcode, 19, 16);
3903                 imm32 = Bits32 (opcode, 7, 0);
3904 
3905                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
3906                 index = BitIsSet (opcode, 10);
3907                 add = BitIsSet (opcode, 9);
3908                 wback = BitIsSet (opcode, 8);
3909 
3910                 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
3911                 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock()))
3912                     return false;
3913 
3914                 break;
3915 
3916             default:
3917                 return false;
3918         }
3919         uint32_t base = ReadCoreReg (Rn, &success);
3920         if (!success)
3921             return false;
3922         if (add)
3923             offset_addr = base + imm32;
3924         else
3925             offset_addr = base - imm32;
3926 
3927         address = (index ? offset_addr : base);
3928 
3929         RegisterInfo base_reg;
3930         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
3931         if (wback)
3932         {
3933             EmulateInstruction::Context ctx;
3934             ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
3935             ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3936 
3937             if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
3938                 return false;
3939         }
3940 
3941         // Prepare to write to the Rt register.
3942         EmulateInstruction::Context context;
3943         context.type = EmulateInstruction::eContextRegisterLoad;
3944         context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3945 
3946         // Read memory from the address.
3947         data = MemURead(context, address, 4, 0, &success);
3948         if (!success)
3949             return false;
3950 
3951         if (Rt == 15)
3952         {
3953             if (Bits32(address, 1, 0) == 0)
3954             {
3955                 if (!LoadWritePC(context, data))
3956                     return false;
3957             }
3958             else
3959                 return false;
3960         }
3961         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
3962         {
3963             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
3964                 return false;
3965         }
3966         else
3967             WriteBits32Unknown (Rt);
3968     }
3969     return true;
3970 }
3971 
3972 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
3973 // from a base register.  The consecutive memory locations start at this address, and teh address just above the last
3974 // of those locations can optionally be written back to the base register.
3975 bool
3976 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding)
3977 {
3978 #if 0
3979     if ConditionPassed() then
3980         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3981         address = R[n];
3982 
3983         for i = 0 to 14
3984             if registers<i> == '1' then
3985                 if i == n && wback && i != LowestSetBit(registers) then
3986                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
3987                 else
3988                     MemA[address,4] = R[i];
3989                 address = address + 4;
3990 
3991         if registers<15> == '1' then // Only possible for encoding A1
3992             MemA[address,4] = PCStoreValue();
3993         if wback then R[n] = R[n] + 4*BitCount(registers);
3994 #endif
3995 
3996     bool success = false;
3997 
3998     if (ConditionPassed(opcode))
3999     {
4000         uint32_t n;
4001         uint32_t registers = 0;
4002         bool wback;
4003         const uint32_t addr_byte_size = GetAddressByteSize();
4004 
4005         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4006         switch (encoding)
4007         {
4008             case eEncodingT1:
4009                 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4010                 n = Bits32 (opcode, 10, 8);
4011                 registers = Bits32 (opcode, 7, 0);
4012                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
4013                 wback = true;
4014 
4015                 // if BitCount(registers) < 1 then UNPREDICTABLE;
4016                 if (BitCount (registers) < 1)
4017                     return false;
4018 
4019                 break;
4020 
4021             case eEncodingT2:
4022                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4023                 n = Bits32 (opcode, 19, 16);
4024                 registers = Bits32 (opcode, 15, 0);
4025                 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4026                 wback = BitIsSet (opcode, 21);
4027 
4028                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4029                 if ((n == 15) || (BitCount (registers) < 2))
4030                     return false;
4031 
4032                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4033                 if (wback && BitIsSet (registers, n))
4034                     return false;
4035 
4036                 break;
4037 
4038             case eEncodingA1:
4039                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4040                 n = Bits32 (opcode, 19, 16);
4041                 registers = Bits32 (opcode, 15, 0);
4042                 wback = BitIsSet (opcode, 21);
4043 
4044                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4045                 if ((n == 15) || (BitCount (registers) < 1))
4046                     return false;
4047 
4048                 break;
4049 
4050             default:
4051                 return false;
4052         }
4053 
4054         // address = R[n];
4055         int32_t offset = 0;
4056         const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4057         if (!success)
4058             return false;
4059 
4060         EmulateInstruction::Context context;
4061         context.type = EmulateInstruction::eContextRegisterStore;
4062         RegisterInfo base_reg;
4063         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4064 
4065         // for i = 0 to 14
4066         int lowest_set_bit = 14;
4067         for (int i = 0; i < 14; ++i)
4068         {
4069             // if registers<i> == '1' then
4070             if (BitIsSet (registers, i))
4071             {
4072                   if (i < lowest_set_bit)
4073                       lowest_set_bit = i;
4074                   // if i == n && wback && i != LowestSetBit(registers) then
4075                   if ((i == n) && wback && (i != lowest_set_bit))
4076                       // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4077                       WriteBits32UnknownToMemory (address + offset);
4078                   else
4079                   {
4080                      // MemA[address,4] = R[i];
4081                       uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4082                       if (!success)
4083                           return false;
4084 
4085                       RegisterInfo data_reg;
4086                       GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4087                       context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4088                       if (!MemAWrite (context, address + offset, data, addr_byte_size))
4089                           return false;
4090                   }
4091 
4092                   // address = address + 4;
4093                   offset += addr_byte_size;
4094             }
4095         }
4096 
4097         // if registers<15> == '1' then // Only possible for encoding A1
4098         //     MemA[address,4] = PCStoreValue();
4099         if (BitIsSet (registers, 15))
4100         {
4101             RegisterInfo pc_reg;
4102             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4103             context.SetRegisterPlusOffset (pc_reg, 8);
4104             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4105             if (!success)
4106                 return false;
4107 
4108             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4109                 return false;
4110         }
4111 
4112         // if wback then R[n] = R[n] + 4*BitCount(registers);
4113         if (wback)
4114         {
4115             offset = addr_byte_size * BitCount (registers);
4116             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4117             context.SetImmediateSigned (offset);
4118             addr_t data = address + offset;
4119             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4120                 return false;
4121         }
4122     }
4123     return true;
4124 }
4125 
4126 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
4127 // from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
4128 // of those locations can optionally be written back to the base register.
4129 bool
4130 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding)
4131 {
4132 #if 0
4133     if ConditionPassed() then
4134         EncodingSpecificOperations();
4135         address = R[n] - 4*BitCount(registers) + 4;
4136 
4137         for i = 0 to 14
4138             if registers<i> == '1' then
4139                 if i == n && wback && i != LowestSetBit(registers) then
4140                     MemA[address,4] = bits(32) UNKNOWN;
4141                 else
4142                     MemA[address,4] = R[i];
4143                 address = address + 4;
4144 
4145         if registers<15> == '1' then
4146             MemA[address,4] = PCStoreValue();
4147 
4148         if wback then R[n] = R[n] - 4*BitCount(registers);
4149 #endif
4150 
4151     bool success = false;
4152 
4153     if (ConditionPassed(opcode))
4154     {
4155         uint32_t n;
4156         uint32_t registers = 0;
4157         bool wback;
4158         const uint32_t addr_byte_size = GetAddressByteSize();
4159 
4160         // EncodingSpecificOperations();
4161         switch (encoding)
4162         {
4163             case eEncodingA1:
4164                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4165                 n = Bits32 (opcode, 19, 16);
4166                 registers = Bits32 (opcode, 15, 0);
4167                 wback = BitIsSet (opcode, 21);
4168 
4169                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4170                 if ((n == 15) || (BitCount (registers) < 1))
4171                     return false;
4172                 break;
4173             default:
4174                 return false;
4175         }
4176 
4177         // address = R[n] - 4*BitCount(registers) + 4;
4178         int32_t offset = 0;
4179         addr_t Rn = ReadCoreReg (n, &success);
4180         if (!success)
4181             return false;
4182 
4183         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4;
4184 
4185         EmulateInstruction::Context context;
4186         context.type = EmulateInstruction::eContextRegisterStore;
4187         RegisterInfo base_reg;
4188         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4189 
4190         // for i = 0 to 14
4191         int lowest_bit_set = 14;
4192         for (int i = 0; i < 14; ++i)
4193         {
4194             // if registers<i> == '1' then
4195             if (BitIsSet (registers, i))
4196             {
4197                 if (i < lowest_bit_set)
4198                     lowest_bit_set = i;
4199                 //if i == n && wback && i != LowestSetBit(registers) then
4200                 if ((i == n) && wback && (i != lowest_bit_set))
4201                     // MemA[address,4] = bits(32) UNKNOWN;
4202                     WriteBits32UnknownToMemory (address + offset);
4203                 else
4204                 {
4205                     // MemA[address,4] = R[i];
4206                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4207                     if (!success)
4208                         return false;
4209 
4210                     RegisterInfo data_reg;
4211                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4212                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4213                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4214                         return false;
4215                 }
4216 
4217                 // address = address + 4;
4218                 offset += addr_byte_size;
4219             }
4220         }
4221 
4222         // if registers<15> == '1' then
4223         //    MemA[address,4] = PCStoreValue();
4224         if (BitIsSet (registers, 15))
4225         {
4226             RegisterInfo pc_reg;
4227             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4228             context.SetRegisterPlusOffset (pc_reg, 8);
4229             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4230             if (!success)
4231                 return false;
4232 
4233             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4234                 return false;
4235         }
4236 
4237         // if wback then R[n] = R[n] - 4*BitCount(registers);
4238         if (wback)
4239         {
4240             offset = (addr_byte_size * BitCount (registers)) * -1;
4241             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4242             context.SetImmediateSigned (offset);
4243             addr_t data = Rn + offset;
4244             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4245                 return false;
4246         }
4247     }
4248     return true;
4249 }
4250 
4251 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
4252 // from a base register.  The consecutive memory locations end just below this address, and the address of the first of
4253 // those locations can optionally be written back to the base register.
4254 bool
4255 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding)
4256 {
4257 #if 0
4258     if ConditionPassed() then
4259         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4260         address = R[n] - 4*BitCount(registers);
4261 
4262         for i = 0 to 14
4263             if registers<i> == '1' then
4264                 if i == n && wback && i != LowestSetBit(registers) then
4265                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4266                 else
4267                     MemA[address,4] = R[i];
4268                 address = address + 4;
4269 
4270         if registers<15> == '1' then // Only possible for encoding A1
4271             MemA[address,4] = PCStoreValue();
4272 
4273         if wback then R[n] = R[n] - 4*BitCount(registers);
4274 #endif
4275 
4276 
4277     bool success = false;
4278 
4279     if (ConditionPassed(opcode))
4280     {
4281         uint32_t n;
4282         uint32_t registers = 0;
4283         bool wback;
4284         const uint32_t addr_byte_size = GetAddressByteSize();
4285 
4286         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4287         switch (encoding)
4288         {
4289             case eEncodingT1:
4290                 // if W == '1' && Rn == '1101' then SEE PUSH;
4291                 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
4292                 {
4293                     // See PUSH
4294                 }
4295                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4296                 n = Bits32 (opcode, 19, 16);
4297                 registers = Bits32 (opcode, 15, 0);
4298                 registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
4299                 wback = BitIsSet (opcode, 21);
4300                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4301                 if ((n == 15) || BitCount (registers) < 2)
4302                     return false;
4303                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4304                 if (wback && BitIsSet (registers, n))
4305                     return false;
4306                 break;
4307 
4308             case eEncodingA1:
4309                 // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH;
4310                 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
4311                 {
4312                     // See Push
4313                 }
4314                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4315                 n = Bits32 (opcode, 19, 16);
4316                 registers = Bits32 (opcode, 15, 0);
4317                 wback = BitIsSet (opcode, 21);
4318                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4319                 if ((n == 15) || BitCount (registers) < 1)
4320                     return false;
4321                 break;
4322 
4323             default:
4324                 return false;
4325         }
4326 
4327         // address = R[n] - 4*BitCount(registers);
4328 
4329         int32_t offset = 0;
4330         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4331         if (!success)
4332         return false;
4333 
4334         addr_t address = Rn - (addr_byte_size * BitCount (registers));
4335 
4336         EmulateInstruction::Context context;
4337         context.type = EmulateInstruction::eContextRegisterStore;
4338         RegisterInfo base_reg;
4339         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4340 
4341         // for i = 0 to 14
4342         uint32_t lowest_set_bit = 14;
4343         for (int i = 0; i < 14; ++i)
4344         {
4345             // if registers<i> == '1' then
4346             if (BitIsSet (registers, i))
4347             {
4348                 if (i < lowest_set_bit)
4349                     lowest_set_bit = i;
4350                 // if i == n && wback && i != LowestSetBit(registers) then
4351                 if ((i == n) && wback && (i != lowest_set_bit))
4352                     // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4353                     WriteBits32UnknownToMemory (address + offset);
4354                 else
4355                 {
4356                     // MemA[address,4] = R[i];
4357                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4358                     if (!success)
4359                         return false;
4360 
4361                     RegisterInfo data_reg;
4362                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4363                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4364                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4365                         return false;
4366                 }
4367 
4368                 // address = address + 4;
4369                 offset += addr_byte_size;
4370             }
4371         }
4372 
4373         // if registers<15> == '1' then // Only possible for encoding A1
4374         //     MemA[address,4] = PCStoreValue();
4375         if (BitIsSet (registers, 15))
4376         {
4377             RegisterInfo pc_reg;
4378             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4379             context.SetRegisterPlusOffset (pc_reg, 8);
4380             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4381             if (!success)
4382                 return false;
4383 
4384             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4385                 return false;
4386         }
4387 
4388         // if wback then R[n] = R[n] - 4*BitCount(registers);
4389         if (wback)
4390         {
4391             offset = (addr_byte_size * BitCount (registers)) * -1;
4392             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4393             context.SetImmediateSigned (offset);
4394             addr_t data = Rn + offset;
4395             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4396                 return false;
4397         }
4398     }
4399     return true;
4400 }
4401 
4402 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
4403 // from a base register.  The consecutive memory locations start just above this address, and the address of the last
4404 // of those locations can optionally be written back to the base register.
4405 bool
4406 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding)
4407 {
4408 #if 0
4409     if ConditionPassed() then
4410         EncodingSpecificOperations();
4411         address = R[n] + 4;
4412 
4413         for i = 0 to 14
4414             if registers<i> == '1' then
4415                 if i == n && wback && i != LowestSetBit(registers) then
4416                     MemA[address,4] = bits(32) UNKNOWN;
4417                 else
4418                     MemA[address,4] = R[i];
4419                 address = address + 4;
4420 
4421         if registers<15> == '1' then
4422             MemA[address,4] = PCStoreValue();
4423 
4424         if wback then R[n] = R[n] + 4*BitCount(registers);
4425 #endif
4426 
4427     bool success = false;
4428 
4429     if (ConditionPassed(opcode))
4430     {
4431         uint32_t n;
4432         uint32_t registers = 0;
4433         bool wback;
4434         const uint32_t addr_byte_size = GetAddressByteSize();
4435 
4436         // EncodingSpecificOperations();
4437         switch (encoding)
4438         {
4439             case eEncodingA1:
4440                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4441                 n = Bits32 (opcode, 19, 16);
4442                 registers = Bits32 (opcode, 15, 0);
4443                 wback = BitIsSet (opcode, 21);
4444 
4445                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4446                 if ((n == 15) && (BitCount (registers) < 1))
4447                     return false;
4448                 break;
4449             default:
4450                 return false;
4451         }
4452         // address = R[n] + 4;
4453 
4454         int32_t offset = 0;
4455         addr_t Rn = ReadCoreReg (n, &success);
4456         if (!success)
4457             return false;
4458 
4459         addr_t address = Rn + addr_byte_size;
4460 
4461         EmulateInstruction::Context context;
4462         context.type = EmulateInstruction::eContextRegisterStore;
4463         RegisterInfo base_reg;
4464         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4465 
4466         uint32_t lowest_set_bit = 14;
4467         // for i = 0 to 14
4468         for (int i = 0; i < 14; ++i)
4469         {
4470             // if registers<i> == '1' then
4471             if (BitIsSet (registers, i))
4472             {
4473                 if (i < lowest_set_bit)
4474                     lowest_set_bit = i;
4475                 // if i == n && wback && i != LowestSetBit(registers) then
4476                 if ((i == n) && wback && (i != lowest_set_bit))
4477                     // MemA[address,4] = bits(32) UNKNOWN;
4478                     WriteBits32UnknownToMemory (address + offset);
4479                 // else
4480                 else
4481                 {
4482                     // MemA[address,4] = R[i];
4483                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4484                     if (!success)
4485                         return false;
4486 
4487                     RegisterInfo data_reg;
4488                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4489                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size);
4490                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4491                         return false;
4492                 }
4493 
4494                 // address = address + 4;
4495                 offset += addr_byte_size;
4496             }
4497         }
4498 
4499         // if registers<15> == '1' then
4500             // MemA[address,4] = PCStoreValue();
4501         if (BitIsSet (registers, 15))
4502         {
4503             RegisterInfo pc_reg;
4504             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4505             context.SetRegisterPlusOffset (pc_reg, 8);
4506             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4507             if (!success)
4508             return false;
4509 
4510             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4511                 return false;
4512         }
4513 
4514         // if wback then R[n] = R[n] + 4*BitCount(registers);
4515         if (wback)
4516         {
4517             offset = addr_byte_size * BitCount (registers);
4518             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4519             context.SetImmediateSigned (offset);
4520             addr_t data = Rn + offset;
4521             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4522                 return false;
4523         }
4524     }
4525     return true;
4526 }
4527 
4528 // STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word
4529 // from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
4530 bool
4531 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding)
4532 {
4533 #if 0
4534     if ConditionPassed() then
4535         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4536         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4537         address = if index then offset_addr else R[n];
4538         if UnalignedSupport() || address<1:0> == '00' then
4539             MemU[address,4] = R[t];
4540         else // Can only occur before ARMv7
4541             MemU[address,4] = bits(32) UNKNOWN;
4542         if wback then R[n] = offset_addr;
4543 #endif
4544 
4545     bool success = false;
4546 
4547     if (ConditionPassed(opcode))
4548     {
4549         const uint32_t addr_byte_size = GetAddressByteSize();
4550 
4551         uint32_t t;
4552         uint32_t n;
4553         uint32_t imm32;
4554         bool index;
4555         bool add;
4556         bool wback;
4557         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4558         switch (encoding)
4559         {
4560             case eEncodingT1:
4561                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
4562                 t = Bits32 (opcode, 2, 0);
4563                 n = Bits32 (opcode, 5, 3);
4564                 imm32 = Bits32 (opcode, 10, 6) << 2;
4565 
4566                 // index = TRUE; add = TRUE; wback = FALSE;
4567                 index = true;
4568                 add = false;
4569                 wback = false;
4570                 break;
4571 
4572             case eEncodingT2:
4573                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4574                 t = Bits32 (opcode, 10, 8);
4575                 n = 13;
4576                 imm32 = Bits32 (opcode, 7, 0) << 2;
4577 
4578                 // index = TRUE; add = TRUE; wback = FALSE;
4579                 index = true;
4580                 add = true;
4581                 wback = false;
4582                 break;
4583 
4584             case eEncodingT3:
4585                 // if Rn == '1111' then UNDEFINED;
4586                 if (Bits32 (opcode, 19, 16) == 15)
4587                     return false;
4588 
4589                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4590                 t = Bits32 (opcode, 15, 12);
4591                 n = Bits32 (opcode, 19, 16);
4592                 imm32 = Bits32 (opcode, 11, 0);
4593 
4594                 // index = TRUE; add = TRUE; wback = FALSE;
4595                 index = true;
4596                 add = true;
4597                 wback = false;
4598 
4599                 // if t == 15 then UNPREDICTABLE;
4600                 if (t == 15)
4601                     return false;
4602                 break;
4603 
4604             case eEncodingT4:
4605                 // if P == '1' && U == '1' && W == '0' then SEE STRT;
4606                 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH;
4607                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4608                 if ((Bits32 (opcode, 19, 16) == 15)
4609                       || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
4610                     return false;
4611 
4612                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4613                 t = Bits32 (opcode, 15, 12);
4614                 n = Bits32 (opcode, 19, 16);
4615                 imm32 = Bits32 (opcode, 7, 0);
4616 
4617                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4618                 index = BitIsSet (opcode, 10);
4619                 add = BitIsSet (opcode, 9);
4620                 wback = BitIsSet (opcode, 8);
4621 
4622                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
4623                 if ((t == 15) || (wback && (n == t)))
4624                     return false;
4625                 break;
4626 
4627             default:
4628                 return false;
4629         }
4630 
4631         addr_t offset_addr;
4632         addr_t address;
4633 
4634         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4635         uint32_t base_address = ReadCoreReg (n, &success);
4636         if (!success)
4637             return false;
4638 
4639         if (add)
4640             offset_addr = base_address + imm32;
4641         else
4642             offset_addr = base_address - imm32;
4643 
4644         // address = if index then offset_addr else R[n];
4645         if (index)
4646             address = offset_addr;
4647         else
4648             address = base_address;
4649 
4650         EmulateInstruction::Context context;
4651         context.type = eContextRegisterStore;
4652         RegisterInfo base_reg;
4653         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4654 
4655         // if UnalignedSupport() || address<1:0> == '00' then
4656         if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
4657         {
4658             // MemU[address,4] = R[t];
4659             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4660             if (!success)
4661                 return false;
4662 
4663             RegisterInfo data_reg;
4664             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4665             int32_t offset = address - base_address;
4666             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4667             if (!MemUWrite (context, address, data, addr_byte_size))
4668                 return false;
4669         }
4670         else
4671         {
4672             // MemU[address,4] = bits(32) UNKNOWN;
4673             WriteBits32UnknownToMemory (address);
4674         }
4675 
4676         // if wback then R[n] = offset_addr;
4677         if (wback)
4678         {
4679             context.type = eContextRegisterLoad;
4680             context.SetAddress (offset_addr);
4681             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4682                 return false;
4683         }
4684     }
4685     return true;
4686 }
4687 
4688 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a
4689 // word from a register to memory.   The offset register value can optionally be shifted.
4690 bool
4691 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding)
4692 {
4693 #if 0
4694     if ConditionPassed() then
4695         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4696         offset = Shift(R[m], shift_t, shift_n, APSR.C);
4697         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4698         address = if index then offset_addr else R[n];
4699         if t == 15 then // Only possible for encoding A1
4700             data = PCStoreValue();
4701         else
4702             data = R[t];
4703         if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4704             MemU[address,4] = data;
4705         else // Can only occur before ARMv7
4706             MemU[address,4] = bits(32) UNKNOWN;
4707         if wback then R[n] = offset_addr;
4708 #endif
4709 
4710     bool success = false;
4711 
4712     if (ConditionPassed(opcode))
4713     {
4714         const uint32_t addr_byte_size = GetAddressByteSize();
4715 
4716         uint32_t t;
4717         uint32_t n;
4718         uint32_t m;
4719         ARM_ShifterType shift_t;
4720         uint32_t shift_n;
4721         bool index;
4722         bool add;
4723         bool wback;
4724 
4725         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4726         switch (encoding)
4727         {
4728             case eEncodingT1:
4729                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4730                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4731                 t = Bits32 (opcode, 2, 0);
4732                 n = Bits32 (opcode, 5, 3);
4733                 m = Bits32 (opcode, 8, 6);
4734 
4735                 // index = TRUE; add = TRUE; wback = FALSE;
4736                 index = true;
4737                 add = true;
4738                 wback = false;
4739 
4740                 // (shift_t, shift_n) = (SRType_LSL, 0);
4741                 shift_t = SRType_LSL;
4742                 shift_n = 0;
4743                 break;
4744 
4745             case eEncodingT2:
4746                 // if Rn == '1111' then UNDEFINED;
4747                 if (Bits32 (opcode, 19, 16) == 15)
4748                     return false;
4749 
4750                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4751                 t = Bits32 (opcode, 15, 12);
4752                 n = Bits32 (opcode, 19, 16);
4753                 m = Bits32 (opcode, 3, 0);
4754 
4755                 // index = TRUE; add = TRUE; wback = FALSE;
4756                 index = true;
4757                 add = true;
4758                 wback = false;
4759 
4760                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4761                 shift_t = SRType_LSL;
4762                 shift_n = Bits32 (opcode, 5, 4);
4763 
4764                 // if t == 15 || BadReg(m) then UNPREDICTABLE;
4765                 if ((t == 15) || (BadReg (m)))
4766                     return false;
4767                 break;
4768 
4769             case eEncodingA1:
4770             {
4771                 // if P == '0' && W == '1' then SEE STRT;
4772                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4773                 t = Bits32 (opcode, 15, 12);
4774                 n = Bits32 (opcode, 19, 16);
4775                 m = Bits32 (opcode, 3, 0);
4776 
4777                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
4778                 index = BitIsSet (opcode, 24);
4779                 add = BitIsSet (opcode, 23);
4780                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
4781 
4782                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
4783                 uint32_t typ = Bits32 (opcode, 6, 5);
4784                 uint32_t imm5 = Bits32 (opcode, 11, 7);
4785                 shift_n = DecodeImmShift(typ, imm5, shift_t);
4786 
4787                 // if m == 15 then UNPREDICTABLE;
4788                 if (m == 15)
4789                     return false;
4790 
4791                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
4792                 if (wback && ((n == 15) || (n == t)))
4793                     return false;
4794 
4795                 break;
4796             }
4797             default:
4798                 return false;
4799         }
4800 
4801         addr_t offset_addr;
4802         addr_t address;
4803         int32_t offset = 0;
4804 
4805         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4806         if (!success)
4807             return false;
4808 
4809         uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
4810         if (!success)
4811             return false;
4812 
4813         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4814         offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success);
4815         if (!success)
4816             return false;
4817 
4818         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4819         if (add)
4820             offset_addr = base_address + offset;
4821         else
4822             offset_addr = base_address - offset;
4823 
4824         // address = if index then offset_addr else R[n];
4825         if (index)
4826             address = offset_addr;
4827         else
4828             address = base_address;
4829 
4830         uint32_t data;
4831         // if t == 15 then // Only possible for encoding A1
4832         if (t == 15)
4833             // data = PCStoreValue();
4834             data = ReadCoreReg (PC_REG, &success);
4835         else
4836             // data = R[t];
4837             data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4838 
4839         if (!success)
4840             return false;
4841 
4842         EmulateInstruction::Context context;
4843         context.type = eContextRegisterStore;
4844 
4845         // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4846         if (UnalignedSupport ()
4847             || (BitIsClear (address, 1) && BitIsClear (address, 0))
4848             || CurrentInstrSet() == eModeARM)
4849         {
4850             // MemU[address,4] = data;
4851 
4852             RegisterInfo base_reg;
4853             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 +  n, base_reg);
4854 
4855             RegisterInfo data_reg;
4856             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4857 
4858             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4859             if (!MemUWrite (context, address, data, addr_byte_size))
4860                 return false;
4861 
4862         }
4863         else
4864             // MemU[address,4] = bits(32) UNKNOWN;
4865             WriteBits32UnknownToMemory (address);
4866 
4867         // if wback then R[n] = offset_addr;
4868         if (wback)
4869         {
4870             context.type = eContextRegisterLoad;
4871             context.SetAddress (offset_addr);
4872             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4873                 return false;
4874         }
4875 
4876     }
4877     return true;
4878 }
4879 
4880 bool
4881 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding)
4882 {
4883 #if 0
4884     if ConditionPassed() then
4885         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4886         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4887         address = if index then offset_addr else R[n];
4888         MemU[address,1] = R[t]<7:0>;
4889         if wback then R[n] = offset_addr;
4890 #endif
4891 
4892 
4893     bool success = false;
4894 
4895     if (ConditionPassed(opcode))
4896     {
4897         uint32_t t;
4898         uint32_t n;
4899         uint32_t imm32;
4900         bool index;
4901         bool add;
4902         bool wback;
4903         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4904         switch (encoding)
4905         {
4906             case eEncodingT1:
4907                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
4908                 t = Bits32 (opcode, 2, 0);
4909                 n = Bits32 (opcode, 5, 3);
4910                 imm32 = Bits32 (opcode, 10, 6);
4911 
4912                 // index = TRUE; add = TRUE; wback = FALSE;
4913                 index = true;
4914                 add = true;
4915                 wback = false;
4916                 break;
4917 
4918             case eEncodingT2:
4919                 // if Rn == '1111' then UNDEFINED;
4920                 if (Bits32 (opcode, 19, 16) == 15)
4921                     return false;
4922 
4923                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4924                 t = Bits32 (opcode, 15, 12);
4925                 n = Bits32 (opcode, 19, 16);
4926                 imm32 = Bits32 (opcode, 11, 0);
4927 
4928                 // index = TRUE; add = TRUE; wback = FALSE;
4929                 index = true;
4930                 add = true;
4931                 wback = false;
4932 
4933                 // if BadReg(t) then UNPREDICTABLE;
4934                 if (BadReg (t))
4935                     return false;
4936                 break;
4937 
4938             case eEncodingT3:
4939                 // if P == '1' && U == '1' && W == '0' then SEE STRBT;
4940                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4941                 if (Bits32 (opcode, 19, 16) == 15)
4942                     return false;
4943 
4944                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4945                 t = Bits32 (opcode, 15, 12);
4946                 n = Bits32 (opcode, 19, 16);
4947                 imm32 = Bits32 (opcode, 7, 0);
4948 
4949                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4950                 index = BitIsSet (opcode, 10);
4951                 add = BitIsSet (opcode, 9);
4952                 wback = BitIsSet (opcode, 8);
4953 
4954                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
4955                 if ((BadReg (t)) || (wback && (n == t)))
4956                     return false;
4957                 break;
4958 
4959             default:
4960                 return false;
4961         }
4962 
4963         addr_t offset_addr;
4964         addr_t address;
4965         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4966         if (!success)
4967             return false;
4968 
4969         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4970         if (add)
4971             offset_addr = base_address + imm32;
4972         else
4973             offset_addr = base_address - imm32;
4974 
4975         // address = if index then offset_addr else R[n];
4976         if (index)
4977             address = offset_addr;
4978         else
4979             address = base_address;
4980 
4981         // MemU[address,1] = R[t]<7:0>
4982         RegisterInfo base_reg;
4983         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4984 
4985         RegisterInfo data_reg;
4986         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4987 
4988         EmulateInstruction::Context context;
4989         context.type = eContextRegisterStore;
4990         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4991 
4992         uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4993         if (!success)
4994             return false;
4995 
4996         data = Bits32 (data, 7, 0);
4997 
4998         if (!MemUWrite (context, address, data, 1))
4999             return false;
5000 
5001         // if wback then R[n] = offset_addr;
5002         if (wback)
5003         {
5004             context.type = eContextRegisterLoad;
5005             context.SetAddress (offset_addr);
5006             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5007                 return false;
5008         }
5009 
5010     }
5011 
5012     return true;
5013 }
5014 
5015 // STRH (register) calculates an address from a base register value and an offset register value, and stores a
5016 // halfword from a register to memory.  The offset register alue can be shifted left by 0, 1, 2, or 3 bits.
5017 bool
5018 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding)
5019 {
5020 #if 0
5021     if ConditionPassed() then
5022         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5023         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5024         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5025         address = if index then offset_addr else R[n];
5026         if UnalignedSupport() || address<0> == '0' then
5027             MemU[address,2] = R[t]<15:0>;
5028         else // Can only occur before ARMv7
5029             MemU[address,2] = bits(16) UNKNOWN;
5030         if wback then R[n] = offset_addr;
5031 #endif
5032 
5033     bool success = false;
5034 
5035     if (ConditionPassed(opcode))
5036     {
5037         uint32_t t;
5038         uint32_t n;
5039         uint32_t m;
5040         bool index;
5041         bool add;
5042         bool wback;
5043         ARM_ShifterType shift_t;
5044         uint32_t shift_n;
5045 
5046         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5047         switch (encoding)
5048         {
5049             case eEncodingT1:
5050                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5051                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5052                 t = Bits32 (opcode, 2, 0);
5053                 n = Bits32 (opcode, 5, 3);
5054                 m = Bits32 (opcode, 8, 6);
5055 
5056                 // index = TRUE; add = TRUE; wback = FALSE;
5057                 index = true;
5058                 add = true;
5059                 wback = false;
5060 
5061                 // (shift_t, shift_n) = (SRType_LSL, 0);
5062                 shift_t = SRType_LSL;
5063                 shift_n = 0;
5064 
5065                 break;
5066 
5067             case eEncodingT2:
5068                 // if Rn == '1111' then UNDEFINED;
5069                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5070                 t = Bits32 (opcode, 15, 12);
5071                 n = Bits32 (opcode, 19, 16);
5072                 m = Bits32 (opcode, 3, 0);
5073                 if (n == 15)
5074                     return false;
5075 
5076                 // index = TRUE; add = TRUE; wback = FALSE;
5077                 index = true;
5078                 add = true;
5079                 wback = false;
5080 
5081                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5082                 shift_t = SRType_LSL;
5083                 shift_n = Bits32 (opcode, 5, 4);
5084 
5085                 // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5086                 if (BadReg (t) || BadReg (m))
5087                     return false;
5088 
5089                 break;
5090 
5091             case eEncodingA1:
5092                 // if P == '0' && W == '1' then SEE STRHT;
5093                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5094                 t = Bits32 (opcode, 15, 12);
5095                 n = Bits32 (opcode, 19, 16);
5096                 m = Bits32 (opcode, 3, 0);
5097 
5098                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5099                 index = BitIsSet (opcode, 24);
5100                 add = BitIsSet (opcode, 23);
5101                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5102 
5103                 // (shift_t, shift_n) = (SRType_LSL, 0);
5104                 shift_t = SRType_LSL;
5105                 shift_n = 0;
5106 
5107                 // if t == 15 || m == 15 then UNPREDICTABLE;
5108                 if ((t == 15) || (m == 15))
5109                     return false;
5110 
5111                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5112                 if (wback && ((n == 15) || (n == t)))
5113                     return false;
5114 
5115                 break;
5116 
5117             default:
5118                 return false;
5119         }
5120 
5121         uint32_t Rm = ReadCoreReg (m, &success);
5122         if (!success)
5123             return false;
5124 
5125         uint32_t Rn = ReadCoreReg (n, &success);
5126         if (!success)
5127             return false;
5128 
5129         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5130         uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
5131         if (!success)
5132             return false;
5133 
5134         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5135         addr_t offset_addr;
5136         if (add)
5137             offset_addr = Rn + offset;
5138         else
5139             offset_addr = Rn - offset;
5140 
5141         // address = if index then offset_addr else R[n];
5142         addr_t address;
5143         if (index)
5144             address = offset_addr;
5145         else
5146             address = Rn;
5147 
5148         EmulateInstruction::Context context;
5149         context.type = eContextRegisterStore;
5150         RegisterInfo base_reg;
5151         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5152         RegisterInfo offset_reg;
5153         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5154 
5155         // if UnalignedSupport() || address<0> == '0' then
5156         if (UnalignedSupport() || BitIsClear (address, 0))
5157         {
5158             // MemU[address,2] = R[t]<15:0>;
5159             uint32_t Rt = ReadCoreReg (t, &success);
5160             if (!success)
5161                 return false;
5162 
5163             EmulateInstruction::Context context;
5164             context.type = eContextRegisterStore;
5165             RegisterInfo base_reg;
5166             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5167             RegisterInfo offset_reg;
5168             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5169             RegisterInfo data_reg;
5170             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5171             context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
5172 
5173             if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2))
5174                 return false;
5175         }
5176         else // Can only occur before ARMv7
5177         {
5178             // MemU[address,2] = bits(16) UNKNOWN;
5179         }
5180 
5181         // if wback then R[n] = offset_addr;
5182         if (wback)
5183         {
5184             context.type = eContextAdjustBaseRegister;
5185             context.SetAddress (offset_addr);
5186             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5187                 return false;
5188         }
5189     }
5190 
5191     return true;
5192 }
5193 
5194 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value,
5195 // and writes the result to the destination register.  It can optionally update the condition flags
5196 // based on the result.
5197 bool
5198 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding)
5199 {
5200 #if 0
5201     // ARM pseudo code...
5202     if ConditionPassed() then
5203         EncodingSpecificOperations();
5204         (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5205         if d == 15 then         // Can only occur for ARM encoding
5206             ALUWritePC(result); // setflags is always FALSE here
5207         else
5208             R[d] = result;
5209             if setflags then
5210                 APSR.N = result<31>;
5211                 APSR.Z = IsZeroBit(result);
5212                 APSR.C = carry;
5213                 APSR.V = overflow;
5214 #endif
5215 
5216     bool success = false;
5217 
5218     if (ConditionPassed(opcode))
5219     {
5220         uint32_t Rd, Rn;
5221         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
5222         bool setflags;
5223         switch (encoding)
5224         {
5225         case eEncodingT1:
5226             Rd = Bits32(opcode, 11, 8);
5227             Rn = Bits32(opcode, 19, 16);
5228             setflags = BitIsSet(opcode, 20);
5229             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5230             if (BadReg(Rd) || BadReg(Rn))
5231                 return false;
5232             break;
5233         case eEncodingA1:
5234             Rd = Bits32(opcode, 15, 12);
5235             Rn = Bits32(opcode, 19, 16);
5236             setflags = BitIsSet(opcode, 20);
5237             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5238 
5239             if (Rd == 15 && setflags)
5240                 return EmulateSUBSPcLrEtc (opcode, encoding);
5241             break;
5242         default:
5243             return false;
5244         }
5245 
5246         // Read the first operand.
5247         int32_t val1 = ReadCoreReg(Rn, &success);
5248         if (!success)
5249             return false;
5250 
5251         AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5252 
5253         EmulateInstruction::Context context;
5254         context.type = EmulateInstruction::eContextImmediate;
5255         context.SetNoArgs ();
5256 
5257         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5258             return false;
5259     }
5260     return true;
5261 }
5262 
5263 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted
5264 // register value, and writes the result to the destination register.  It can optionally update the
5265 // condition flags based on the result.
5266 bool
5267 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding)
5268 {
5269 #if 0
5270     // ARM pseudo code...
5271     if ConditionPassed() then
5272         EncodingSpecificOperations();
5273         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5274         (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5275         if d == 15 then         // Can only occur for ARM encoding
5276             ALUWritePC(result); // setflags is always FALSE here
5277         else
5278             R[d] = result;
5279             if setflags then
5280                 APSR.N = result<31>;
5281                 APSR.Z = IsZeroBit(result);
5282                 APSR.C = carry;
5283                 APSR.V = overflow;
5284 #endif
5285 
5286     bool success = false;
5287 
5288     if (ConditionPassed(opcode))
5289     {
5290         uint32_t Rd, Rn, Rm;
5291         ARM_ShifterType shift_t;
5292         uint32_t shift_n; // the shift applied to the value read from Rm
5293         bool setflags;
5294         switch (encoding)
5295         {
5296         case eEncodingT1:
5297             Rd = Rn = Bits32(opcode, 2, 0);
5298             Rm = Bits32(opcode, 5, 3);
5299             setflags = !InITBlock();
5300             shift_t = SRType_LSL;
5301             shift_n = 0;
5302             break;
5303         case eEncodingT2:
5304             Rd = Bits32(opcode, 11, 8);
5305             Rn = Bits32(opcode, 19, 16);
5306             Rm = Bits32(opcode, 3, 0);
5307             setflags = BitIsSet(opcode, 20);
5308             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5309             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5310                 return false;
5311             break;
5312         case eEncodingA1:
5313             Rd = Bits32(opcode, 15, 12);
5314             Rn = Bits32(opcode, 19, 16);
5315             Rm = Bits32(opcode, 3, 0);
5316             setflags = BitIsSet(opcode, 20);
5317             shift_n = DecodeImmShiftARM(opcode, shift_t);
5318 
5319             if (Rd == 15 && setflags)
5320                 return EmulateSUBSPcLrEtc (opcode, encoding);
5321             break;
5322         default:
5323             return false;
5324         }
5325 
5326         // Read the first operand.
5327         int32_t val1 = ReadCoreReg(Rn, &success);
5328         if (!success)
5329             return false;
5330 
5331         // Read the second operand.
5332         int32_t val2 = ReadCoreReg(Rm, &success);
5333         if (!success)
5334             return false;
5335 
5336         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5337         if (!success)
5338             return false;
5339         AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5340 
5341         EmulateInstruction::Context context;
5342         context.type = EmulateInstruction::eContextImmediate;
5343         context.SetNoArgs ();
5344 
5345         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5346             return false;
5347     }
5348     return true;
5349 }
5350 
5351 // This instruction adds an immediate value to the PC value to form a PC-relative address,
5352 // and writes the result to the destination register.
5353 bool
5354 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding)
5355 {
5356 #if 0
5357     // ARM pseudo code...
5358     if ConditionPassed() then
5359         EncodingSpecificOperations();
5360         result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5361         if d == 15 then         // Can only occur for ARM encodings
5362             ALUWritePC(result);
5363         else
5364             R[d] = result;
5365 #endif
5366 
5367     bool success = false;
5368 
5369     if (ConditionPassed(opcode))
5370     {
5371         uint32_t Rd;
5372         uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5373         bool add;
5374         switch (encoding)
5375         {
5376         case eEncodingT1:
5377             Rd = Bits32(opcode, 10, 8);
5378             imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5379             break;
5380         case eEncodingT2:
5381         case eEncodingT3:
5382             Rd = Bits32(opcode, 11, 8);
5383             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5384             add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5385             if (BadReg(Rd))
5386                 return false;
5387             break;
5388         case eEncodingA1:
5389         case eEncodingA2:
5390             Rd = Bits32(opcode, 15, 12);
5391             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5392             add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5393             break;
5394         default:
5395             return false;
5396         }
5397 
5398         // Read the PC value.
5399         uint32_t pc = ReadCoreReg(PC_REG, &success);
5400         if (!success)
5401             return false;
5402 
5403         uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5404 
5405         EmulateInstruction::Context context;
5406         context.type = EmulateInstruction::eContextImmediate;
5407         context.SetNoArgs ();
5408 
5409         if (!WriteCoreReg(context, result, Rd))
5410             return false;
5411     }
5412     return true;
5413 }
5414 
5415 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result
5416 // to the destination register.  It can optionally update the condition flags based on the result.
5417 bool
5418 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding)
5419 {
5420 #if 0
5421     // ARM pseudo code...
5422     if ConditionPassed() then
5423         EncodingSpecificOperations();
5424         result = R[n] AND imm32;
5425         if d == 15 then         // Can only occur for ARM encoding
5426             ALUWritePC(result); // setflags is always FALSE here
5427         else
5428             R[d] = result;
5429             if setflags then
5430                 APSR.N = result<31>;
5431                 APSR.Z = IsZeroBit(result);
5432                 APSR.C = carry;
5433                 // APSR.V unchanged
5434 #endif
5435 
5436     bool success = false;
5437 
5438     if (ConditionPassed(opcode))
5439     {
5440         uint32_t Rd, Rn;
5441         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
5442         bool setflags;
5443         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5444         switch (encoding)
5445         {
5446         case eEncodingT1:
5447             Rd = Bits32(opcode, 11, 8);
5448             Rn = Bits32(opcode, 19, 16);
5449             setflags = BitIsSet(opcode, 20);
5450             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5451             // if Rd == '1111' && S == '1' then SEE TST (immediate);
5452             if (Rd == 15 && setflags)
5453                 return EmulateTSTImm(opcode, eEncodingT1);
5454             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
5455                 return false;
5456             break;
5457         case eEncodingA1:
5458             Rd = Bits32(opcode, 15, 12);
5459             Rn = Bits32(opcode, 19, 16);
5460             setflags = BitIsSet(opcode, 20);
5461             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5462 
5463             if (Rd == 15 && setflags)
5464                 return EmulateSUBSPcLrEtc (opcode, encoding);
5465             break;
5466         default:
5467             return false;
5468         }
5469 
5470         // Read the first operand.
5471         uint32_t val1 = ReadCoreReg(Rn, &success);
5472         if (!success)
5473             return false;
5474 
5475         uint32_t result = val1 & imm32;
5476 
5477         EmulateInstruction::Context context;
5478         context.type = EmulateInstruction::eContextImmediate;
5479         context.SetNoArgs ();
5480 
5481         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5482             return false;
5483     }
5484     return true;
5485 }
5486 
5487 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value,
5488 // and writes the result to the destination register.  It can optionally update the condition flags
5489 // based on the result.
5490 bool
5491 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding)
5492 {
5493 #if 0
5494     // ARM pseudo code...
5495     if ConditionPassed() then
5496         EncodingSpecificOperations();
5497         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5498         result = R[n] AND shifted;
5499         if d == 15 then         // Can only occur for ARM encoding
5500             ALUWritePC(result); // setflags is always FALSE here
5501         else
5502             R[d] = result;
5503             if setflags then
5504                 APSR.N = result<31>;
5505                 APSR.Z = IsZeroBit(result);
5506                 APSR.C = carry;
5507                 // APSR.V unchanged
5508 #endif
5509 
5510     bool success = false;
5511 
5512     if (ConditionPassed(opcode))
5513     {
5514         uint32_t Rd, Rn, Rm;
5515         ARM_ShifterType shift_t;
5516         uint32_t shift_n; // the shift applied to the value read from Rm
5517         bool setflags;
5518         uint32_t carry;
5519         switch (encoding)
5520         {
5521         case eEncodingT1:
5522             Rd = Rn = Bits32(opcode, 2, 0);
5523             Rm = Bits32(opcode, 5, 3);
5524             setflags = !InITBlock();
5525             shift_t = SRType_LSL;
5526             shift_n = 0;
5527             break;
5528         case eEncodingT2:
5529             Rd = Bits32(opcode, 11, 8);
5530             Rn = Bits32(opcode, 19, 16);
5531             Rm = Bits32(opcode, 3, 0);
5532             setflags = BitIsSet(opcode, 20);
5533             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5534             // if Rd == '1111' && S == '1' then SEE TST (register);
5535             if (Rd == 15 && setflags)
5536                 return EmulateTSTReg(opcode, eEncodingT2);
5537             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
5538                 return false;
5539             break;
5540         case eEncodingA1:
5541             Rd = Bits32(opcode, 15, 12);
5542             Rn = Bits32(opcode, 19, 16);
5543             Rm = Bits32(opcode, 3, 0);
5544             setflags = BitIsSet(opcode, 20);
5545             shift_n = DecodeImmShiftARM(opcode, shift_t);
5546 
5547             if (Rd == 15 && setflags)
5548                 return EmulateSUBSPcLrEtc (opcode, encoding);
5549             break;
5550         default:
5551             return false;
5552         }
5553 
5554         // Read the first operand.
5555         uint32_t val1 = ReadCoreReg(Rn, &success);
5556         if (!success)
5557             return false;
5558 
5559         // Read the second operand.
5560         uint32_t val2 = ReadCoreReg(Rm, &success);
5561         if (!success)
5562             return false;
5563 
5564         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5565         if (!success)
5566             return false;
5567         uint32_t result = val1 & shifted;
5568 
5569         EmulateInstruction::Context context;
5570         context.type = EmulateInstruction::eContextImmediate;
5571         context.SetNoArgs ();
5572 
5573         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5574             return false;
5575     }
5576     return true;
5577 }
5578 
5579 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an
5580 // immediate value, and writes the result to the destination register.  It can optionally update the
5581 // condition flags based on the result.
5582 bool
5583 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding)
5584 {
5585 #if 0
5586     // ARM pseudo code...
5587     if ConditionPassed() then
5588         EncodingSpecificOperations();
5589         result = R[n] AND NOT(imm32);
5590         if d == 15 then         // Can only occur for ARM encoding
5591             ALUWritePC(result); // setflags is always FALSE here
5592         else
5593             R[d] = result;
5594             if setflags then
5595                 APSR.N = result<31>;
5596                 APSR.Z = IsZeroBit(result);
5597                 APSR.C = carry;
5598                 // APSR.V unchanged
5599 #endif
5600 
5601     bool success = false;
5602 
5603     if (ConditionPassed(opcode))
5604     {
5605         uint32_t Rd, Rn;
5606         uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn
5607         bool setflags;
5608         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5609         switch (encoding)
5610         {
5611         case eEncodingT1:
5612             Rd = Bits32(opcode, 11, 8);
5613             Rn = Bits32(opcode, 19, 16);
5614             setflags = BitIsSet(opcode, 20);
5615             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5616             if (BadReg(Rd) || BadReg(Rn))
5617                 return false;
5618             break;
5619         case eEncodingA1:
5620             Rd = Bits32(opcode, 15, 12);
5621             Rn = Bits32(opcode, 19, 16);
5622             setflags = BitIsSet(opcode, 20);
5623             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5624 
5625             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5626             if (Rd == 15 && setflags)
5627                 return EmulateSUBSPcLrEtc (opcode, encoding);
5628             break;
5629         default:
5630             return false;
5631         }
5632 
5633         // Read the first operand.
5634         uint32_t val1 = ReadCoreReg(Rn, &success);
5635         if (!success)
5636             return false;
5637 
5638         uint32_t result = val1 & ~imm32;
5639 
5640         EmulateInstruction::Context context;
5641         context.type = EmulateInstruction::eContextImmediate;
5642         context.SetNoArgs ();
5643 
5644         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5645             return false;
5646     }
5647     return true;
5648 }
5649 
5650 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an
5651 // optionally-shifted register value, and writes the result to the destination register.
5652 // It can optionally update the condition flags based on the result.
5653 bool
5654 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding)
5655 {
5656 #if 0
5657     // ARM pseudo code...
5658     if ConditionPassed() then
5659         EncodingSpecificOperations();
5660         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5661         result = R[n] AND NOT(shifted);
5662         if d == 15 then         // Can only occur for ARM encoding
5663             ALUWritePC(result); // setflags is always FALSE here
5664         else
5665             R[d] = result;
5666             if setflags then
5667                 APSR.N = result<31>;
5668                 APSR.Z = IsZeroBit(result);
5669                 APSR.C = carry;
5670                 // APSR.V unchanged
5671 #endif
5672 
5673     bool success = false;
5674 
5675     if (ConditionPassed(opcode))
5676     {
5677         uint32_t Rd, Rn, Rm;
5678         ARM_ShifterType shift_t;
5679         uint32_t shift_n; // the shift applied to the value read from Rm
5680         bool setflags;
5681         uint32_t carry;
5682         switch (encoding)
5683         {
5684         case eEncodingT1:
5685             Rd = Rn = Bits32(opcode, 2, 0);
5686             Rm = Bits32(opcode, 5, 3);
5687             setflags = !InITBlock();
5688             shift_t = SRType_LSL;
5689             shift_n = 0;
5690             break;
5691         case eEncodingT2:
5692             Rd = Bits32(opcode, 11, 8);
5693             Rn = Bits32(opcode, 19, 16);
5694             Rm = Bits32(opcode, 3, 0);
5695             setflags = BitIsSet(opcode, 20);
5696             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5697             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5698                 return false;
5699             break;
5700         case eEncodingA1:
5701             Rd = Bits32(opcode, 15, 12);
5702             Rn = Bits32(opcode, 19, 16);
5703             Rm = Bits32(opcode, 3, 0);
5704             setflags = BitIsSet(opcode, 20);
5705             shift_n = DecodeImmShiftARM(opcode, shift_t);
5706 
5707             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5708             if (Rd == 15 && setflags)
5709                 return EmulateSUBSPcLrEtc (opcode, encoding);
5710             break;
5711         default:
5712             return false;
5713         }
5714 
5715         // Read the first operand.
5716         uint32_t val1 = ReadCoreReg(Rn, &success);
5717         if (!success)
5718             return false;
5719 
5720         // Read the second operand.
5721         uint32_t val2 = ReadCoreReg(Rm, &success);
5722         if (!success)
5723             return false;
5724 
5725         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5726         if (!success)
5727             return false;
5728         uint32_t result = val1 & ~shifted;
5729 
5730         EmulateInstruction::Context context;
5731         context.type = EmulateInstruction::eContextImmediate;
5732         context.SetNoArgs ();
5733 
5734         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5735             return false;
5736     }
5737     return true;
5738 }
5739 
5740 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
5741 // from memory, and writes it to a register.  It can use offset, post-indexed, or pre-indexed addressing.
5742 bool
5743 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding)
5744 {
5745 #if 0
5746     if ConditionPassed() then
5747         EncodingSpecificOperations();
5748         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5749         address = if index then offset_addr else R[n];
5750         data = MemU[address,4];
5751         if wback then R[n] = offset_addr;
5752         if t == 15 then
5753             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5754         elsif UnalignedSupport() || address<1:0> = '00' then
5755             R[t] = data;
5756         else // Can only apply before ARMv7
5757             R[t] = ROR(data, 8*UInt(address<1:0>));
5758 #endif
5759 
5760     bool success = false;
5761 
5762     if (ConditionPassed(opcode))
5763     {
5764         const uint32_t addr_byte_size = GetAddressByteSize();
5765 
5766         uint32_t t;
5767         uint32_t n;
5768         uint32_t imm32;
5769         bool index;
5770         bool add;
5771         bool wback;
5772 
5773         switch (encoding)
5774         {
5775             case eEncodingA1:
5776                 // if Rn == '1111' then SEE LDR (literal);
5777                 // if P == '0' && W == '1' then SEE LDRT;
5778                 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP;
5779                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5780                 t = Bits32 (opcode, 15, 12);
5781                 n = Bits32 (opcode, 19, 16);
5782                 imm32 = Bits32 (opcode, 11, 0);
5783 
5784                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5785                 index = BitIsSet (opcode, 24);
5786                 add = BitIsSet (opcode, 23);
5787                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5788 
5789                 // if wback && n == t then UNPREDICTABLE;
5790                 if (wback && (n == t))
5791                     return false;
5792 
5793                 break;
5794 
5795             default:
5796                 return false;
5797         }
5798 
5799         addr_t address;
5800         addr_t offset_addr;
5801         addr_t base_address = ReadCoreReg (n, &success);
5802         if (!success)
5803             return false;
5804 
5805         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5806         if (add)
5807             offset_addr = base_address + imm32;
5808         else
5809             offset_addr = base_address - imm32;
5810 
5811         // address = if index then offset_addr else R[n];
5812         if (index)
5813             address = offset_addr;
5814         else
5815             address = base_address;
5816 
5817         // data = MemU[address,4];
5818 
5819         RegisterInfo base_reg;
5820         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5821 
5822         EmulateInstruction::Context context;
5823         context.type = eContextRegisterLoad;
5824         context.SetRegisterPlusOffset (base_reg, address - base_address);
5825 
5826         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5827         if (!success)
5828             return false;
5829 
5830         // if wback then R[n] = offset_addr;
5831         if (wback)
5832         {
5833             context.type = eContextAdjustBaseRegister;
5834             context.SetAddress (offset_addr);
5835             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5836                 return false;
5837         }
5838 
5839         // if t == 15 then
5840         if (t == 15)
5841         {
5842             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5843             if (BitIsClear (address, 1) && BitIsClear (address, 0))
5844             {
5845                 // LoadWritePC (data);
5846                 context.type = eContextRegisterLoad;
5847                 context.SetRegisterPlusOffset (base_reg, address - base_address);
5848                 LoadWritePC (context, data);
5849             }
5850             else
5851                   return false;
5852         }
5853         // elsif UnalignedSupport() || address<1:0> = '00' then
5854         else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5855         {
5856             // R[t] = data;
5857             context.type = eContextRegisterLoad;
5858             context.SetRegisterPlusOffset (base_reg, address - base_address);
5859             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5860                 return false;
5861         }
5862         // else // Can only apply before ARMv7
5863         else
5864         {
5865             // R[t] = ROR(data, 8*UInt(address<1:0>));
5866             data = ROR (data, Bits32 (address, 1, 0), &success);
5867             if (!success)
5868                 return false;
5869             context.type = eContextRegisterLoad;
5870             context.SetImmediate (data);
5871             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5872                 return false;
5873         }
5874 
5875     }
5876     return true;
5877 }
5878 
5879 // LDR (register) calculates an address from a base register value and an offset register value, loads a word
5880 // from memory, and writes it to a resgister.  The offset register value can optionally be shifted.
5881 bool
5882 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding)
5883 {
5884 #if 0
5885     if ConditionPassed() then
5886         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5887         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5888         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5889         address = if index then offset_addr else R[n];
5890         data = MemU[address,4];
5891         if wback then R[n] = offset_addr;
5892         if t == 15 then
5893             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5894         elsif UnalignedSupport() || address<1:0> = '00' then
5895             R[t] = data;
5896         else // Can only apply before ARMv7
5897             if CurrentInstrSet() == InstrSet_ARM then
5898                 R[t] = ROR(data, 8*UInt(address<1:0>));
5899             else
5900                 R[t] = bits(32) UNKNOWN;
5901 #endif
5902 
5903     bool success = false;
5904 
5905     if (ConditionPassed(opcode))
5906     {
5907         const uint32_t addr_byte_size = GetAddressByteSize();
5908 
5909         uint32_t t;
5910         uint32_t n;
5911         uint32_t m;
5912         bool index;
5913         bool add;
5914         bool wback;
5915         ARM_ShifterType shift_t;
5916         uint32_t shift_n;
5917 
5918         switch (encoding)
5919         {
5920             case eEncodingT1:
5921                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5922                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5923                 t = Bits32 (opcode, 2, 0);
5924                 n = Bits32 (opcode, 5, 3);
5925                 m = Bits32 (opcode, 8, 6);
5926 
5927                 // index = TRUE; add = TRUE; wback = FALSE;
5928                 index = true;
5929                 add = true;
5930                 wback = false;
5931 
5932                 // (shift_t, shift_n) = (SRType_LSL, 0);
5933                 shift_t = SRType_LSL;
5934                 shift_n = 0;
5935 
5936                 break;
5937 
5938             case eEncodingT2:
5939                 // if Rn == '1111' then SEE LDR (literal);
5940                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5941                 t = Bits32 (opcode, 15, 12);
5942                 n = Bits32 (opcode, 19, 16);
5943                 m = Bits32 (opcode, 3, 0);
5944 
5945                 // index = TRUE; add = TRUE; wback = FALSE;
5946                 index = true;
5947                 add = true;
5948                 wback = false;
5949 
5950                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5951                 shift_t = SRType_LSL;
5952                 shift_n = Bits32 (opcode, 5, 4);
5953 
5954                 // if BadReg(m) then UNPREDICTABLE;
5955                 if (BadReg (m))
5956                     return false;
5957 
5958                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
5959                 if ((t == 15) && InITBlock() && !LastInITBlock())
5960                     return false;
5961 
5962                 break;
5963 
5964             case eEncodingA1:
5965             {
5966                 // if P == '0' && W == '1' then SEE LDRT;
5967                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5968                 t = Bits32 (opcode, 15, 12);
5969                 n = Bits32 (opcode, 19, 16);
5970                 m = Bits32 (opcode, 3, 0);
5971 
5972                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5973                 index = BitIsSet (opcode, 24);
5974                 add = BitIsSet (opcode, 23);
5975                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5976 
5977                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
5978                 uint32_t type = Bits32 (opcode, 6, 5);
5979                 uint32_t imm5 = Bits32 (opcode, 11, 7);
5980                 shift_n = DecodeImmShift (type, imm5, shift_t);
5981 
5982                 // if m == 15 then UNPREDICTABLE;
5983                 if (m == 15)
5984                     return false;
5985 
5986                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5987                 if (wback && ((n == 15) || (n == t)))
5988                     return false;
5989             }
5990                 break;
5991 
5992 
5993             default:
5994                 return false;
5995         }
5996 
5997         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
5998         if (!success)
5999             return false;
6000 
6001         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6002         if (!success)
6003             return false;
6004 
6005         addr_t offset_addr;
6006         addr_t address;
6007 
6008         // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an application level alias for the CPSR".
6009         addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success);
6010         if (!success)
6011             return false;
6012 
6013         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6014         if (add)
6015             offset_addr = Rn + offset;
6016         else
6017             offset_addr = Rn - offset;
6018 
6019         // address = if index then offset_addr else R[n];
6020             if (index)
6021                 address = offset_addr;
6022             else
6023                 address = Rn;
6024 
6025         // data = MemU[address,4];
6026         RegisterInfo base_reg;
6027         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6028 
6029         EmulateInstruction::Context context;
6030         context.type = eContextRegisterLoad;
6031         context.SetRegisterPlusOffset (base_reg, address - Rn);
6032 
6033         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
6034         if (!success)
6035             return false;
6036 
6037         // if wback then R[n] = offset_addr;
6038         if (wback)
6039         {
6040             context.type = eContextAdjustBaseRegister;
6041             context.SetAddress (offset_addr);
6042             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6043                 return false;
6044         }
6045 
6046         // if t == 15 then
6047         if (t == 15)
6048         {
6049             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6050             if (BitIsClear (address, 1) && BitIsClear (address, 0))
6051             {
6052                 context.type = eContextRegisterLoad;
6053                 context.SetRegisterPlusOffset (base_reg, address - Rn);
6054                 LoadWritePC (context, data);
6055             }
6056             else
6057                 return false;
6058         }
6059         // elsif UnalignedSupport() || address<1:0> = '00' then
6060         else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
6061         {
6062             // R[t] = data;
6063             context.type = eContextRegisterLoad;
6064             context.SetRegisterPlusOffset (base_reg, address - Rn);
6065             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6066                 return false;
6067         }
6068         else // Can only apply before ARMv7
6069         {
6070             // if CurrentInstrSet() == InstrSet_ARM then
6071             if (CurrentInstrSet () == eModeARM)
6072             {
6073                 // R[t] = ROR(data, 8*UInt(address<1:0>));
6074                 data = ROR (data, Bits32 (address, 1, 0), &success);
6075                 if (!success)
6076                     return false;
6077                 context.type = eContextRegisterLoad;
6078                 context.SetImmediate (data);
6079                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6080                     return false;
6081             }
6082             else
6083             {
6084                 // R[t] = bits(32) UNKNOWN;
6085                 WriteBits32Unknown (t);
6086             }
6087         }
6088     }
6089     return true;
6090 }
6091 
6092 // LDRB (immediate, Thumb)
6093 bool
6094 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6095 {
6096 #if 0
6097     if ConditionPassed() then
6098         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6099         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6100         address = if index then offset_addr else R[n];
6101         R[t] = ZeroExtend(MemU[address,1], 32);
6102         if wback then R[n] = offset_addr;
6103 #endif
6104 
6105     bool success = false;
6106 
6107     if (ConditionPassed(opcode))
6108     {
6109         uint32_t t;
6110         uint32_t n;
6111         uint32_t imm32;
6112         bool index;
6113         bool add;
6114         bool wback;
6115 
6116         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6117         switch (encoding)
6118         {
6119             case eEncodingT1:
6120                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6121                 t = Bits32 (opcode, 2, 0);
6122                 n = Bits32 (opcode, 5, 3);
6123                 imm32 = Bits32 (opcode, 10, 6);
6124 
6125                 // index = TRUE; add = TRUE; wback = FALSE;
6126                 index = true;
6127                 add = true;
6128                 wback= false;
6129 
6130                 break;
6131 
6132             case eEncodingT2:
6133                 // if Rt == '1111' then SEE PLD;
6134                 // if Rn == '1111' then SEE LDRB (literal);
6135                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6136                 t = Bits32 (opcode, 15, 12);
6137                 n = Bits32 (opcode, 19, 16);
6138                 imm32 = Bits32 (opcode, 11, 0);
6139 
6140                 // index = TRUE; add = TRUE; wback = FALSE;
6141                 index = true;
6142                 add = true;
6143                 wback = false;
6144 
6145                 // if t == 13 then UNPREDICTABLE;
6146                 if (t == 13)
6147                     return false;
6148 
6149                 break;
6150 
6151             case eEncodingT3:
6152                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6153                 // if Rn == '1111' then SEE LDRB (literal);
6154                 // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6155                 // if P == '0' && W == '0' then UNDEFINED;
6156                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6157                     return false;
6158 
6159                   // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6160                 t = Bits32 (opcode, 15, 12);
6161                 n = Bits32 (opcode, 19, 16);
6162                 imm32 = Bits32 (opcode, 7, 0);
6163 
6164                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6165                 index = BitIsSet (opcode, 10);
6166                 add = BitIsSet (opcode, 9);
6167                 wback = BitIsSet (opcode, 8);
6168 
6169                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6170                 if (BadReg (t) || (wback && (n == t)))
6171                     return false;
6172 
6173                 break;
6174 
6175             default:
6176                 return false;
6177         }
6178 
6179         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6180         if (!success)
6181             return false;
6182 
6183         addr_t address;
6184         addr_t offset_addr;
6185 
6186         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6187         if (add)
6188             offset_addr = Rn + imm32;
6189         else
6190             offset_addr = Rn - imm32;
6191 
6192         // address = if index then offset_addr else R[n];
6193         if (index)
6194             address = offset_addr;
6195         else
6196             address = Rn;
6197 
6198         // R[t] = ZeroExtend(MemU[address,1], 32);
6199         RegisterInfo base_reg;
6200         RegisterInfo data_reg;
6201         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6202         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6203 
6204         EmulateInstruction::Context context;
6205         context.type = eContextRegisterLoad;
6206         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
6207 
6208         uint64_t data = MemURead (context, address, 1, 0, &success);
6209         if (!success)
6210             return false;
6211 
6212         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6213             return false;
6214 
6215         // if wback then R[n] = offset_addr;
6216         if (wback)
6217         {
6218             context.type = eContextAdjustBaseRegister;
6219             context.SetAddress (offset_addr);
6220             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6221                 return false;
6222         }
6223     }
6224     return true;
6225 }
6226 
6227 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6228 // zero-extends it to form a 32-bit word and writes it to a register.
6229 bool
6230 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6231 {
6232 #if 0
6233     if ConditionPassed() then
6234         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6235         base = Align(PC,4);
6236         address = if add then (base + imm32) else (base - imm32);
6237         R[t] = ZeroExtend(MemU[address,1], 32);
6238 #endif
6239 
6240     bool success = false;
6241 
6242     if (ConditionPassed(opcode))
6243     {
6244         uint32_t t;
6245         uint32_t imm32;
6246         bool add;
6247         switch (encoding)
6248         {
6249             case eEncodingT1:
6250                 // if Rt == '1111' then SEE PLD;
6251                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6252                 t = Bits32 (opcode, 15, 12);
6253                 imm32 = Bits32 (opcode, 11, 0);
6254                 add = BitIsSet (opcode, 23);
6255 
6256                 // if t == 13 then UNPREDICTABLE;
6257                 if (t == 13)
6258                     return false;
6259 
6260                 break;
6261 
6262             case eEncodingA1:
6263                 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6264                 t = Bits32 (opcode, 15, 12);
6265                 imm32 = Bits32 (opcode, 11, 0);
6266                 add = BitIsSet (opcode, 23);
6267 
6268                 // if t == 15 then UNPREDICTABLE;
6269                 if (t == 15)
6270                     return false;
6271                 break;
6272 
6273             default:
6274                 return false;
6275         }
6276 
6277         // base = Align(PC,4);
6278         uint32_t pc_val = ReadCoreReg (PC_REG, &success);
6279         if (!success)
6280             return false;
6281 
6282         uint32_t base = AlignPC (pc_val);
6283 
6284         addr_t address;
6285         // address = if add then (base + imm32) else (base - imm32);
6286         if (add)
6287             address = base + imm32;
6288         else
6289             address = base - imm32;
6290 
6291         // R[t] = ZeroExtend(MemU[address,1], 32);
6292         EmulateInstruction::Context context;
6293         context.type = eContextRelativeBranchImmediate;
6294         context.SetImmediate (address - base);
6295 
6296         uint64_t data = MemURead (context, address, 1, 0, &success);
6297         if (!success)
6298             return false;
6299 
6300         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6301             return false;
6302     }
6303     return true;
6304 }
6305 
6306 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from
6307 // memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6308 // optionally be shifted.
6309 bool
6310 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding)
6311 {
6312 #if 0
6313     if ConditionPassed() then
6314         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6315         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6316         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6317         address = if index then offset_addr else R[n];
6318         R[t] = ZeroExtend(MemU[address,1],32);
6319         if wback then R[n] = offset_addr;
6320 #endif
6321 
6322     bool success = false;
6323 
6324     if (ConditionPassed(opcode))
6325     {
6326         uint32_t t;
6327         uint32_t n;
6328         uint32_t m;
6329         bool index;
6330         bool add;
6331         bool wback;
6332         ARM_ShifterType shift_t;
6333         uint32_t shift_n;
6334 
6335         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6336         switch (encoding)
6337         {
6338             case eEncodingT1:
6339                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6340                 t = Bits32 (opcode, 2, 0);
6341                 n = Bits32 (opcode, 5, 3);
6342                 m = Bits32 (opcode, 8, 6);
6343 
6344                 // index = TRUE; add = TRUE; wback = FALSE;
6345                 index = true;
6346                 add = true;
6347                 wback = false;
6348 
6349                 // (shift_t, shift_n) = (SRType_LSL, 0);
6350                 shift_t = SRType_LSL;
6351                 shift_n = 0;
6352                 break;
6353 
6354             case eEncodingT2:
6355                 // if Rt == '1111' then SEE PLD;
6356                 // if Rn == '1111' then SEE LDRB (literal);
6357                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6358                 t = Bits32 (opcode, 15, 12);
6359                 n = Bits32 (opcode, 19, 16);
6360                 m = Bits32 (opcode, 3, 0);
6361 
6362                 // index = TRUE; add = TRUE; wback = FALSE;
6363                 index = true;
6364                 add = true;
6365                 wback = false;
6366 
6367                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6368                 shift_t = SRType_LSL;
6369                 shift_n = Bits32 (opcode, 5, 4);
6370 
6371                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6372                 if ((t == 13) || BadReg (m))
6373                     return false;
6374                 break;
6375 
6376             case eEncodingA1:
6377             {
6378                 // if P == '0' && W == '1' then SEE LDRBT;
6379                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6380                 t = Bits32 (opcode, 15, 12);
6381                 n = Bits32 (opcode, 19, 16);
6382                 m = Bits32 (opcode, 3, 0);
6383 
6384                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6385                 index = BitIsSet (opcode, 24);
6386                 add = BitIsSet (opcode, 23);
6387                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6388 
6389                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6390                 uint32_t type = Bits32 (opcode, 6, 5);
6391                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6392                 shift_n = DecodeImmShift (type, imm5, shift_t);
6393 
6394                 // if t == 15 || m == 15 then UNPREDICTABLE;
6395                 if ((t == 15) || (m == 15))
6396                     return false;
6397 
6398                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6399                 if (wback && ((n == 15) || (n == t)))
6400                     return false;
6401             }
6402                 break;
6403 
6404             default:
6405                 return false;
6406         }
6407 
6408         addr_t offset_addr;
6409         addr_t address;
6410 
6411         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6412         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6413         if (!success)
6414             return false;
6415 
6416         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6417         if (!success)
6418             return false;
6419 
6420         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6421         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6422         if (!success)
6423             return false;
6424 
6425         if (add)
6426             offset_addr = Rn + offset;
6427         else
6428             offset_addr = Rn - offset;
6429 
6430         // address = if index then offset_addr else R[n];
6431         if (index)
6432             address = offset_addr;
6433         else
6434             address = Rn;
6435 
6436         // R[t] = ZeroExtend(MemU[address,1],32);
6437         RegisterInfo base_reg;
6438         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6439 
6440         EmulateInstruction::Context context;
6441         context.type = eContextRegisterLoad;
6442         context.SetRegisterPlusOffset (base_reg, address - Rn);
6443 
6444         uint64_t data = MemURead (context, address, 1, 0, &success);
6445         if (!success)
6446             return false;
6447 
6448         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6449             return false;
6450 
6451         // if wback then R[n] = offset_addr;
6452         if (wback)
6453         {
6454             context.type = eContextAdjustBaseRegister;
6455             context.SetAddress (offset_addr);
6456             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6457                 return false;
6458         }
6459     }
6460     return true;
6461 }
6462 
6463 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a
6464 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register.  It can use offset,
6465 // post-indexed, or pre-indexed addressing.
6466 bool
6467 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding)
6468 {
6469 #if 0
6470     if ConditionPassed() then
6471         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6472         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6473         address = if index then offset_addr else R[n];
6474         data = MemU[address,2];
6475         if wback then R[n] = offset_addr;
6476         if UnalignedSupport() || address<0> = '0' then
6477             R[t] = ZeroExtend(data, 32);
6478         else // Can only apply before ARMv7
6479             R[t] = bits(32) UNKNOWN;
6480 #endif
6481 
6482 
6483     bool success = false;
6484 
6485     if (ConditionPassed(opcode))
6486     {
6487         uint32_t t;
6488         uint32_t n;
6489         uint32_t imm32;
6490         bool index;
6491         bool add;
6492         bool wback;
6493 
6494         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6495         switch (encoding)
6496         {
6497             case eEncodingT1:
6498                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
6499                 t = Bits32 (opcode, 2, 0);
6500                 n = Bits32 (opcode, 5, 3);
6501                 imm32 = Bits32 (opcode, 10, 6) << 1;
6502 
6503                 // index = TRUE; add = TRUE; wback = FALSE;
6504                 index = true;
6505                 add = true;
6506                 wback = false;
6507 
6508                 break;
6509 
6510             case eEncodingT2:
6511                 // if Rt == '1111' then SEE "Unallocated memory hints";
6512                 // if Rn == '1111' then SEE LDRH (literal);
6513                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6514                 t = Bits32 (opcode, 15, 12);
6515                 n = Bits32 (opcode, 19, 16);
6516                 imm32 = Bits32 (opcode, 11, 0);
6517 
6518                 // index = TRUE; add = TRUE; wback = FALSE;
6519                 index = true;
6520                 add = true;
6521                 wback = false;
6522 
6523                 // if t == 13 then UNPREDICTABLE;
6524                 if (t == 13)
6525                     return false;
6526                 break;
6527 
6528             case eEncodingT3:
6529                 // if Rn == '1111' then SEE LDRH (literal);
6530                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
6531                 // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
6532                 // if P == '0' && W == '0' then UNDEFINED;
6533                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6534                     return false;
6535 
6536                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6537                 t = Bits32 (opcode, 15, 12);
6538                 n = Bits32 (opcode, 19, 16);
6539                 imm32 = Bits32 (opcode, 7, 0);
6540 
6541                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6542                 index = BitIsSet (opcode, 10);
6543                 add = BitIsSet (opcode, 9);
6544                 wback = BitIsSet (opcode, 8);
6545 
6546                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6547                 if (BadReg (t) || (wback && (n == t)))
6548                     return false;
6549                 break;
6550 
6551             default:
6552                 return false;
6553         }
6554 
6555         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6556         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6557         if (!success)
6558             return false;
6559 
6560         addr_t offset_addr;
6561         addr_t address;
6562 
6563         if (add)
6564             offset_addr = Rn + imm32;
6565         else
6566             offset_addr = Rn - imm32;
6567 
6568         // address = if index then offset_addr else R[n];
6569         if (index)
6570             address = offset_addr;
6571         else
6572             address = Rn;
6573 
6574         // data = MemU[address,2];
6575         RegisterInfo base_reg;
6576         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6577 
6578         EmulateInstruction::Context context;
6579         context.type = eContextRegisterLoad;
6580         context.SetRegisterPlusOffset (base_reg, address - Rn);
6581 
6582         uint64_t data = MemURead (context, address, 2, 0, &success);
6583         if (!success)
6584             return false;
6585 
6586         // if wback then R[n] = offset_addr;
6587         if (wback)
6588         {
6589             context.type = eContextAdjustBaseRegister;
6590             context.SetAddress (offset_addr);
6591             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6592                 return false;
6593         }
6594 
6595         // if UnalignedSupport() || address<0> = '0' then
6596         if (UnalignedSupport () || BitIsClear (address, 0))
6597         {
6598             // R[t] = ZeroExtend(data, 32);
6599             context.type = eContextRegisterLoad;
6600             context.SetRegisterPlusOffset (base_reg, address - Rn);
6601             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6602                 return false;
6603         }
6604         else // Can only apply before ARMv7
6605         {
6606             // R[t] = bits(32) UNKNOWN;
6607             WriteBits32Unknown (t);
6608         }
6609     }
6610     return true;
6611 }
6612 
6613 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory,
6614 // zero-extends it to form a 32-bit word, and writes it to a register.
6615 bool
6616 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding)
6617 {
6618 #if 0
6619     if ConditionPassed() then
6620         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6621         base = Align(PC,4);
6622         address = if add then (base + imm32) else (base - imm32);
6623         data = MemU[address,2];
6624         if UnalignedSupport() || address<0> = '0' then
6625             R[t] = ZeroExtend(data, 32);
6626         else // Can only apply before ARMv7
6627             R[t] = bits(32) UNKNOWN;
6628 #endif
6629 
6630     bool success = false;
6631 
6632     if (ConditionPassed(opcode))
6633     {
6634         uint32_t t;
6635         uint32_t imm32;
6636         bool add;
6637 
6638         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6639         switch (encoding)
6640         {
6641             case eEncodingT1:
6642                 // if Rt == '1111' then SEE "Unallocated memory hints";
6643                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6644                 t = Bits32 (opcode, 15, 12);
6645                 imm32 = Bits32 (opcode, 11, 0);
6646                 add = BitIsSet (opcode, 23);
6647 
6648                 // if t == 13 then UNPREDICTABLE;
6649                 if (t == 13)
6650                     return false;
6651 
6652                 break;
6653 
6654             case eEncodingA1:
6655             {
6656                 uint32_t imm4H = Bits32 (opcode, 11, 8);
6657                 uint32_t imm4L = Bits32 (opcode, 3, 0);
6658 
6659                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6660                 t = Bits32 (opcode, 15, 12);
6661                 imm32 = (imm4H << 4) | imm4L;
6662                 add = BitIsSet (opcode, 23);
6663 
6664                 // if t == 15 then UNPREDICTABLE;
6665                 if (t == 15)
6666                     return false;
6667                 break;
6668             }
6669 
6670             default:
6671                 return false;
6672         }
6673 
6674         // base = Align(PC,4);
6675         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6676         if (!success)
6677             return false;
6678 
6679         addr_t base = AlignPC (pc_value);
6680         addr_t address;
6681 
6682         // address = if add then (base + imm32) else (base - imm32);
6683         if (add)
6684             address = base + imm32;
6685         else
6686             address = base - imm32;
6687 
6688         // data = MemU[address,2];
6689         RegisterInfo base_reg;
6690         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
6691 
6692         EmulateInstruction::Context context;
6693         context.type = eContextRegisterLoad;
6694         context.SetRegisterPlusOffset (base_reg, address - base);
6695 
6696         uint64_t data = MemURead (context, address, 2, 0, &success);
6697         if (!success)
6698             return false;
6699 
6700 
6701         // if UnalignedSupport() || address<0> = '0' then
6702         if (UnalignedSupport () || BitIsClear (address, 0))
6703         {
6704             // R[t] = ZeroExtend(data, 32);
6705             context.type = eContextRegisterLoad;
6706             context.SetRegisterPlusOffset (base_reg, address - base);
6707             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6708                 return false;
6709 
6710         }
6711         else // Can only apply before ARMv7
6712         {
6713             // R[t] = bits(32) UNKNOWN;
6714             WriteBits32Unknown (t);
6715         }
6716     }
6717     return true;
6718 }
6719 
6720 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword
6721 // from memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6722 // be shifted left by 0, 1, 2, or 3 bits.
6723 bool
6724 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding)
6725 {
6726 #if 0
6727     if ConditionPassed() then
6728         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6729         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6730         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6731         address = if index then offset_addr else R[n];
6732         data = MemU[address,2];
6733         if wback then R[n] = offset_addr;
6734         if UnalignedSupport() || address<0> = '0' then
6735             R[t] = ZeroExtend(data, 32);
6736         else // Can only apply before ARMv7
6737             R[t] = bits(32) UNKNOWN;
6738 #endif
6739 
6740     bool success = false;
6741 
6742     if (ConditionPassed(opcode))
6743     {
6744         uint32_t t;
6745         uint32_t n;
6746         uint32_t m;
6747         bool index;
6748         bool add;
6749         bool wback;
6750         ARM_ShifterType shift_t;
6751         uint32_t shift_n;
6752 
6753         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6754         switch (encoding)
6755         {
6756             case eEncodingT1:
6757                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6758                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6759                 t = Bits32 (opcode, 2, 0);
6760                 n = Bits32 (opcode, 5, 3);
6761                 m = Bits32 (opcode, 8, 6);
6762 
6763                 // index = TRUE; add = TRUE; wback = FALSE;
6764                 index = true;
6765                 add = true;
6766                 wback = false;
6767 
6768                 // (shift_t, shift_n) = (SRType_LSL, 0);
6769                 shift_t = SRType_LSL;
6770                 shift_n = 0;
6771 
6772                 break;
6773 
6774             case eEncodingT2:
6775                 // if Rn == '1111' then SEE LDRH (literal);
6776                 // if Rt == '1111' then SEE "Unallocated memory hints";
6777                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6778                 t = Bits32 (opcode, 15, 12);
6779                 n = Bits32 (opcode, 19, 16);
6780                 m = Bits32 (opcode, 3, 0);
6781 
6782                 // index = TRUE; add = TRUE; wback = FALSE;
6783                 index = true;
6784                 add = true;
6785                 wback = false;
6786 
6787                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6788                 shift_t = SRType_LSL;
6789                 shift_n = Bits32 (opcode, 5, 4);
6790 
6791                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6792                 if ((t == 13) || BadReg (m))
6793                     return false;
6794                 break;
6795 
6796             case eEncodingA1:
6797                 // if P == '0' && W == '1' then SEE LDRHT;
6798                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6799                 t = Bits32 (opcode, 15, 12);
6800                 n = Bits32 (opcode, 19, 16);
6801                 m = Bits32 (opcode, 3, 0);
6802 
6803                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6804                 index = BitIsSet (opcode, 24);
6805                 add = BitIsSet (opcode, 23);
6806                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6807 
6808                 // (shift_t, shift_n) = (SRType_LSL, 0);
6809                 shift_t = SRType_LSL;
6810                 shift_n = 0;
6811 
6812                 // if t == 15 || m == 15 then UNPREDICTABLE;
6813                 if ((t == 15) || (m == 15))
6814                     return false;
6815 
6816                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6817                 if (wback && ((n == 15) || (n == t)))
6818                     return false;
6819 
6820                 break;
6821 
6822             default:
6823                 return false;
6824         }
6825 
6826         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6827 
6828         uint64_t Rm  = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6829         if (!success)
6830             return false;
6831 
6832         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6833         if (!success)
6834             return false;
6835 
6836         addr_t offset_addr;
6837         addr_t address;
6838 
6839         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6840         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6841         if (!success)
6842             return false;
6843 
6844         if (add)
6845             offset_addr = Rn + offset;
6846         else
6847             offset_addr = Rn - offset;
6848 
6849         // address = if index then offset_addr else R[n];
6850         if (index)
6851             address = offset_addr;
6852         else
6853             address = Rn;
6854 
6855         // data = MemU[address,2];
6856         RegisterInfo base_reg;
6857         RegisterInfo offset_reg;
6858         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6859         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
6860 
6861         EmulateInstruction::Context context;
6862         context.type = eContextRegisterLoad;
6863         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6864         uint64_t data = MemURead (context, address, 2, 0, &success);
6865         if (!success)
6866             return false;
6867 
6868         // if wback then R[n] = offset_addr;
6869         if (wback)
6870         {
6871             context.type = eContextAdjustBaseRegister;
6872             context.SetAddress (offset_addr);
6873             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6874                 return false;
6875         }
6876 
6877         // if UnalignedSupport() || address<0> = '0' then
6878         if (UnalignedSupport() || BitIsClear (address, 0))
6879         {
6880             // R[t] = ZeroExtend(data, 32);
6881             context.type = eContextRegisterLoad;
6882             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6883             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6884                 return false;
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 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from
6896 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed,
6897 // or pre-indexed addressing.
6898 bool
6899 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6900 {
6901 #if 0
6902     if ConditionPassed() then
6903         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6904         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6905         address = if index then offset_addr else R[n];
6906         R[t] = SignExtend(MemU[address,1], 32);
6907         if wback then R[n] = offset_addr;
6908 #endif
6909 
6910     bool success = false;
6911 
6912     if (ConditionPassed(opcode))
6913     {
6914         uint32_t t;
6915         uint32_t n;
6916         uint32_t imm32;
6917         bool index;
6918         bool add;
6919         bool wback;
6920 
6921         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6922         switch (encoding)
6923         {
6924             case eEncodingT1:
6925                 // if Rt == '1111' then SEE PLI;
6926                 // if Rn == '1111' then SEE LDRSB (literal);
6927                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6928                 t = Bits32 (opcode, 15, 12);
6929                 n = Bits32 (opcode, 19, 16);
6930                 imm32 = Bits32 (opcode, 11, 0);
6931 
6932                 // index = TRUE; add = TRUE; wback = FALSE;
6933                 index = true;
6934                 add = true;
6935                 wback = false;
6936 
6937                 // if t == 13 then UNPREDICTABLE;
6938                 if (t == 13)
6939                     return false;
6940 
6941                 break;
6942 
6943             case eEncodingT2:
6944                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
6945                 // if Rn == '1111' then SEE LDRSB (literal);
6946                 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
6947                 // if P == '0' && W == '0' then UNDEFINED;
6948                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6949                     return false;
6950 
6951                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6952                 t = Bits32 (opcode, 15, 12);
6953                 n = Bits32 (opcode, 19, 16);
6954                 imm32 = Bits32 (opcode, 7, 0);
6955 
6956                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6957                 index = BitIsSet (opcode, 10);
6958                 add = BitIsSet (opcode, 9);
6959                 wback = BitIsSet (opcode, 8);
6960 
6961                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6962                   if (((t == 13) || ((t == 15)
6963                                      && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8))))
6964                       || (wback && (n == t)))
6965                     return false;
6966 
6967                 break;
6968 
6969             case eEncodingA1:
6970             {
6971                 // if Rn == '1111' then SEE LDRSB (literal);
6972                 // if P == '0' && W == '1' then SEE LDRSBT;
6973                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
6974                 t = Bits32 (opcode, 15, 12);
6975                 n = Bits32 (opcode, 19, 16);
6976 
6977                 uint32_t imm4H = Bits32 (opcode, 11, 8);
6978                 uint32_t imm4L = Bits32 (opcode, 3, 0);
6979                 imm32 = (imm4H << 4) | imm4L;
6980 
6981                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6982                 index = BitIsSet (opcode, 24);
6983                 add = BitIsSet (opcode, 23);
6984                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6985 
6986                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
6987                 if ((t == 15) || (wback && (n == t)))
6988                     return false;
6989 
6990                 break;
6991             }
6992 
6993             default:
6994                 return false;
6995         }
6996 
6997         uint64_t Rn = ReadCoreReg (n, &success);
6998         if (!success)
6999             return false;
7000 
7001         addr_t offset_addr;
7002         addr_t address;
7003 
7004         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7005         if (add)
7006             offset_addr = Rn + imm32;
7007         else
7008             offset_addr = Rn - imm32;
7009 
7010         // address = if index then offset_addr else R[n];
7011         if (index)
7012             address = offset_addr;
7013         else
7014             address = Rn;
7015 
7016         // R[t] = SignExtend(MemU[address,1], 32);
7017         RegisterInfo base_reg;
7018         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7019 
7020         EmulateInstruction::Context context;
7021         context.type = eContextRegisterLoad;
7022         context.SetRegisterPlusOffset (base_reg, address - Rn);
7023 
7024         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7025         if (!success)
7026             return false;
7027 
7028         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7029         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7030             return false;
7031 
7032         // if wback then R[n] = offset_addr;
7033         if (wback)
7034         {
7035             context.type = eContextAdjustBaseRegister;
7036             context.SetAddress (offset_addr);
7037             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7038                 return false;
7039         }
7040     }
7041 
7042     return true;
7043 }
7044 
7045 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
7046 // sign-extends it to form a 32-bit word, and writes tit to a register.
7047 bool
7048 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding)
7049 {
7050 #if 0
7051     if ConditionPassed() then
7052         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7053         base = Align(PC,4);
7054         address = if add then (base + imm32) else (base - imm32);
7055         R[t] = SignExtend(MemU[address,1], 32);
7056 #endif
7057 
7058     bool success = false;
7059 
7060     if (ConditionPassed(opcode))
7061     {
7062         uint32_t t;
7063         uint32_t imm32;
7064         bool add;
7065 
7066         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7067         switch (encoding)
7068         {
7069             case eEncodingT1:
7070                 // if Rt == '1111' then SEE PLI;
7071                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7072                 t = Bits32 (opcode, 15, 12);
7073                 imm32 = Bits32 (opcode, 11, 0);
7074                 add = BitIsSet (opcode, 23);
7075 
7076                 // if t == 13 then UNPREDICTABLE;
7077                 if (t == 13)
7078                     return false;
7079 
7080                 break;
7081 
7082             case eEncodingA1:
7083             {
7084                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7085                 t = Bits32 (opcode, 15, 12);
7086                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7087                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7088                 imm32 = (imm4H << 4) | imm4L;
7089                 add = BitIsSet (opcode, 23);
7090 
7091                 // if t == 15 then UNPREDICTABLE;
7092                 if (t == 15)
7093                     return false;
7094 
7095                 break;
7096             }
7097 
7098             default:
7099                 return false;
7100         }
7101 
7102         // base = Align(PC,4);
7103         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7104         if (!success)
7105             return false;
7106         uint64_t base = AlignPC (pc_value);
7107 
7108         // address = if add then (base + imm32) else (base - imm32);
7109         addr_t address;
7110         if (add)
7111             address = base + imm32;
7112         else
7113             address = base - imm32;
7114 
7115         // R[t] = SignExtend(MemU[address,1], 32);
7116         RegisterInfo base_reg;
7117         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7118 
7119         EmulateInstruction::Context context;
7120         context.type = eContextRegisterLoad;
7121         context.SetRegisterPlusOffset (base_reg, address - base);
7122 
7123         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7124         if (!success)
7125             return false;
7126 
7127         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7128         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7129             return false;
7130     }
7131     return true;
7132 }
7133 
7134 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from
7135 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7136 // shifted left by 0, 1, 2, or 3 bits.
7137 bool
7138 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding)
7139 {
7140 #if 0
7141     if ConditionPassed() then
7142         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7143         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7144         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7145         address = if index then offset_addr else R[n];
7146         R[t] = SignExtend(MemU[address,1], 32);
7147         if wback then R[n] = offset_addr;
7148 #endif
7149 
7150     bool success = false;
7151 
7152     if (ConditionPassed(opcode))
7153     {
7154         uint32_t t;
7155         uint32_t n;
7156         uint32_t m;
7157         bool index;
7158         bool add;
7159         bool wback;
7160         ARM_ShifterType shift_t;
7161         uint32_t shift_n;
7162 
7163         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7164         switch (encoding)
7165         {
7166             case eEncodingT1:
7167                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7168                 t = Bits32 (opcode, 2, 0);
7169                 n = Bits32 (opcode, 5, 3);
7170                 m = Bits32 (opcode, 8, 6);
7171 
7172                 // index = TRUE; add = TRUE; wback = FALSE;
7173                 index = true;
7174                 add = true;
7175                 wback = false;
7176 
7177                 // (shift_t, shift_n) = (SRType_LSL, 0);
7178                 shift_t = SRType_LSL;
7179                 shift_n = 0;
7180 
7181                 break;
7182 
7183             case eEncodingT2:
7184                 // if Rt == '1111' then SEE PLI;
7185                 // if Rn == '1111' then SEE LDRSB (literal);
7186                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7187                 t = Bits32 (opcode, 15, 12);
7188                 n = Bits32 (opcode, 19, 16);
7189                 m = Bits32 (opcode, 3, 0);
7190 
7191                 // index = TRUE; add = TRUE; wback = FALSE;
7192                 index = true;
7193                 add = true;
7194                 wback = false;
7195 
7196                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7197                 shift_t = SRType_LSL;
7198                 shift_n = Bits32 (opcode, 5, 4);
7199 
7200                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7201                 if ((t == 13) || BadReg (m))
7202                     return false;
7203                 break;
7204 
7205             case eEncodingA1:
7206                 // if P == '0' && W == '1' then SEE LDRSBT;
7207                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7208                 t = Bits32 (opcode, 15, 12);
7209                 n = Bits32 (opcode, 19, 16);
7210                 m = Bits32 (opcode, 3, 0);
7211 
7212                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7213                 index = BitIsSet (opcode, 24);
7214                 add = BitIsSet (opcode, 23);
7215                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7216 
7217                 // (shift_t, shift_n) = (SRType_LSL, 0);
7218                 shift_t = SRType_LSL;
7219                 shift_n = 0;
7220 
7221                 // if t == 15 || m == 15 then UNPREDICTABLE;
7222                 if ((t == 15) || (m == 15))
7223                     return false;
7224 
7225                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7226                 if (wback && ((n == 15) || (n == t)))
7227                     return false;
7228                 break;
7229 
7230             default:
7231                 return false;
7232         }
7233 
7234         uint64_t Rm =  ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7235         if (!success)
7236             return false;
7237 
7238         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7239         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7240         if (!success)
7241             return false;
7242 
7243         addr_t offset_addr;
7244         addr_t address;
7245 
7246         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7247         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7248         if (!success)
7249             return false;
7250 
7251         if (add)
7252             offset_addr = Rn + offset;
7253         else
7254             offset_addr = Rn - offset;
7255 
7256         // address = if index then offset_addr else R[n];
7257         if (index)
7258             address = offset_addr;
7259         else
7260             address = Rn;
7261 
7262         // R[t] = SignExtend(MemU[address,1], 32);
7263         RegisterInfo base_reg;
7264         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7265         RegisterInfo offset_reg;
7266         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7267 
7268         EmulateInstruction::Context context;
7269         context.type = eContextRegisterLoad;
7270         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7271 
7272         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7273         if (!success)
7274             return false;
7275 
7276         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7277         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7278             return false;
7279 
7280         // if wback then R[n] = offset_addr;
7281         if (wback)
7282         {
7283             context.type = eContextAdjustBaseRegister;
7284             context.SetAddress (offset_addr);
7285             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7286                 return false;
7287         }
7288     }
7289     return true;
7290 }
7291 
7292 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from
7293 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed, or
7294 // pre-indexed addressing.
7295 bool
7296 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding)
7297 {
7298 #if 0
7299     if ConditionPassed() then
7300         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7301         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7302         address = if index then offset_addr else R[n];
7303         data = MemU[address,2];
7304         if wback then R[n] = offset_addr;
7305         if UnalignedSupport() || address<0> = '0' then
7306             R[t] = SignExtend(data, 32);
7307         else // Can only apply before ARMv7
7308             R[t] = bits(32) UNKNOWN;
7309 #endif
7310 
7311     bool success = false;
7312 
7313     if (ConditionPassed(opcode))
7314     {
7315         uint32_t t;
7316         uint32_t n;
7317         uint32_t imm32;
7318         bool index;
7319         bool add;
7320         bool wback;
7321 
7322         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7323         switch (encoding)
7324         {
7325             case eEncodingT1:
7326                 // if Rn == '1111' then SEE LDRSH (literal);
7327                 // if Rt == '1111' then SEE "Unallocated memory hints";
7328                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7329                 t = Bits32 (opcode, 15, 12);
7330                 n = Bits32 (opcode, 19, 16);
7331                 imm32 = Bits32 (opcode, 11, 0);
7332 
7333                 // index = TRUE; add = TRUE; wback = FALSE;
7334                 index = true;
7335                 add = true;
7336                 wback = false;
7337 
7338                 // if t == 13 then UNPREDICTABLE;
7339                 if (t == 13)
7340                     return false;
7341 
7342                 break;
7343 
7344             case eEncodingT2:
7345                 // if Rn == '1111' then SEE LDRSH (literal);
7346                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
7347                 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7348                 // if P == '0' && W == '0' then UNDEFINED;
7349                   if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7350                   return false;
7351 
7352                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7353                 t = Bits32 (opcode, 15, 12);
7354                 n = Bits32 (opcode, 19, 16);
7355                 imm32 = Bits32 (opcode, 7, 0);
7356 
7357                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7358                 index = BitIsSet (opcode, 10);
7359                 add = BitIsSet (opcode, 9);
7360                 wback = BitIsSet (opcode, 8);
7361 
7362                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7363                 if (BadReg (t) || (wback && (n == t)))
7364                     return false;
7365 
7366                 break;
7367 
7368             case eEncodingA1:
7369             {
7370                 // if Rn == '1111' then SEE LDRSH (literal);
7371                 // if P == '0' && W == '1' then SEE LDRSHT;
7372                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7373                 t = Bits32 (opcode, 15, 12);
7374                 n = Bits32 (opcode, 19, 16);
7375                 uint32_t imm4H = Bits32 (opcode, 11,8);
7376                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7377                 imm32 = (imm4H << 4) | imm4L;
7378 
7379                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7380                 index = BitIsSet (opcode, 24);
7381                 add = BitIsSet (opcode, 23);
7382                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7383 
7384                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7385                 if ((t == 15) || (wback && (n == t)))
7386                     return false;
7387 
7388                 break;
7389             }
7390 
7391             default:
7392                 return false;
7393         }
7394 
7395         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7396         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7397         if (!success)
7398             return false;
7399 
7400         addr_t offset_addr;
7401         if (add)
7402             offset_addr = Rn + imm32;
7403         else
7404             offset_addr = Rn - imm32;
7405 
7406         // address = if index then offset_addr else R[n];
7407         addr_t address;
7408         if (index)
7409             address = offset_addr;
7410         else
7411             address = Rn;
7412 
7413         // data = MemU[address,2];
7414         RegisterInfo base_reg;
7415         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7416 
7417         EmulateInstruction::Context context;
7418         context.type = eContextRegisterLoad;
7419         context.SetRegisterPlusOffset (base_reg, address - Rn);
7420 
7421         uint64_t data = MemURead (context, address, 2, 0, &success);
7422         if (!success)
7423             return false;
7424 
7425         // if wback then R[n] = offset_addr;
7426         if (wback)
7427         {
7428             context.type = eContextAdjustBaseRegister;
7429             context.SetAddress (offset_addr);
7430             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7431                 return false;
7432         }
7433 
7434         // if UnalignedSupport() || address<0> = '0' then
7435         if (UnalignedSupport() || BitIsClear (address, 0))
7436         {
7437             // R[t] = SignExtend(data, 32);
7438             int64_t signed_data = llvm::SignExtend64<16>(data);
7439             context.type = eContextRegisterLoad;
7440             context.SetRegisterPlusOffset (base_reg, address - Rn);
7441             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7442                 return false;
7443         }
7444         else // Can only apply before ARMv7
7445         {
7446             // R[t] = bits(32) UNKNOWN;
7447             WriteBits32Unknown (t);
7448         }
7449     }
7450     return true;
7451 }
7452 
7453 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory,
7454 // sign-extends it to from a 32-bit word, and writes it to a register.
7455 bool
7456 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding)
7457 {
7458 #if 0
7459     if ConditionPassed() then
7460         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7461         base = Align(PC,4);
7462         address = if add then (base + imm32) else (base - imm32);
7463         data = MemU[address,2];
7464         if UnalignedSupport() || address<0> = '0' then
7465             R[t] = SignExtend(data, 32);
7466         else // Can only apply before ARMv7
7467             R[t] = bits(32) UNKNOWN;
7468 #endif
7469 
7470     bool success = false;
7471 
7472     if (ConditionPassed(opcode))
7473     {
7474         uint32_t t;
7475         uint32_t imm32;
7476         bool add;
7477 
7478         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7479         switch (encoding)
7480         {
7481             case eEncodingT1:
7482                 // if Rt == '1111' then SEE "Unallocated memory hints";
7483                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7484                 t = Bits32  (opcode, 15, 12);
7485                 imm32 = Bits32 (opcode, 11, 0);
7486                 add = BitIsSet (opcode, 23);
7487 
7488                 // if t == 13 then UNPREDICTABLE;
7489                 if (t == 13)
7490                     return false;
7491 
7492                 break;
7493 
7494             case eEncodingA1:
7495             {
7496                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7497                 t = Bits32 (opcode, 15, 12);
7498                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7499                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7500                 imm32 = (imm4H << 4) | imm4L;
7501                 add = BitIsSet (opcode, 23);
7502 
7503                 // if t == 15 then UNPREDICTABLE;
7504                 if (t == 15)
7505                     return false;
7506 
7507                 break;
7508             }
7509             default:
7510                 return false;
7511         }
7512 
7513         // base = Align(PC,4);
7514         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7515         if (!success)
7516             return false;
7517 
7518         uint64_t base = AlignPC (pc_value);
7519 
7520         addr_t address;
7521         // address = if add then (base + imm32) else (base - imm32);
7522         if (add)
7523             address = base + imm32;
7524         else
7525             address = base - imm32;
7526 
7527         // data = MemU[address,2];
7528         RegisterInfo base_reg;
7529         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7530 
7531         EmulateInstruction::Context context;
7532         context.type = eContextRegisterLoad;
7533         context.SetRegisterPlusOffset (base_reg, imm32);
7534 
7535         uint64_t data = MemURead (context, address, 2, 0, &success);
7536         if (!success)
7537             return false;
7538 
7539         // if UnalignedSupport() || address<0> = '0' then
7540         if (UnalignedSupport() || BitIsClear (address, 0))
7541         {
7542             // R[t] = SignExtend(data, 32);
7543             int64_t signed_data = llvm::SignExtend64<16>(data);
7544             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7545                 return false;
7546         }
7547         else // Can only apply before ARMv7
7548         {
7549             // R[t] = bits(32) UNKNOWN;
7550             WriteBits32Unknown (t);
7551         }
7552     }
7553     return true;
7554 }
7555 
7556 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword
7557 // from memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7558 // shifted left by 0, 1, 2, or 3 bits.
7559 bool
7560 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding)
7561 {
7562 #if 0
7563     if ConditionPassed() then
7564         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7565         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7566         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7567         address = if index then offset_addr else R[n];
7568         data = MemU[address,2];
7569         if wback then R[n] = offset_addr;
7570         if UnalignedSupport() || address<0> = '0' then
7571             R[t] = SignExtend(data, 32);
7572         else // Can only apply before ARMv7
7573             R[t] = bits(32) UNKNOWN;
7574 #endif
7575 
7576     bool success = false;
7577 
7578     if (ConditionPassed(opcode))
7579     {
7580         uint32_t t;
7581         uint32_t n;
7582         uint32_t m;
7583         bool index;
7584         bool add;
7585         bool wback;
7586         ARM_ShifterType shift_t;
7587         uint32_t shift_n;
7588 
7589         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7590         switch (encoding)
7591         {
7592             case eEncodingT1:
7593                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
7594                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7595                 t = Bits32 (opcode, 2, 0);
7596                 n = Bits32 (opcode, 5, 3);
7597                 m = Bits32 (opcode, 8, 6);
7598 
7599                 // index = TRUE; add = TRUE; wback = FALSE;
7600                 index = true;
7601                 add = true;
7602                 wback = false;
7603 
7604                 // (shift_t, shift_n) = (SRType_LSL, 0);
7605                 shift_t = SRType_LSL;
7606                 shift_n = 0;
7607 
7608                 break;
7609 
7610             case eEncodingT2:
7611                 // if Rn == '1111' then SEE LDRSH (literal);
7612                 // if Rt == '1111' then SEE "Unallocated memory hints";
7613                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7614                 t = Bits32 (opcode, 15, 12);
7615                 n = Bits32 (opcode, 19, 16);
7616                 m = Bits32 (opcode, 3, 0);
7617 
7618                 // index = TRUE; add = TRUE; wback = FALSE;
7619                 index = true;
7620                 add = true;
7621                 wback = false;
7622 
7623                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7624                 shift_t = SRType_LSL;
7625                 shift_n = Bits32 (opcode, 5, 4);
7626 
7627                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7628                 if ((t == 13) || BadReg (m))
7629                     return false;
7630 
7631                 break;
7632 
7633             case eEncodingA1:
7634                 // if P == '0' && W == '1' then SEE LDRSHT;
7635                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7636                 t = Bits32 (opcode, 15, 12);
7637                 n = Bits32 (opcode, 19, 16);
7638                 m = Bits32 (opcode, 3, 0);
7639 
7640                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7641                 index = BitIsSet (opcode, 24);
7642                 add = BitIsSet (opcode, 23);
7643                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7644 
7645                 // (shift_t, shift_n) = (SRType_LSL, 0);
7646                 shift_t = SRType_LSL;
7647                 shift_n = 0;
7648 
7649                 // if t == 15 || m == 15 then UNPREDICTABLE;
7650                 if ((t == 15) || (m == 15))
7651                     return false;
7652 
7653                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7654                 if (wback && ((n == 15) || (n == t)))
7655                     return false;
7656 
7657                 break;
7658 
7659             default:
7660                 return false;
7661         }
7662 
7663         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7664         if (!success)
7665             return false;
7666 
7667         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7668         if (!success)
7669             return false;
7670 
7671         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7672         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7673         if (!success)
7674             return false;
7675 
7676         addr_t offset_addr;
7677         addr_t address;
7678 
7679         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7680         if (add)
7681             offset_addr = Rn + offset;
7682         else
7683             offset_addr = Rn - offset;
7684 
7685         // address = if index then offset_addr else R[n];
7686         if (index)
7687             address = offset_addr;
7688         else
7689             address = Rn;
7690 
7691         // data = MemU[address,2];
7692         RegisterInfo base_reg;
7693         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7694 
7695         RegisterInfo offset_reg;
7696         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7697 
7698         EmulateInstruction::Context context;
7699         context.type = eContextRegisterLoad;
7700         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7701 
7702         uint64_t data = MemURead (context, address, 2, 0, &success);
7703         if (!success)
7704             return false;
7705 
7706         // if wback then R[n] = offset_addr;
7707         if (wback)
7708         {
7709             context.type = eContextAdjustBaseRegister;
7710             context.SetAddress (offset_addr);
7711             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7712                 return false;
7713         }
7714 
7715         // if UnalignedSupport() || address<0> = '0' then
7716         if (UnalignedSupport() || BitIsClear (address, 0))
7717         {
7718             // R[t] = SignExtend(data, 32);
7719             context.type = eContextRegisterLoad;
7720             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7721 
7722             int64_t signed_data = llvm::SignExtend64<16>(data);
7723             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7724                 return false;
7725         }
7726         else // Can only apply before ARMv7
7727         {
7728             // R[t] = bits(32) UNKNOWN;
7729             WriteBits32Unknown (t);
7730         }
7731     }
7732     return true;
7733 }
7734 
7735 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7736 // register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7737 bool
7738 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding)
7739 {
7740 #if 0
7741     if ConditionPassed() then
7742         EncodingSpecificOperations();
7743         rotated = ROR(R[m], rotation);
7744         R[d] = SignExtend(rotated<7:0>, 32);
7745 #endif
7746 
7747     bool success = false;
7748 
7749     if (ConditionPassed(opcode))
7750     {
7751         uint32_t d;
7752         uint32_t m;
7753         uint32_t rotation;
7754 
7755         // EncodingSpecificOperations();
7756         switch (encoding)
7757         {
7758             case eEncodingT1:
7759                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7760                 d = Bits32 (opcode, 2, 0);
7761                 m = Bits32 (opcode, 5, 3);
7762                 rotation = 0;
7763 
7764                 break;
7765 
7766             case eEncodingT2:
7767                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7768                 d = Bits32 (opcode, 11, 8);
7769                 m = Bits32 (opcode, 3, 0);
7770                 rotation = Bits32 (opcode, 5, 4) << 3;
7771 
7772                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7773                 if (BadReg (d) || BadReg (m))
7774                     return false;
7775 
7776                 break;
7777 
7778             case eEncodingA1:
7779                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7780                 d = Bits32 (opcode, 15, 12);
7781                 m = Bits32 (opcode, 3, 0);
7782                 rotation = Bits32 (opcode, 11, 10) << 3;
7783 
7784                 // if d == 15 || m == 15 then UNPREDICTABLE;
7785                 if ((d == 15) || (m == 15))
7786                     return false;
7787 
7788                 break;
7789 
7790             default:
7791                 return false;
7792         }
7793 
7794         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7795         if (!success)
7796             return false;
7797 
7798         // rotated = ROR(R[m], rotation);
7799         uint64_t rotated = ROR (Rm, rotation, &success);
7800         if (!success)
7801             return false;
7802 
7803         // R[d] = SignExtend(rotated<7:0>, 32);
7804         int64_t data = llvm::SignExtend64<8>(rotated);
7805 
7806         RegisterInfo source_reg;
7807         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7808 
7809         EmulateInstruction::Context context;
7810         context.type = eContextRegisterLoad;
7811         context.SetRegister (source_reg);
7812 
7813         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7814             return false;
7815     }
7816     return true;
7817 }
7818 
7819 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7820 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7821 bool
7822 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding)
7823 {
7824 #if 0
7825     if ConditionPassed() then
7826         EncodingSpecificOperations();
7827         rotated = ROR(R[m], rotation);
7828         R[d] = SignExtend(rotated<15:0>, 32);
7829 #endif
7830 
7831     bool success = false;
7832 
7833     if (ConditionPassed(opcode))
7834     {
7835         uint32_t d;
7836         uint32_t m;
7837         uint32_t rotation;
7838 
7839         // EncodingSpecificOperations();
7840         switch (encoding)
7841         {
7842             case eEncodingT1:
7843                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7844                 d = Bits32 (opcode, 2, 0);
7845                 m = Bits32 (opcode, 5, 3);
7846                 rotation = 0;
7847 
7848                 break;
7849 
7850             case eEncodingT2:
7851                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7852                 d = Bits32 (opcode, 11, 8);
7853                 m = Bits32 (opcode, 3, 0);
7854                 rotation = Bits32 (opcode, 5, 4) << 3;
7855 
7856                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7857                 if (BadReg (d) || BadReg (m))
7858                     return false;
7859 
7860                 break;
7861 
7862             case eEncodingA1:
7863                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7864                 d = Bits32 (opcode, 15, 12);
7865                 m = Bits32 (opcode, 3, 0);
7866                 rotation = Bits32 (opcode, 11, 10) << 3;
7867 
7868                 // if d == 15 || m == 15 then UNPREDICTABLE;
7869                 if ((d == 15) || (m == 15))
7870                     return false;
7871 
7872                 break;
7873 
7874             default:
7875                 return false;
7876         }
7877 
7878         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7879         if (!success)
7880             return false;
7881 
7882         // rotated = ROR(R[m], rotation);
7883         uint64_t rotated = ROR (Rm, rotation, &success);
7884         if (!success)
7885             return false;
7886 
7887         // R[d] = SignExtend(rotated<15:0>, 32);
7888         RegisterInfo source_reg;
7889         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7890 
7891         EmulateInstruction::Context context;
7892         context.type = eContextRegisterLoad;
7893         context.SetRegister (source_reg);
7894 
7895         int64_t data = llvm::SignExtend64<16> (rotated);
7896         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7897             return false;
7898     }
7899 
7900     return true;
7901 }
7902 
7903 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination
7904 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7905 bool
7906 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding)
7907 {
7908 #if 0
7909     if ConditionPassed() then
7910         EncodingSpecificOperations();
7911         rotated = ROR(R[m], rotation);
7912         R[d] = ZeroExtend(rotated<7:0>, 32);
7913 #endif
7914 
7915     bool success = false;
7916 
7917     if (ConditionPassed(opcode))
7918     {
7919         uint32_t d;
7920         uint32_t m;
7921         uint32_t rotation;
7922 
7923         // EncodingSpecificOperations();
7924         switch (encoding)
7925         {
7926             case eEncodingT1:
7927                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7928                 d = Bits32 (opcode, 2, 0);
7929                 m = Bits32 (opcode, 5, 3);
7930                 rotation = 0;
7931 
7932                 break;
7933 
7934             case eEncodingT2:
7935                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7936                 d = Bits32 (opcode, 11, 8);
7937                 m = Bits32 (opcode, 3, 0);
7938                   rotation = Bits32 (opcode, 5, 4) << 3;
7939 
7940                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7941                 if (BadReg (d) || BadReg (m))
7942                   return false;
7943 
7944                 break;
7945 
7946             case eEncodingA1:
7947                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7948                 d = Bits32 (opcode, 15, 12);
7949                 m = Bits32 (opcode, 3, 0);
7950                 rotation = Bits32 (opcode, 11, 10) << 3;
7951 
7952                 // if d == 15 || m == 15 then UNPREDICTABLE;
7953                 if ((d == 15) || (m == 15))
7954                     return false;
7955 
7956                 break;
7957 
7958             default:
7959                 return false;
7960         }
7961 
7962         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7963         if (!success)
7964             return false;
7965 
7966         // rotated = ROR(R[m], rotation);
7967         uint64_t rotated = ROR (Rm, rotation, &success);
7968         if (!success)
7969             return false;
7970 
7971         // R[d] = ZeroExtend(rotated<7:0>, 32);
7972         RegisterInfo source_reg;
7973         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7974 
7975         EmulateInstruction::Context context;
7976         context.type = eContextRegisterLoad;
7977         context.SetRegister (source_reg);
7978 
7979         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0)))
7980             return false;
7981     }
7982     return true;
7983 }
7984 
7985 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination
7986 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7987 bool
7988 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding)
7989 {
7990 #if 0
7991     if ConditionPassed() then
7992         EncodingSpecificOperations();
7993         rotated = ROR(R[m], rotation);
7994         R[d] = ZeroExtend(rotated<15:0>, 32);
7995 #endif
7996 
7997     bool success = false;
7998 
7999     if (ConditionPassed(opcode))
8000     {
8001         uint32_t d;
8002         uint32_t m;
8003         uint32_t rotation;
8004 
8005         switch (encoding)
8006         {
8007             case eEncodingT1:
8008                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8009                 d = Bits32 (opcode, 2, 0);
8010                 m = Bits32 (opcode, 5, 3);
8011                 rotation = 0;
8012 
8013                 break;
8014 
8015             case eEncodingT2:
8016                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8017                 d = Bits32 (opcode, 11, 8);
8018                 m = Bits32 (opcode, 3, 0);
8019                 rotation = Bits32 (opcode, 5, 4) << 3;
8020 
8021                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8022                 if (BadReg (d) || BadReg (m))
8023                   return false;
8024 
8025                 break;
8026 
8027             case eEncodingA1:
8028                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8029                 d = Bits32 (opcode, 15, 12);
8030                 m = Bits32 (opcode, 3, 0);
8031                 rotation = Bits32 (opcode, 11, 10) << 3;
8032 
8033                 // if d == 15 || m == 15 then UNPREDICTABLE;
8034                 if ((d == 15) || (m == 15))
8035                     return false;
8036 
8037                 break;
8038 
8039             default:
8040                 return false;
8041         }
8042 
8043         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8044         if (!success)
8045             return false;
8046 
8047         // rotated = ROR(R[m], rotation);
8048         uint64_t rotated = ROR (Rm, rotation, &success);
8049         if (!success)
8050             return false;
8051 
8052         // R[d] = ZeroExtend(rotated<15:0>, 32);
8053         RegisterInfo source_reg;
8054         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8055 
8056         EmulateInstruction::Context context;
8057         context.type = eContextRegisterLoad;
8058         context.SetRegister (source_reg);
8059 
8060         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0)))
8061             return false;
8062     }
8063     return true;
8064 }
8065 
8066 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following
8067 // word respectively.
8068 bool
8069 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding)
8070 {
8071 #if 0
8072     if ConditionPassed() then
8073         EncodingSpecificOperations();
8074         if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8075             UNPREDICTABLE;
8076         else
8077             address = if increment then R[n] else R[n]-8;
8078             if wordhigher then address = address+4;
8079             CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8080             BranchWritePC(MemA[address,4]);
8081             if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8082 #endif
8083 
8084     bool success = false;
8085 
8086     if (ConditionPassed(opcode))
8087     {
8088         uint32_t n;
8089         bool wback;
8090         bool increment;
8091         bool wordhigher;
8092 
8093         // EncodingSpecificOperations();
8094         switch (encoding)
8095         {
8096             case eEncodingT1:
8097                 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE;
8098                 n = Bits32 (opcode, 19, 16);
8099                 wback = BitIsSet (opcode, 21);
8100                 increment = false;
8101                 wordhigher = false;
8102 
8103                 // if n == 15 then UNPREDICTABLE;
8104                 if (n == 15)
8105                     return false;
8106 
8107                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8108                 if (InITBlock() && !LastInITBlock())
8109                     return false;
8110 
8111                 break;
8112 
8113             case eEncodingT2:
8114                 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8115                 n = Bits32 (opcode, 19, 16);
8116                 wback = BitIsSet (opcode, 21);
8117                 increment = true;
8118                 wordhigher = false;
8119 
8120                 // if n == 15 then UNPREDICTABLE;
8121                 if (n == 15)
8122                     return false;
8123 
8124                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8125                 if (InITBlock() && !LastInITBlock())
8126                     return false;
8127 
8128                 break;
8129 
8130             case eEncodingA1:
8131                 // n = UInt(Rn);
8132                 n = Bits32 (opcode, 19, 16);
8133 
8134                 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8135                 wback = BitIsSet (opcode, 21);
8136                 increment = BitIsSet (opcode, 23);
8137                 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23));
8138 
8139                 // if n == 15 then UNPREDICTABLE;
8140                 if (n == 15)
8141                     return false;
8142 
8143                 break;
8144 
8145             default:
8146                 return false;
8147         }
8148 
8149         // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8150         if (!CurrentModeIsPrivileged ())
8151             // UNPREDICTABLE;
8152             return false;
8153         else
8154         {
8155             uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8156             if (!success)
8157                 return false;
8158 
8159             addr_t address;
8160             // address = if increment then R[n] else R[n]-8;
8161             if (increment)
8162                 address = Rn;
8163             else
8164                 address = Rn - 8;
8165 
8166             // if wordhigher then address = address+4;
8167             if (wordhigher)
8168                 address = address + 4;
8169 
8170             // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8171             RegisterInfo base_reg;
8172             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8173 
8174             EmulateInstruction::Context context;
8175             context.type = eContextReturnFromException;
8176             context.SetRegisterPlusOffset (base_reg, address - Rn);
8177 
8178             uint64_t data = MemARead (context, address + 4, 4, 0, &success);
8179             if (!success)
8180                 return false;
8181 
8182             CPSRWriteByInstr (data, 15, true);
8183 
8184             // BranchWritePC(MemA[address,4]);
8185             uint64_t data2 = MemARead (context, address, 4, 0, &success);
8186             if (!success)
8187                 return false;
8188 
8189             BranchWritePC (context, data2);
8190 
8191             // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8192             if (wback)
8193             {
8194                 context.type = eContextAdjustBaseRegister;
8195                 if (increment)
8196                 {
8197                     context.SetOffset (8);
8198                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8))
8199                         return false;
8200                 }
8201                 else
8202                 {
8203                     context.SetOffset (-8);
8204                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8))
8205                         return false;
8206                 }
8207             } // if wback
8208         }
8209     } // if ConditionPassed()
8210     return true;
8211 }
8212 
8213 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
8214 // and writes the result to the destination register.  It can optionally update the condition flags based on
8215 // the result.
8216 bool
8217 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding)
8218 {
8219 #if 0
8220     // ARM pseudo code...
8221     if ConditionPassed() then
8222         EncodingSpecificOperations();
8223         result = R[n] EOR imm32;
8224         if d == 15 then         // Can only occur for ARM encoding
8225             ALUWritePC(result); // setflags is always FALSE here
8226         else
8227             R[d] = result;
8228             if setflags then
8229                 APSR.N = result<31>;
8230                 APSR.Z = IsZeroBit(result);
8231                 APSR.C = carry;
8232                 // APSR.V unchanged
8233 #endif
8234 
8235     bool success = false;
8236 
8237     if (ConditionPassed(opcode))
8238     {
8239         uint32_t Rd, Rn;
8240         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8241         bool setflags;
8242         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8243         switch (encoding)
8244         {
8245         case eEncodingT1:
8246             Rd = Bits32(opcode, 11, 8);
8247             Rn = Bits32(opcode, 19, 16);
8248             setflags = BitIsSet(opcode, 20);
8249             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8250             // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8251             if (Rd == 15 && setflags)
8252                 return EmulateTEQImm (opcode, eEncodingT1);
8253             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8254                 return false;
8255             break;
8256         case eEncodingA1:
8257             Rd = Bits32(opcode, 15, 12);
8258             Rn = Bits32(opcode, 19, 16);
8259             setflags = BitIsSet(opcode, 20);
8260             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8261 
8262             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8263             if (Rd == 15 && setflags)
8264                 return EmulateSUBSPcLrEtc (opcode, encoding);
8265             break;
8266         default:
8267             return false;
8268         }
8269 
8270         // Read the first operand.
8271         uint32_t val1 = ReadCoreReg(Rn, &success);
8272         if (!success)
8273             return false;
8274 
8275         uint32_t result = val1 ^ imm32;
8276 
8277         EmulateInstruction::Context context;
8278         context.type = EmulateInstruction::eContextImmediate;
8279         context.SetNoArgs ();
8280 
8281         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8282             return false;
8283     }
8284     return true;
8285 }
8286 
8287 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an
8288 // optionally-shifted register value, and writes the result to the destination register.
8289 // It can optionally update the condition flags based on the result.
8290 bool
8291 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding)
8292 {
8293 #if 0
8294     // ARM pseudo code...
8295     if ConditionPassed() then
8296         EncodingSpecificOperations();
8297         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8298         result = R[n] EOR shifted;
8299         if d == 15 then         // Can only occur for ARM encoding
8300             ALUWritePC(result); // setflags is always FALSE here
8301         else
8302             R[d] = result;
8303             if setflags then
8304                 APSR.N = result<31>;
8305                 APSR.Z = IsZeroBit(result);
8306                 APSR.C = carry;
8307                 // APSR.V unchanged
8308 #endif
8309 
8310     bool success = false;
8311 
8312     if (ConditionPassed(opcode))
8313     {
8314         uint32_t Rd, Rn, Rm;
8315         ARM_ShifterType shift_t;
8316         uint32_t shift_n; // the shift applied to the value read from Rm
8317         bool setflags;
8318         uint32_t carry;
8319         switch (encoding)
8320         {
8321         case eEncodingT1:
8322             Rd = Rn = Bits32(opcode, 2, 0);
8323             Rm = Bits32(opcode, 5, 3);
8324             setflags = !InITBlock();
8325             shift_t = SRType_LSL;
8326             shift_n = 0;
8327             break;
8328         case eEncodingT2:
8329             Rd = Bits32(opcode, 11, 8);
8330             Rn = Bits32(opcode, 19, 16);
8331             Rm = Bits32(opcode, 3, 0);
8332             setflags = BitIsSet(opcode, 20);
8333             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8334             // if Rd == '1111' && S == '1' then SEE TEQ (register);
8335             if (Rd == 15 && setflags)
8336                 return EmulateTEQReg (opcode, eEncodingT1);
8337             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8338                 return false;
8339             break;
8340         case eEncodingA1:
8341             Rd = Bits32(opcode, 15, 12);
8342             Rn = Bits32(opcode, 19, 16);
8343             Rm = Bits32(opcode, 3, 0);
8344             setflags = BitIsSet(opcode, 20);
8345             shift_n = DecodeImmShiftARM(opcode, shift_t);
8346 
8347             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8348             if (Rd == 15 && setflags)
8349                 return EmulateSUBSPcLrEtc (opcode, encoding);
8350             break;
8351         default:
8352             return false;
8353         }
8354 
8355         // Read the first operand.
8356         uint32_t val1 = ReadCoreReg(Rn, &success);
8357         if (!success)
8358             return false;
8359 
8360         // Read the second operand.
8361         uint32_t val2 = ReadCoreReg(Rm, &success);
8362         if (!success)
8363             return false;
8364 
8365         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8366         if (!success)
8367             return false;
8368         uint32_t result = val1 ^ shifted;
8369 
8370         EmulateInstruction::Context context;
8371         context.type = EmulateInstruction::eContextImmediate;
8372         context.SetNoArgs ();
8373 
8374         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8375             return false;
8376     }
8377     return true;
8378 }
8379 
8380 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and
8381 // writes the result to the destination register.  It can optionally update the condition flags based
8382 // on the result.
8383 bool
8384 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding)
8385 {
8386 #if 0
8387     // ARM pseudo code...
8388     if ConditionPassed() then
8389         EncodingSpecificOperations();
8390         result = R[n] OR imm32;
8391         if d == 15 then         // Can only occur for ARM encoding
8392             ALUWritePC(result); // setflags is always FALSE here
8393         else
8394             R[d] = result;
8395             if setflags then
8396                 APSR.N = result<31>;
8397                 APSR.Z = IsZeroBit(result);
8398                 APSR.C = carry;
8399                 // APSR.V unchanged
8400 #endif
8401 
8402     bool success = false;
8403 
8404     if (ConditionPassed(opcode))
8405     {
8406         uint32_t Rd, Rn;
8407         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8408         bool setflags;
8409         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8410         switch (encoding)
8411         {
8412         case eEncodingT1:
8413             Rd = Bits32(opcode, 11, 8);
8414             Rn = Bits32(opcode, 19, 16);
8415             setflags = BitIsSet(opcode, 20);
8416             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8417             // if Rn == '1111' then SEE MOV (immediate);
8418             if (Rn == 15)
8419                 return EmulateMOVRdImm (opcode, eEncodingT2);
8420             if (BadReg(Rd) || Rn == 13)
8421                 return false;
8422             break;
8423         case eEncodingA1:
8424             Rd = Bits32(opcode, 15, 12);
8425             Rn = Bits32(opcode, 19, 16);
8426             setflags = BitIsSet(opcode, 20);
8427             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8428 
8429             if (Rd == 15 && setflags)
8430                 return EmulateSUBSPcLrEtc (opcode, encoding);
8431             break;
8432         default:
8433             return false;
8434         }
8435 
8436         // Read the first operand.
8437         uint32_t val1 = ReadCoreReg(Rn, &success);
8438         if (!success)
8439             return false;
8440 
8441         uint32_t result = val1 | imm32;
8442 
8443         EmulateInstruction::Context context;
8444         context.type = EmulateInstruction::eContextImmediate;
8445         context.SetNoArgs ();
8446 
8447         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8448             return false;
8449     }
8450     return true;
8451 }
8452 
8453 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register
8454 // value, and writes the result to the destination register.  It can optionally update the condition flags based
8455 // on the result.
8456 bool
8457 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding)
8458 {
8459 #if 0
8460     // ARM pseudo code...
8461     if ConditionPassed() then
8462         EncodingSpecificOperations();
8463         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8464         result = R[n] OR shifted;
8465         if d == 15 then         // Can only occur for ARM encoding
8466             ALUWritePC(result); // setflags is always FALSE here
8467         else
8468             R[d] = result;
8469             if setflags then
8470                 APSR.N = result<31>;
8471                 APSR.Z = IsZeroBit(result);
8472                 APSR.C = carry;
8473                 // APSR.V unchanged
8474 #endif
8475 
8476     bool success = false;
8477 
8478     if (ConditionPassed(opcode))
8479     {
8480         uint32_t Rd, Rn, Rm;
8481         ARM_ShifterType shift_t;
8482         uint32_t shift_n; // the shift applied to the value read from Rm
8483         bool setflags;
8484         uint32_t carry;
8485         switch (encoding)
8486         {
8487         case eEncodingT1:
8488             Rd = Rn = Bits32(opcode, 2, 0);
8489             Rm = Bits32(opcode, 5, 3);
8490             setflags = !InITBlock();
8491             shift_t = SRType_LSL;
8492             shift_n = 0;
8493             break;
8494         case eEncodingT2:
8495             Rd = Bits32(opcode, 11, 8);
8496             Rn = Bits32(opcode, 19, 16);
8497             Rm = Bits32(opcode, 3, 0);
8498             setflags = BitIsSet(opcode, 20);
8499             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8500             // if Rn == '1111' then SEE MOV (register);
8501             if (Rn == 15)
8502                 return EmulateMOVRdRm (opcode, eEncodingT3);
8503             if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
8504                 return false;
8505             break;
8506         case eEncodingA1:
8507             Rd = Bits32(opcode, 15, 12);
8508             Rn = Bits32(opcode, 19, 16);
8509             Rm = Bits32(opcode, 3, 0);
8510             setflags = BitIsSet(opcode, 20);
8511             shift_n = DecodeImmShiftARM(opcode, shift_t);
8512 
8513             if (Rd == 15 && setflags)
8514                 return EmulateSUBSPcLrEtc (opcode, encoding);
8515             break;
8516         default:
8517             return false;
8518         }
8519 
8520         // Read the first operand.
8521         uint32_t val1 = ReadCoreReg(Rn, &success);
8522         if (!success)
8523             return false;
8524 
8525         // Read the second operand.
8526         uint32_t val2 = ReadCoreReg(Rm, &success);
8527         if (!success)
8528             return false;
8529 
8530         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8531         if (!success)
8532             return false;
8533         uint32_t result = val1 | shifted;
8534 
8535         EmulateInstruction::Context context;
8536         context.type = EmulateInstruction::eContextImmediate;
8537         context.SetNoArgs ();
8538 
8539         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8540             return false;
8541     }
8542     return true;
8543 }
8544 
8545 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to
8546 // the destination register. It can optionally update the condition flags based on the result.
8547 bool
8548 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding)
8549 {
8550 #if 0
8551     // ARM pseudo code...
8552     if ConditionPassed() then
8553         EncodingSpecificOperations();
8554         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
8555         if d == 15 then         // Can only occur for ARM encoding
8556             ALUWritePC(result); // setflags is always FALSE here
8557         else
8558             R[d] = result;
8559             if setflags then
8560                 APSR.N = result<31>;
8561                 APSR.Z = IsZeroBit(result);
8562                 APSR.C = carry;
8563                 APSR.V = overflow;
8564 #endif
8565 
8566     bool success = false;
8567 
8568     uint32_t Rd; // the destination register
8569     uint32_t Rn; // the first operand
8570     bool setflags;
8571     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8572     switch (encoding) {
8573     case eEncodingT1:
8574         Rd = Bits32(opcode, 2, 0);
8575         Rn = Bits32(opcode, 5, 3);
8576         setflags = !InITBlock();
8577         imm32 = 0;
8578         break;
8579     case eEncodingT2:
8580         Rd = Bits32(opcode, 11, 8);
8581         Rn = Bits32(opcode, 19, 16);
8582         setflags = BitIsSet(opcode, 20);
8583         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8584         if (BadReg(Rd) || BadReg(Rn))
8585             return false;
8586         break;
8587     case eEncodingA1:
8588         Rd = Bits32(opcode, 15, 12);
8589         Rn = Bits32(opcode, 19, 16);
8590         setflags = BitIsSet(opcode, 20);
8591         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8592 
8593         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8594         if (Rd == 15 && setflags)
8595             return EmulateSUBSPcLrEtc (opcode, encoding);
8596         break;
8597     default:
8598         return false;
8599     }
8600     // Read the register value from the operand register Rn.
8601     uint32_t reg_val = ReadCoreReg(Rn, &success);
8602     if (!success)
8603         return false;
8604 
8605     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
8606 
8607     EmulateInstruction::Context context;
8608     context.type = EmulateInstruction::eContextImmediate;
8609     context.SetNoArgs ();
8610 
8611     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8612         return false;
8613 
8614     return true;
8615 }
8616 
8617 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the
8618 // result to the destination register. It can optionally update the condition flags based on the result.
8619 bool
8620 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding)
8621 {
8622 #if 0
8623     // ARM pseudo code...
8624     if ConditionPassed() then
8625         EncodingSpecificOperations();
8626         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8627         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
8628         if d == 15 then         // Can only occur for ARM encoding
8629             ALUWritePC(result); // setflags is always FALSE here
8630         else
8631             R[d] = result;
8632             if setflags then
8633                 APSR.N = result<31>;
8634                 APSR.Z = IsZeroBit(result);
8635                 APSR.C = carry;
8636                 APSR.V = overflow;
8637 #endif
8638 
8639     bool success = false;
8640 
8641     uint32_t Rd; // the destination register
8642     uint32_t Rn; // the first operand
8643     uint32_t Rm; // the second operand
8644     bool setflags;
8645     ARM_ShifterType shift_t;
8646     uint32_t shift_n; // the shift applied to the value read from Rm
8647     switch (encoding) {
8648     case eEncodingT1:
8649         Rd = Bits32(opcode, 11, 8);
8650         Rn = Bits32(opcode, 19, 16);
8651         Rm = Bits32(opcode, 3, 0);
8652         setflags = BitIsSet(opcode, 20);
8653         shift_n = DecodeImmShiftThumb(opcode, shift_t);
8654         // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
8655         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8656             return false;
8657         break;
8658     case eEncodingA1:
8659         Rd = Bits32(opcode, 15, 12);
8660         Rn = Bits32(opcode, 19, 16);
8661         Rm = Bits32(opcode, 3, 0);
8662         setflags = BitIsSet(opcode, 20);
8663         shift_n = DecodeImmShiftARM(opcode, shift_t);
8664 
8665         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8666         if (Rd == 15 && setflags)
8667             return EmulateSUBSPcLrEtc (opcode, encoding);
8668         break;
8669     default:
8670         return false;
8671     }
8672     // Read the register value from register Rn.
8673     uint32_t val1 = ReadCoreReg(Rn, &success);
8674     if (!success)
8675         return false;
8676 
8677     // Read the register value from register Rm.
8678     uint32_t val2 = ReadCoreReg(Rm, &success);
8679     if (!success)
8680         return false;
8681 
8682     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8683     if (!success)
8684         return false;
8685     AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
8686 
8687     EmulateInstruction::Context context;
8688     context.type = EmulateInstruction::eContextImmediate;
8689     context.SetNoArgs();
8690     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8691         return false;
8692 
8693     return true;
8694 }
8695 
8696 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from
8697 // an immediate value, and writes the result to the destination register. It can optionally update the condition
8698 // flags based on the result.
8699 bool
8700 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding)
8701 {
8702 #if 0
8703     // ARM pseudo code...
8704     if ConditionPassed() then
8705         EncodingSpecificOperations();
8706         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
8707         if d == 15 then
8708             ALUWritePC(result); // setflags is always FALSE here
8709         else
8710             R[d] = result;
8711             if setflags then
8712                 APSR.N = result<31>;
8713                 APSR.Z = IsZeroBit(result);
8714                 APSR.C = carry;
8715                 APSR.V = overflow;
8716 #endif
8717 
8718     bool success = false;
8719 
8720     uint32_t Rd; // the destination register
8721     uint32_t Rn; // the first operand
8722     bool setflags;
8723     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8724     switch (encoding) {
8725     case eEncodingA1:
8726         Rd = Bits32(opcode, 15, 12);
8727         Rn = Bits32(opcode, 19, 16);
8728         setflags = BitIsSet(opcode, 20);
8729         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8730 
8731         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8732         if (Rd == 15 && setflags)
8733             return EmulateSUBSPcLrEtc  (opcode, encoding);
8734         break;
8735     default:
8736         return false;
8737     }
8738     // Read the register value from the operand register Rn.
8739     uint32_t reg_val = ReadCoreReg(Rn, &success);
8740     if (!success)
8741         return false;
8742 
8743     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
8744 
8745     EmulateInstruction::Context context;
8746     context.type = EmulateInstruction::eContextImmediate;
8747     context.SetNoArgs ();
8748 
8749     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8750         return false;
8751 
8752     return true;
8753 }
8754 
8755 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an
8756 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the
8757 // condition flags based on the result.
8758 bool
8759 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding)
8760 {
8761 #if 0
8762     // ARM pseudo code...
8763     if ConditionPassed() then
8764         EncodingSpecificOperations();
8765         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8766         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
8767         if d == 15 then
8768             ALUWritePC(result); // setflags is always FALSE here
8769         else
8770             R[d] = result;
8771             if setflags then
8772                 APSR.N = result<31>;
8773                 APSR.Z = IsZeroBit(result);
8774                 APSR.C = carry;
8775                 APSR.V = overflow;
8776 #endif
8777 
8778     bool success = false;
8779 
8780     uint32_t Rd; // the destination register
8781     uint32_t Rn; // the first operand
8782     uint32_t Rm; // the second operand
8783     bool setflags;
8784     ARM_ShifterType shift_t;
8785     uint32_t shift_n; // the shift applied to the value read from Rm
8786     switch (encoding) {
8787     case eEncodingA1:
8788         Rd = Bits32(opcode, 15, 12);
8789         Rn = Bits32(opcode, 19, 16);
8790         Rm = Bits32(opcode, 3, 0);
8791         setflags = BitIsSet(opcode, 20);
8792         shift_n = DecodeImmShiftARM(opcode, shift_t);
8793 
8794         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8795         if (Rd == 15 && setflags)
8796             return EmulateSUBSPcLrEtc (opcode, encoding);
8797         break;
8798     default:
8799         return false;
8800     }
8801     // Read the register value from register Rn.
8802     uint32_t val1 = ReadCoreReg(Rn, &success);
8803     if (!success)
8804         return false;
8805 
8806     // Read the register value from register Rm.
8807     uint32_t val2 = ReadCoreReg(Rm, &success);
8808     if (!success)
8809         return false;
8810 
8811     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8812     if (!success)
8813         return false;
8814     AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
8815 
8816     EmulateInstruction::Context context;
8817     context.type = EmulateInstruction::eContextImmediate;
8818     context.SetNoArgs();
8819     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8820         return false;
8821 
8822     return true;
8823 }
8824 
8825 // Subtract with Carry (immediate) subtracts an immediate value and the value of
8826 // NOT (Carry flag) from a register value, and writes the result to the destination register.
8827 // It can optionally update the condition flags based on the result.
8828 bool
8829 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding)
8830 {
8831 #if 0
8832     // ARM pseudo code...
8833     if ConditionPassed() then
8834         EncodingSpecificOperations();
8835         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
8836         if d == 15 then         // Can only occur for ARM encoding
8837             ALUWritePC(result); // setflags is always FALSE here
8838         else
8839             R[d] = result;
8840             if setflags then
8841                 APSR.N = result<31>;
8842                 APSR.Z = IsZeroBit(result);
8843                 APSR.C = carry;
8844                 APSR.V = overflow;
8845 #endif
8846 
8847     bool success = false;
8848 
8849     uint32_t Rd; // the destination register
8850     uint32_t Rn; // the first operand
8851     bool setflags;
8852     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8853     switch (encoding) {
8854     case eEncodingT1:
8855         Rd = Bits32(opcode, 11, 8);
8856         Rn = Bits32(opcode, 19, 16);
8857         setflags = BitIsSet(opcode, 20);
8858         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8859         if (BadReg(Rd) || BadReg(Rn))
8860             return false;
8861         break;
8862     case eEncodingA1:
8863         Rd = Bits32(opcode, 15, 12);
8864         Rn = Bits32(opcode, 19, 16);
8865         setflags = BitIsSet(opcode, 20);
8866         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8867 
8868         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8869         if (Rd == 15 && setflags)
8870             return EmulateSUBSPcLrEtc (opcode, encoding);
8871         break;
8872     default:
8873         return false;
8874     }
8875     // Read the register value from the operand register Rn.
8876     uint32_t reg_val = ReadCoreReg(Rn, &success);
8877     if (!success)
8878         return false;
8879 
8880     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
8881 
8882     EmulateInstruction::Context context;
8883     context.type = EmulateInstruction::eContextImmediate;
8884     context.SetNoArgs ();
8885 
8886     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8887         return false;
8888 
8889     return true;
8890 }
8891 
8892 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of
8893 // NOT (Carry flag) from a register value, and writes the result to the destination register.
8894 // It can optionally update the condition flags based on the result.
8895 bool
8896 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding)
8897 {
8898 #if 0
8899     // ARM pseudo code...
8900     if ConditionPassed() then
8901         EncodingSpecificOperations();
8902         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8903         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
8904         if d == 15 then         // Can only occur for ARM encoding
8905             ALUWritePC(result); // setflags is always FALSE here
8906         else
8907             R[d] = result;
8908             if setflags then
8909                 APSR.N = result<31>;
8910                 APSR.Z = IsZeroBit(result);
8911                 APSR.C = carry;
8912                 APSR.V = overflow;
8913 #endif
8914 
8915     bool success = false;
8916 
8917     uint32_t Rd; // the destination register
8918     uint32_t Rn; // the first operand
8919     uint32_t Rm; // the second operand
8920     bool setflags;
8921     ARM_ShifterType shift_t;
8922     uint32_t shift_n; // the shift applied to the value read from Rm
8923     switch (encoding) {
8924     case eEncodingT1:
8925         Rd = Rn = Bits32(opcode, 2, 0);
8926         Rm = Bits32(opcode, 5, 3);
8927         setflags = !InITBlock();
8928         shift_t = SRType_LSL;
8929         shift_n = 0;
8930         break;
8931     case eEncodingT2:
8932         Rd = Bits32(opcode, 11, 8);
8933         Rn = Bits32(opcode, 19, 16);
8934         Rm = Bits32(opcode, 3, 0);
8935         setflags = BitIsSet(opcode, 20);
8936         shift_n = DecodeImmShiftThumb(opcode, shift_t);
8937         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8938             return false;
8939         break;
8940     case eEncodingA1:
8941         Rd = Bits32(opcode, 15, 12);
8942         Rn = Bits32(opcode, 19, 16);
8943         Rm = Bits32(opcode, 3, 0);
8944         setflags = BitIsSet(opcode, 20);
8945         shift_n = DecodeImmShiftARM(opcode, shift_t);
8946 
8947         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8948         if (Rd == 15 && setflags)
8949             return EmulateSUBSPcLrEtc (opcode, encoding);
8950         break;
8951     default:
8952         return false;
8953     }
8954     // Read the register value from register Rn.
8955     uint32_t val1 = ReadCoreReg(Rn, &success);
8956     if (!success)
8957         return false;
8958 
8959     // Read the register value from register Rm.
8960     uint32_t val2 = ReadCoreReg(Rm, &success);
8961     if (!success)
8962         return false;
8963 
8964     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8965     if (!success)
8966         return false;
8967     AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
8968 
8969     EmulateInstruction::Context context;
8970     context.type = EmulateInstruction::eContextImmediate;
8971     context.SetNoArgs();
8972     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8973         return false;
8974 
8975     return true;
8976 }
8977 
8978 // This instruction subtracts an immediate value from a register value, and writes the result
8979 // to the destination register.  It can optionally update the condition flags based on the result.
8980 bool
8981 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding)
8982 {
8983 #if 0
8984     // ARM pseudo code...
8985     if ConditionPassed() then
8986         EncodingSpecificOperations();
8987         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
8988         R[d] = result;
8989         if setflags then
8990             APSR.N = result<31>;
8991             APSR.Z = IsZeroBit(result);
8992             APSR.C = carry;
8993             APSR.V = overflow;
8994 #endif
8995 
8996     bool success = false;
8997 
8998     uint32_t Rd; // the destination register
8999     uint32_t Rn; // the first operand
9000     bool setflags;
9001     uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9002     switch (encoding) {
9003     case eEncodingT1:
9004         Rd = Bits32(opcode, 2, 0);
9005         Rn = Bits32(opcode, 5, 3);
9006         setflags = !InITBlock();
9007         imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9008         break;
9009     case eEncodingT2:
9010         Rd = Rn = Bits32(opcode, 10, 8);
9011         setflags = !InITBlock();
9012         imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9013         break;
9014     case eEncodingT3:
9015         Rd = Bits32(opcode, 11, 8);
9016         Rn = Bits32(opcode, 19, 16);
9017         setflags = BitIsSet(opcode, 20);
9018         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9019 
9020         // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9021         if (Rd == 15 && setflags)
9022             return EmulateCMPImm (opcode, eEncodingT2);
9023 
9024         // if Rn == '1101' then SEE SUB (SP minus immediate);
9025         if (Rn == 13)
9026             return EmulateSUBSPImm (opcode, eEncodingT2);
9027 
9028         // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9029         if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9030             return false;
9031         break;
9032     case eEncodingT4:
9033         Rd = Bits32(opcode, 11, 8);
9034         Rn = Bits32(opcode, 19, 16);
9035         setflags = BitIsSet(opcode, 20);
9036         imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9037 
9038         // if Rn == '1111' then SEE ADR;
9039         if (Rn == 15)
9040             return EmulateADR (opcode, eEncodingT2);
9041 
9042         // if Rn == '1101' then SEE SUB (SP minus immediate);
9043         if (Rn == 13)
9044             return EmulateSUBSPImm (opcode, eEncodingT3);
9045 
9046         if (BadReg(Rd))
9047             return false;
9048         break;
9049     default:
9050         return false;
9051     }
9052     // Read the register value from the operand register Rn.
9053     uint32_t reg_val = ReadCoreReg(Rn, &success);
9054     if (!success)
9055         return false;
9056 
9057     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9058 
9059     EmulateInstruction::Context context;
9060     context.type = EmulateInstruction::eContextImmediate;
9061     context.SetNoArgs ();
9062 
9063     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9064         return false;
9065 
9066     return true;
9067 }
9068 
9069 // This instruction subtracts an immediate value from a register value, and writes the result
9070 // to the destination register.  It can optionally update the condition flags based on the result.
9071 bool
9072 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9073 {
9074 #if 0
9075     // ARM pseudo code...
9076     if ConditionPassed() then
9077         EncodingSpecificOperations();
9078         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9079         if d == 15 then
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     bool setflags;
9095     uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9096     switch (encoding) {
9097     case eEncodingA1:
9098         Rd = Bits32(opcode, 15, 12);
9099         Rn = Bits32(opcode, 19, 16);
9100         setflags = BitIsSet(opcode, 20);
9101         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9102 
9103         // if Rn == '1111' && S == '0' then SEE ADR;
9104         if (Rn == 15 && !setflags)
9105             return EmulateADR (opcode, eEncodingA2);
9106 
9107         // if Rn == '1101' then SEE SUB (SP minus immediate);
9108         if (Rn == 13)
9109             return EmulateSUBSPImm (opcode, eEncodingA1);
9110 
9111         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9112         if (Rd == 15 && setflags)
9113             return EmulateSUBSPcLrEtc (opcode, encoding);
9114         break;
9115     default:
9116         return false;
9117     }
9118     // Read the register value from the operand register Rn.
9119     uint32_t reg_val = ReadCoreReg(Rn, &success);
9120     if (!success)
9121         return false;
9122 
9123     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9124 
9125     EmulateInstruction::Context context;
9126     context.type = EmulateInstruction::eContextImmediate;
9127     context.SetNoArgs ();
9128 
9129     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9130         return false;
9131 
9132     return true;
9133 }
9134 
9135 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an
9136 // immediate value.  It updates the condition flags based on the result, and discards the result.
9137 bool
9138 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding)
9139 {
9140 #if 0
9141     // ARM pseudo code...
9142     if ConditionPassed() then
9143         EncodingSpecificOperations();
9144         result = R[n] EOR imm32;
9145         APSR.N = result<31>;
9146         APSR.Z = IsZeroBit(result);
9147         APSR.C = carry;
9148         // APSR.V unchanged
9149 #endif
9150 
9151     bool success = false;
9152 
9153     if (ConditionPassed(opcode))
9154     {
9155         uint32_t Rn;
9156         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9157         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9158         switch (encoding)
9159         {
9160         case eEncodingT1:
9161             Rn = Bits32(opcode, 19, 16);
9162             imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9163             if (BadReg(Rn))
9164                 return false;
9165             break;
9166         case eEncodingA1:
9167             Rn = Bits32(opcode, 19, 16);
9168             imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9169             break;
9170         default:
9171             return false;
9172         }
9173 
9174         // Read the first operand.
9175         uint32_t val1 = ReadCoreReg(Rn, &success);
9176         if (!success)
9177             return false;
9178 
9179         uint32_t result = val1 ^ imm32;
9180 
9181         EmulateInstruction::Context context;
9182         context.type = EmulateInstruction::eContextImmediate;
9183         context.SetNoArgs ();
9184 
9185         if (!WriteFlags(context, result, carry))
9186             return false;
9187     }
9188     return true;
9189 }
9190 
9191 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an
9192 // optionally-shifted register value.  It updates the condition flags based on the result, and discards
9193 // the result.
9194 bool
9195 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding)
9196 {
9197 #if 0
9198     // ARM pseudo code...
9199     if ConditionPassed() then
9200         EncodingSpecificOperations();
9201         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9202         result = R[n] EOR shifted;
9203         APSR.N = result<31>;
9204         APSR.Z = IsZeroBit(result);
9205         APSR.C = carry;
9206         // APSR.V unchanged
9207 #endif
9208 
9209     bool success = false;
9210 
9211     if (ConditionPassed(opcode))
9212     {
9213         uint32_t Rn, Rm;
9214         ARM_ShifterType shift_t;
9215         uint32_t shift_n; // the shift applied to the value read from Rm
9216         uint32_t carry;
9217         switch (encoding)
9218         {
9219         case eEncodingT1:
9220             Rn = Bits32(opcode, 19, 16);
9221             Rm = Bits32(opcode, 3, 0);
9222             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9223             if (BadReg(Rn) || BadReg(Rm))
9224                 return false;
9225             break;
9226         case eEncodingA1:
9227             Rn = Bits32(opcode, 19, 16);
9228             Rm = Bits32(opcode, 3, 0);
9229             shift_n = DecodeImmShiftARM(opcode, shift_t);
9230             break;
9231         default:
9232             return false;
9233         }
9234 
9235         // Read the first operand.
9236         uint32_t val1 = ReadCoreReg(Rn, &success);
9237         if (!success)
9238             return false;
9239 
9240         // Read the second operand.
9241         uint32_t val2 = ReadCoreReg(Rm, &success);
9242         if (!success)
9243             return false;
9244 
9245         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9246         if (!success)
9247             return false;
9248         uint32_t result = val1 ^ shifted;
9249 
9250         EmulateInstruction::Context context;
9251         context.type = EmulateInstruction::eContextImmediate;
9252         context.SetNoArgs ();
9253 
9254         if (!WriteFlags(context, result, carry))
9255             return false;
9256     }
9257     return true;
9258 }
9259 
9260 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value.
9261 // It updates the condition flags based on the result, and discards the result.
9262 bool
9263 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding)
9264 {
9265 #if 0
9266     // ARM pseudo code...
9267     if ConditionPassed() then
9268         EncodingSpecificOperations();
9269         result = R[n] AND imm32;
9270         APSR.N = result<31>;
9271         APSR.Z = IsZeroBit(result);
9272         APSR.C = carry;
9273         // APSR.V unchanged
9274 #endif
9275 
9276     bool success = false;
9277 
9278     if (ConditionPassed(opcode))
9279     {
9280         uint32_t Rn;
9281         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9282         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9283         switch (encoding)
9284         {
9285         case eEncodingT1:
9286             Rn = Bits32(opcode, 19, 16);
9287             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9288             if (BadReg(Rn))
9289                 return false;
9290             break;
9291         case eEncodingA1:
9292             Rn = Bits32(opcode, 19, 16);
9293             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9294             break;
9295         default:
9296             return false;
9297         }
9298 
9299         // Read the first operand.
9300         uint32_t val1 = ReadCoreReg(Rn, &success);
9301         if (!success)
9302             return false;
9303 
9304         uint32_t result = val1 & imm32;
9305 
9306         EmulateInstruction::Context context;
9307         context.type = EmulateInstruction::eContextImmediate;
9308         context.SetNoArgs ();
9309 
9310         if (!WriteFlags(context, result, carry))
9311             return false;
9312     }
9313     return true;
9314 }
9315 
9316 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value.
9317 // It updates the condition flags based on the result, and discards the result.
9318 bool
9319 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding)
9320 {
9321 #if 0
9322     // ARM pseudo code...
9323     if ConditionPassed() then
9324         EncodingSpecificOperations();
9325         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9326         result = R[n] AND shifted;
9327         APSR.N = result<31>;
9328         APSR.Z = IsZeroBit(result);
9329         APSR.C = carry;
9330         // APSR.V unchanged
9331 #endif
9332 
9333     bool success = false;
9334 
9335     if (ConditionPassed(opcode))
9336     {
9337         uint32_t Rn, Rm;
9338         ARM_ShifterType shift_t;
9339         uint32_t shift_n; // the shift applied to the value read from Rm
9340         uint32_t carry;
9341         switch (encoding)
9342         {
9343         case eEncodingT1:
9344             Rn = Bits32(opcode, 2, 0);
9345             Rm = Bits32(opcode, 5, 3);
9346             shift_t = SRType_LSL;
9347             shift_n = 0;
9348             break;
9349         case eEncodingT2:
9350             Rn = Bits32(opcode, 19, 16);
9351             Rm = Bits32(opcode, 3, 0);
9352             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9353             if (BadReg(Rn) || BadReg(Rm))
9354                 return false;
9355             break;
9356         case eEncodingA1:
9357             Rn = Bits32(opcode, 19, 16);
9358             Rm = Bits32(opcode, 3, 0);
9359             shift_n = DecodeImmShiftARM(opcode, shift_t);
9360             break;
9361         default:
9362             return false;
9363         }
9364 
9365         // Read the first operand.
9366         uint32_t val1 = ReadCoreReg(Rn, &success);
9367         if (!success)
9368             return false;
9369 
9370         // Read the second operand.
9371         uint32_t val2 = ReadCoreReg(Rm, &success);
9372         if (!success)
9373             return false;
9374 
9375         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9376         if (!success)
9377             return false;
9378         uint32_t result = val1 & shifted;
9379 
9380         EmulateInstruction::Context context;
9381         context.type = EmulateInstruction::eContextImmediate;
9382         context.SetNoArgs ();
9383 
9384         if (!WriteFlags(context, result, carry))
9385             return false;
9386     }
9387     return true;
9388 }
9389 
9390 // A8.6.216 SUB (SP minus register)
9391 bool
9392 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding)
9393 {
9394 #if 0
9395     if ConditionPassed() then
9396         EncodingSpecificOperations();
9397         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9398         (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9399         if d == 15 then // Can only occur for ARM encoding
9400             ALUWritePC(result); // setflags is always FALSE here
9401         else
9402             R[d] = result;
9403             if setflags then
9404                 APSR.N = result<31>;
9405                 APSR.Z = IsZeroBit(result);
9406                 APSR.C = carry;
9407                 APSR.V = overflow;
9408 #endif
9409 
9410     bool success = false;
9411 
9412     if (ConditionPassed(opcode))
9413     {
9414         uint32_t d;
9415         uint32_t m;
9416         bool setflags;
9417         ARM_ShifterType shift_t;
9418         uint32_t shift_n;
9419 
9420         switch (encoding)
9421         {
9422             case eEncodingT1:
9423                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9424                 d = Bits32 (opcode, 11, 8);
9425                 m = Bits32 (opcode, 3, 0);
9426                 setflags = BitIsSet (opcode, 20);
9427 
9428                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9429                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9430 
9431                 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE;
9432                 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
9433                     return false;
9434 
9435                 // if d == 15 || BadReg(m) then UNPREDICTABLE;
9436                 if ((d == 15) || BadReg (m))
9437                     return false;
9438                 break;
9439 
9440             case eEncodingA1:
9441                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9442                 d = Bits32 (opcode, 15, 12);
9443                 m = Bits32 (opcode, 3, 0);
9444                 setflags = BitIsSet (opcode, 20);
9445 
9446                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9447                 if (d == 15 && setflags)
9448                     EmulateSUBSPcLrEtc (opcode, encoding);
9449 
9450                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9451                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9452                 break;
9453 
9454             default:
9455                 return false;
9456         }
9457 
9458         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9459         uint32_t Rm = ReadCoreReg (m, &success);
9460         if (!success)
9461             return false;
9462 
9463         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9464         if (!success)
9465             return false;
9466 
9467         // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9468         uint32_t sp_val = ReadCoreReg (SP_REG, &success);
9469         if (!success)
9470             return false;
9471 
9472         AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1);
9473 
9474         EmulateInstruction::Context context;
9475         context.type = eContextArithmetic;
9476         RegisterInfo sp_reg;
9477         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
9478         RegisterInfo dwarf_reg;
9479         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
9480         context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
9481 
9482         if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9483             return false;
9484     }
9485     return true;
9486 }
9487 
9488 
9489 // A8.6.7 ADD (register-shifted register)
9490 bool
9491 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding)
9492 {
9493 #if 0
9494     if ConditionPassed() then
9495         EncodingSpecificOperations();
9496         shift_n = UInt(R[s]<7:0>);
9497         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9498         (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9499         R[d] = result;
9500         if setflags then
9501             APSR.N = result<31>;
9502             APSR.Z = IsZeroBit(result);
9503             APSR.C = carry;
9504             APSR.V = overflow;
9505 #endif
9506 
9507     bool success = false;
9508 
9509     if (ConditionPassed(opcode))
9510     {
9511         uint32_t d;
9512         uint32_t n;
9513         uint32_t m;
9514         uint32_t s;
9515         bool setflags;
9516         ARM_ShifterType shift_t;
9517 
9518         switch (encoding)
9519         {
9520             case eEncodingA1:
9521                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
9522                 d = Bits32 (opcode, 15, 12);
9523                 n = Bits32 (opcode, 19, 16);
9524                 m = Bits32 (opcode, 3, 0);
9525                 s = Bits32 (opcode, 11, 8);
9526 
9527                 // setflags = (S == �1�); shift_t = DecodeRegShift(type);
9528                 setflags = BitIsSet (opcode, 20);
9529                 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5));
9530 
9531                 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
9532                 if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
9533                     return false;
9534                 break;
9535 
9536             default:
9537                 return false;
9538         }
9539 
9540         // shift_n = UInt(R[s]<7:0>);
9541         uint32_t Rs = ReadCoreReg (s, &success);
9542         if (!success)
9543             return false;
9544 
9545         uint32_t shift_n = Bits32 (Rs, 7, 0);
9546 
9547         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9548         uint32_t Rm = ReadCoreReg (m, &success);
9549         if (!success)
9550             return false;
9551 
9552         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9553         if (!success)
9554             return false;
9555 
9556         // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9557         uint32_t Rn = ReadCoreReg (n, &success);
9558         if (!success)
9559             return false;
9560 
9561         AddWithCarryResult res = AddWithCarry (Rn, shifted, 0);
9562 
9563         // R[d] = result;
9564         EmulateInstruction::Context context;
9565         context.type = eContextArithmetic;
9566         RegisterInfo reg_n;
9567         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9568         RegisterInfo reg_m;
9569         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9570 
9571         context.SetRegisterRegisterOperands (reg_n, reg_m);
9572 
9573         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result))
9574             return false;
9575 
9576         // if setflags then
9577             // APSR.N = result<31>;
9578             // APSR.Z = IsZeroBit(result);
9579             // APSR.C = carry;
9580             // APSR.V = overflow;
9581         if (setflags)
9582             return WriteFlags (context, res.result, res.carry_out, res.overflow);
9583     }
9584     return true;
9585 }
9586 
9587 // A8.6.213 SUB (register)
9588 bool
9589 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding)
9590 {
9591 #if 0
9592     if ConditionPassed() then
9593         EncodingSpecificOperations();
9594         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9595         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9596         if d == 15 then // Can only occur for ARM encoding
9597             ALUWritePC(result); // setflags is always FALSE here
9598         else
9599             R[d] = result;
9600             if setflags then
9601                 APSR.N = result<31>;
9602                 APSR.Z = IsZeroBit(result);
9603                 APSR.C = carry;
9604                 APSR.V = overflow;
9605 #endif
9606 
9607     bool success = false;
9608 
9609     if (ConditionPassed(opcode))
9610     {
9611         uint32_t d;
9612         uint32_t n;
9613         uint32_t m;
9614         bool setflags;
9615         ARM_ShifterType shift_t;
9616         uint32_t shift_n;
9617 
9618         switch (encoding)
9619         {
9620             case eEncodingT1:
9621                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
9622                 d = Bits32 (opcode, 2, 0);
9623                 n = Bits32 (opcode, 5, 3);
9624                 m = Bits32 (opcode, 8, 6);
9625                 setflags = !InITBlock();
9626 
9627                 // (shift_t, shift_n) = (SRType_LSL, 0);
9628                 shift_t = SRType_LSL;
9629                 shift_n = 0;
9630 
9631                 break;
9632 
9633             case eEncodingT2:
9634                 // if Rd == �1111� && S == �1� then SEE CMP (register);
9635                 // if Rn == �1101� then SEE SUB (SP minus register);
9636                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9637                 d = Bits32 (opcode, 11, 8);
9638                 n = Bits32 (opcode, 19, 16);
9639                 m = Bits32 (opcode, 3, 0);
9640                 setflags = BitIsSet (opcode, 20);
9641 
9642                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9643                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9644 
9645                 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE;
9646                 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m))
9647                     return false;
9648 
9649                 break;
9650 
9651             case eEncodingA1:
9652                 // if Rn == �1101� then SEE SUB (SP minus register);
9653                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9654                 d = Bits32 (opcode, 15, 12);
9655                 n = Bits32 (opcode, 19, 16);
9656                 m = Bits32 (opcode, 3, 0);
9657                 setflags = BitIsSet (opcode, 20);
9658 
9659                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9660                 if ((d == 15) && setflags)
9661                     EmulateSUBSPcLrEtc (opcode, encoding);
9662 
9663                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9664                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9665 
9666                 break;
9667 
9668             default:
9669                 return false;
9670         }
9671 
9672         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9673         uint32_t Rm = ReadCoreReg (m, &success);
9674         if (!success)
9675             return false;
9676 
9677         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9678         if (!success)
9679             return false;
9680 
9681         // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9682         uint32_t Rn = ReadCoreReg (n, &success);
9683         if (!success)
9684             return false;
9685 
9686         AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1);
9687 
9688         // if d == 15 then // Can only occur for ARM encoding
9689             // ALUWritePC(result); // setflags is always FALSE here
9690         // else
9691             // R[d] = result;
9692             // if setflags then
9693                 // APSR.N = result<31>;
9694                 // APSR.Z = IsZeroBit(result);
9695                 // APSR.C = carry;
9696                 // APSR.V = overflow;
9697 
9698         EmulateInstruction::Context context;
9699         context.type = eContextArithmetic;
9700         RegisterInfo reg_n;
9701         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9702         RegisterInfo reg_m;
9703         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9704         context.SetRegisterRegisterOperands (reg_n, reg_m);
9705 
9706         if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9707             return false;
9708     }
9709     return true;
9710 }
9711 
9712 // A8.6.202 STREX
9713 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a
9714 // word from a register to memory if the executing processor has exclusive access to the memory addressed.
9715 bool
9716 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding)
9717 {
9718 #if 0
9719     if ConditionPassed() then
9720         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9721         address = R[n] + imm32;
9722         if ExclusiveMonitorsPass(address,4) then
9723             MemA[address,4] = R[t];
9724             R[d] = 0;
9725         else
9726             R[d] = 1;
9727 #endif
9728 
9729     bool success = false;
9730 
9731     if (ConditionPassed(opcode))
9732     {
9733         uint32_t d;
9734         uint32_t t;
9735         uint32_t n;
9736         uint32_t imm32;
9737         const uint32_t addr_byte_size = GetAddressByteSize();
9738 
9739         switch (encoding)
9740         {
9741             case eEncodingT1:
9742                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
9743                 d = Bits32 (opcode, 11, 8);
9744                 t = Bits32 (opcode, 15, 12);
9745                 n = Bits32 (opcode, 19, 16);
9746                 imm32 = Bits32 (opcode, 7, 0) << 2;
9747 
9748                 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
9749                 if (BadReg (d) || BadReg (t) || (n == 15))
9750                   return false;
9751 
9752                 // if d == n || d == t then UNPREDICTABLE;
9753                 if ((d == n) || (d == t))
9754                   return false;
9755 
9756                 break;
9757 
9758             case eEncodingA1:
9759                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset
9760                 d = Bits32 (opcode, 15, 12);
9761                 t = Bits32 (opcode, 3, 0);
9762                 n = Bits32 (opcode, 19, 16);
9763                 imm32 = 0;
9764 
9765                 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
9766                 if ((d == 15) || (t == 15) || (n == 15))
9767                     return false;
9768 
9769                 // if d == n || d == t then UNPREDICTABLE;
9770                 if ((d == n) || (d == t))
9771                     return false;
9772 
9773                 break;
9774 
9775             default:
9776                 return false;
9777         }
9778 
9779         // address = R[n] + imm32;
9780         uint32_t Rn = ReadCoreReg (n, &success);
9781         if (!success)
9782             return false;
9783 
9784         addr_t address = Rn + imm32;
9785 
9786         RegisterInfo base_reg;
9787         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9788         RegisterInfo data_reg;
9789         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9790         EmulateInstruction::Context context;
9791         context.type = eContextRegisterStore;
9792         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32);
9793 
9794         // if ExclusiveMonitorsPass(address,4) then
9795         // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this
9796         //                                                         always return true.
9797         if (true)
9798         {
9799             // MemA[address,4] = R[t];
9800             uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
9801             if (!success)
9802                 return false;
9803 
9804             if (!MemAWrite (context, address, Rt, addr_byte_size))
9805                 return false;
9806 
9807             // R[d] = 0;
9808             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0))
9809                 return false;
9810         }
9811         else
9812         {
9813             // R[d] = 1;
9814             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
9815                 return false;
9816         }
9817     }
9818     return true;
9819 }
9820 
9821 // A8.6.197 STRB (immediate, ARM)
9822 bool
9823 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9824 {
9825 #if 0
9826     if ConditionPassed() then
9827         EncodingSpecificOperations();
9828         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9829         address = if index then offset_addr else R[n];
9830         MemU[address,1] = R[t]<7:0>;
9831         if wback then R[n] = offset_addr;
9832 #endif
9833 
9834     bool success = false;
9835 
9836     if (ConditionPassed(opcode))
9837     {
9838         uint32_t t;
9839         uint32_t n;
9840         uint32_t imm32;
9841         bool index;
9842         bool add;
9843         bool wback;
9844 
9845         switch (encoding)
9846         {
9847             case eEncodingA1:
9848                 // if P == �0� && W == �1� then SEE STRBT;
9849                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9850                 t = Bits32 (opcode, 15, 12);
9851                 n = Bits32 (opcode, 19, 16);
9852                 imm32 = Bits32 (opcode, 11, 0);
9853 
9854                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9855                 index = BitIsSet (opcode, 24);
9856                 add = BitIsSet (opcode, 23);
9857                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9858 
9859                 // if t == 15 then UNPREDICTABLE;
9860                 if (t == 15)
9861                     return false;
9862 
9863                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9864                 if (wback && ((n == 15) || (n == t)))
9865                     return false;
9866 
9867                 break;
9868 
9869             default:
9870                 return false;
9871         }
9872 
9873         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9874         uint32_t Rn = ReadCoreReg (n, &success);
9875         if (!success)
9876             return false;
9877 
9878         addr_t offset_addr;
9879         if (add)
9880             offset_addr = Rn + imm32;
9881         else
9882             offset_addr = Rn - imm32;
9883 
9884         // address = if index then offset_addr else R[n];
9885         addr_t address;
9886         if (index)
9887             address = offset_addr;
9888         else
9889             address = Rn;
9890 
9891         // MemU[address,1] = R[t]<7:0>;
9892         uint32_t Rt = ReadCoreReg (t, &success);
9893         if (!success)
9894             return false;
9895 
9896         RegisterInfo base_reg;
9897         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9898         RegisterInfo data_reg;
9899         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9900         EmulateInstruction::Context context;
9901         context.type = eContextRegisterStore;
9902         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
9903 
9904         if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1))
9905             return false;
9906 
9907         // if wback then R[n] = offset_addr;
9908         if (wback)
9909         {
9910             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
9911                 return false;
9912         }
9913     }
9914     return true;
9915 }
9916 
9917 // A8.6.194 STR (immediate, ARM)
9918 bool
9919 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding)
9920 {
9921 #if 0
9922     if ConditionPassed() then
9923         EncodingSpecificOperations();
9924         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9925         address = if index then offset_addr else R[n];
9926         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
9927         if wback then R[n] = offset_addr;
9928 #endif
9929 
9930     bool success = false;
9931 
9932     if (ConditionPassed(opcode))
9933     {
9934         uint32_t t;
9935         uint32_t n;
9936         uint32_t imm32;
9937         bool index;
9938         bool add;
9939         bool wback;
9940 
9941         const uint32_t addr_byte_size = GetAddressByteSize();
9942 
9943         switch (encoding)
9944         {
9945             case eEncodingA1:
9946                 // if P == �0� && W == �1� then SEE STRT;
9947                 // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH;
9948                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9949                 t = Bits32 (opcode, 15, 12);
9950                 n = Bits32 (opcode, 19, 16);
9951                 imm32 = Bits32 (opcode, 11, 0);
9952 
9953                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9954                 index = BitIsSet (opcode, 24);
9955                 add = BitIsSet (opcode, 23);
9956                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9957 
9958                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9959                 if (wback && ((n == 15) || (n == t)))
9960                     return false;
9961 
9962                 break;
9963 
9964             default:
9965                 return false;
9966         }
9967 
9968         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9969         uint32_t Rn = ReadCoreReg (n, &success);
9970         if (!success)
9971             return false;
9972 
9973         addr_t offset_addr;
9974         if (add)
9975             offset_addr = Rn + imm32;
9976         else
9977             offset_addr = Rn - imm32;
9978 
9979         // address = if index then offset_addr else R[n];
9980         addr_t address;
9981         if (index)
9982             address = offset_addr;
9983         else
9984             address = Rn;
9985 
9986         RegisterInfo base_reg;
9987         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9988         RegisterInfo data_reg;
9989         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9990         EmulateInstruction::Context context;
9991         context.type = eContextRegisterStore;
9992         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
9993 
9994         // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
9995         uint32_t Rt = ReadCoreReg (t, &success);
9996         if (!success)
9997             return false;
9998 
9999         if (t == 15)
10000         {
10001             uint32_t pc_value = ReadCoreReg (PC_REG, &success);
10002             if (!success)
10003                 return false;
10004 
10005             if (!MemUWrite (context, address, pc_value, addr_byte_size))
10006                 return false;
10007         }
10008         else
10009         {
10010             if (!MemUWrite (context, address, Rt, addr_byte_size))
10011                   return false;
10012         }
10013 
10014         // if wback then R[n] = offset_addr;
10015         if (wback)
10016         {
10017             context.type = eContextAdjustBaseRegister;
10018             context.SetImmediate (offset_addr);
10019 
10020             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10021                 return false;
10022         }
10023     }
10024     return true;
10025 }
10026 
10027 // A8.6.66 LDRD (immediate)
10028 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two
10029 // words from memory, and writes them to two registers.  It can use offset, post-indexed, or pre-indexed addressing.
10030 bool
10031 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding)
10032 {
10033 #if 0
10034     if ConditionPassed() then
10035         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10036         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10037         address = if index then offset_addr else R[n];
10038         R[t] = MemA[address,4];
10039         R[t2] = MemA[address+4,4];
10040         if wback then R[n] = offset_addr;
10041 #endif
10042 
10043     bool success = false;
10044 
10045     if (ConditionPassed(opcode))
10046     {
10047         uint32_t t;
10048         uint32_t t2;
10049         uint32_t n;
10050         uint32_t imm32;
10051         bool index;
10052         bool add;
10053         bool wback;
10054 
10055         switch (encoding)
10056         {
10057             case eEncodingT1:
10058                 //if P == �0� && W == �0� then SEE �Related encodings�;
10059                 //if Rn == �1111� then SEE LDRD (literal);
10060                 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10061                 t = Bits32 (opcode, 15, 12);
10062                 t2 = Bits32 (opcode, 11, 8);
10063                 n = Bits32 (opcode, 19, 16);
10064                 imm32 = Bits32 (opcode, 7, 0) << 2;
10065 
10066                 //index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10067                 index = BitIsSet (opcode, 24);
10068                 add = BitIsSet (opcode, 23);
10069                 wback = BitIsSet (opcode, 21);
10070 
10071                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10072                 if (wback && ((n == t) || (n == t2)))
10073                     return false;
10074 
10075                 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10076                 if (BadReg (t) || BadReg (t2) || (t == t2))
10077                     return false;
10078 
10079                 break;
10080 
10081             case eEncodingA1:
10082                 //if Rn == �1111� then SEE LDRD (literal);
10083                 //if Rt<0> == �1� then UNPREDICTABLE;
10084                 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10085                 t = Bits32 (opcode, 15, 12);
10086                 if (BitIsSet (t, 0))
10087                     return false;
10088                 t2 = t + 1;
10089                 n = Bits32 (opcode, 19, 16);
10090                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10091 
10092                 //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10093                 index = BitIsSet (opcode, 24);
10094                 add = BitIsSet (opcode, 23);
10095                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10096 
10097                 //if P == �0� && W == �1� then UNPREDICTABLE;
10098                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10099                     return false;
10100 
10101                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10102                 if (wback && ((n == t) || (n == t2)))
10103                     return false;
10104 
10105                 //if t2 == 15 then UNPREDICTABLE;
10106                 if (t2 == 15)
10107                     return false;
10108 
10109                 break;
10110 
10111             default:
10112                 return false;
10113         }
10114 
10115         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10116         uint32_t Rn = ReadCoreReg (n, &success);
10117         if (!success)
10118             return false;
10119 
10120         addr_t offset_addr;
10121         if (add)
10122                   offset_addr = Rn + imm32;
10123         else
10124             offset_addr = Rn - imm32;
10125 
10126         //address = if index then offset_addr else R[n];
10127         addr_t address;
10128         if (index)
10129             address = offset_addr;
10130         else
10131             address = Rn;
10132 
10133         //R[t] = MemA[address,4];
10134         RegisterInfo base_reg;
10135         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10136 
10137         EmulateInstruction::Context context;
10138         context.type = eContextRegisterLoad;
10139         context.SetRegisterPlusOffset (base_reg, address - Rn);
10140 
10141         const uint32_t addr_byte_size = GetAddressByteSize();
10142         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10143         if (!success)
10144             return false;
10145 
10146         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10147             return false;
10148 
10149         //R[t2] = MemA[address+4,4];
10150 
10151         context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10152         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10153         if (!success)
10154             return false;
10155 
10156         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10157             return false;
10158 
10159         //if wback then R[n] = offset_addr;
10160         if (wback)
10161         {
10162             context.type = eContextAdjustBaseRegister;
10163             context.SetAddress (offset_addr);
10164 
10165             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10166                 return false;
10167         }
10168     }
10169     return true;
10170 }
10171 
10172 // A8.6.68 LDRD (register)
10173 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two
10174 // words from memory, and writes them to two registers.  It can use offset, post-indexed or pre-indexed addressing.
10175 bool
10176 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding)
10177 {
10178 #if 0
10179     if ConditionPassed() then
10180         EncodingSpecificOperations();
10181         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10182         address = if index then offset_addr else R[n];
10183         R[t] = MemA[address,4];
10184         R[t2] = MemA[address+4,4];
10185         if wback then R[n] = offset_addr;
10186 #endif
10187 
10188     bool success = false;
10189 
10190     if (ConditionPassed(opcode))
10191     {
10192         uint32_t t;
10193         uint32_t t2;
10194         uint32_t n;
10195         uint32_t m;
10196         bool index;
10197         bool add;
10198         bool wback;
10199 
10200         switch (encoding)
10201         {
10202             case eEncodingA1:
10203                 // if Rt<0> == �1� then UNPREDICTABLE;
10204                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10205                 t = Bits32 (opcode, 15, 12);
10206                 if (BitIsSet (t, 0))
10207                     return false;
10208                 t2 = t + 1;
10209                 n = Bits32 (opcode, 19, 16);
10210                 m = Bits32 (opcode, 3, 0);
10211 
10212                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10213                 index = BitIsSet (opcode, 24);
10214                 add = BitIsSet (opcode, 23);
10215                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10216 
10217                 // if P == �0� && W == �1� then UNPREDICTABLE;
10218                   if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10219                   return false;
10220 
10221                 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10222                   if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10223                   return false;
10224 
10225                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10226                   if (wback && ((n == 15) || (n == t) || (n == t2)))
10227                   return false;
10228 
10229                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10230                 if ((ArchVersion() < 6) && wback && (m == n))
10231                   return false;
10232                 break;
10233 
10234             default:
10235                 return false;
10236         }
10237 
10238         uint32_t Rn = ReadCoreReg (n, &success);
10239         if (!success)
10240             return false;
10241         RegisterInfo base_reg;
10242         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10243 
10244         uint32_t Rm = ReadCoreReg (m, &success);
10245         if (!success)
10246             return false;
10247         RegisterInfo offset_reg;
10248         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10249 
10250         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10251         addr_t offset_addr;
10252         if (add)
10253             offset_addr = Rn + Rm;
10254         else
10255             offset_addr = Rn - Rm;
10256 
10257         // address = if index then offset_addr else R[n];
10258         addr_t address;
10259         if (index)
10260             address = offset_addr;
10261         else
10262             address = Rn;
10263 
10264         EmulateInstruction::Context context;
10265         context.type = eContextRegisterLoad;
10266         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
10267 
10268         // R[t] = MemA[address,4];
10269         const uint32_t addr_byte_size = GetAddressByteSize();
10270         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10271         if (!success)
10272             return false;
10273 
10274         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10275             return false;
10276 
10277         // R[t2] = MemA[address+4,4];
10278 
10279         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10280         if (!success)
10281             return false;
10282 
10283         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10284             return false;
10285 
10286         // if wback then R[n] = offset_addr;
10287         if (wback)
10288         {
10289             context.type = eContextAdjustBaseRegister;
10290             context.SetAddress (offset_addr);
10291 
10292             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10293                 return false;
10294         }
10295     }
10296     return true;
10297 }
10298 
10299 // A8.6.200 STRD (immediate)
10300 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and
10301 // stores two words from two registers to memory.  It can use offset, post-indexed, or pre-indexed addressing.
10302 bool
10303 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding)
10304 {
10305 #if 0
10306     if ConditionPassed() then
10307         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10308         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10309         address = if index then offset_addr else R[n];
10310         MemA[address,4] = R[t];
10311         MemA[address+4,4] = R[t2];
10312         if wback then R[n] = offset_addr;
10313 #endif
10314 
10315     bool success = false;
10316 
10317     if (ConditionPassed(opcode))
10318     {
10319         uint32_t t;
10320         uint32_t t2;
10321         uint32_t n;
10322         uint32_t imm32;
10323         bool index;
10324         bool add;
10325         bool wback;
10326 
10327         switch (encoding)
10328         {
10329             case eEncodingT1:
10330                 // if P == �0� && W == �0� then SEE �Related encodings�;
10331                 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10332                 t = Bits32 (opcode, 15, 12);
10333                 t2 = Bits32 (opcode, 11, 8);
10334                 n = Bits32 (opcode, 19, 16);
10335                 imm32 = Bits32 (opcode, 7, 0) << 2;
10336 
10337                 // index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10338                 index = BitIsSet (opcode, 24);
10339                 add = BitIsSet (opcode, 23);
10340                 wback = BitIsSet (opcode, 21);
10341 
10342                 // if wback && (n == t || n == t2) then UNPREDICTABLE;
10343                 if (wback && ((n == t) || (n == t2)))
10344                     return false;
10345 
10346                 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10347                 if ((n == 15) || BadReg (t) || BadReg (t2))
10348                     return false;
10349 
10350                 break;
10351 
10352             case eEncodingA1:
10353                 // if Rt<0> == �1� then UNPREDICTABLE;
10354                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10355                 t = Bits32 (opcode, 15, 12);
10356                 if (BitIsSet (t, 0))
10357                     return false;
10358 
10359                 t2 = t + 1;
10360                 n = Bits32 (opcode, 19, 16);
10361                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10362 
10363                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10364                 index = BitIsSet (opcode, 24);
10365                 add = BitIsSet (opcode, 23);
10366                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10367 
10368                 // if P == �0� && W == �1� then UNPREDICTABLE;
10369                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10370                     return false;
10371 
10372                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10373                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10374                     return false;
10375 
10376                 // if t2 == 15 then UNPREDICTABLE;
10377                 if (t2 == 15)
10378                     return false;
10379 
10380                 break;
10381 
10382             default:
10383                 return false;
10384         }
10385 
10386         RegisterInfo base_reg;
10387         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10388 
10389         uint32_t Rn = ReadCoreReg (n, &success);
10390         if (!success)
10391             return false;
10392 
10393         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10394         addr_t offset_addr;
10395         if (add)
10396             offset_addr = Rn + imm32;
10397         else
10398             offset_addr = Rn - imm32;
10399 
10400         //address = if index then offset_addr else R[n];
10401         addr_t address;
10402         if (index)
10403             address = offset_addr;
10404         else
10405             address = Rn;
10406 
10407         //MemA[address,4] = R[t];
10408         RegisterInfo data_reg;
10409         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10410 
10411         uint32_t data = ReadCoreReg (t, &success);
10412         if (!success)
10413             return false;
10414 
10415         EmulateInstruction::Context context;
10416         context.type = eContextRegisterStore;
10417         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10418 
10419         const uint32_t addr_byte_size = GetAddressByteSize();
10420 
10421         if (!MemAWrite (context, address, data, addr_byte_size))
10422             return false;
10423 
10424         //MemA[address+4,4] = R[t2];
10425         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10426         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10427 
10428         data = ReadCoreReg (t2, &success);
10429         if (!success)
10430             return false;
10431 
10432         if (!MemAWrite (context, address + 4, data, addr_byte_size))
10433             return false;
10434 
10435         //if wback then R[n] = offset_addr;
10436         if (wback)
10437         {
10438             context.type = eContextAdjustBaseRegister;
10439             context.SetAddress (offset_addr);
10440 
10441             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10442                 return false;
10443         }
10444     }
10445     return true;
10446 }
10447 
10448 
10449 // A8.6.201 STRD (register)
10450 bool
10451 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding)
10452 {
10453 #if 0
10454     if ConditionPassed() then
10455         EncodingSpecificOperations();
10456         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10457         address = if index then offset_addr else R[n];
10458         MemA[address,4] = R[t];
10459         MemA[address+4,4] = R[t2];
10460         if wback then R[n] = offset_addr;
10461 #endif
10462 
10463     bool success = false;
10464 
10465     if (ConditionPassed(opcode))
10466     {
10467         uint32_t t;
10468         uint32_t t2;
10469         uint32_t n;
10470         uint32_t m;
10471         bool index;
10472         bool add;
10473         bool wback;
10474 
10475         switch (encoding)
10476         {
10477             case eEncodingA1:
10478                 // if Rt<0> == �1� then UNPREDICTABLE;
10479                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10480                 t = Bits32 (opcode, 15, 12);
10481                 if (BitIsSet (t, 0))
10482                    return false;
10483 
10484                 t2 = t+1;
10485                 n = Bits32 (opcode, 19, 16);
10486                 m = Bits32 (opcode, 3, 0);
10487 
10488                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10489                 index = BitIsSet (opcode, 24);
10490                 add = BitIsSet (opcode, 23);
10491                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10492 
10493                 // if P == �0� && W == �1� then UNPREDICTABLE;
10494                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10495                    return false;
10496 
10497                 // if t2 == 15 || m == 15 then UNPREDICTABLE;
10498                 if ((t2 == 15) || (m == 15))
10499                    return false;
10500 
10501                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10502                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10503                    return false;
10504 
10505                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10506                 if ((ArchVersion() < 6) && wback && (m == n))
10507                    return false;
10508 
10509                 break;
10510 
10511             default:
10512                 return false;
10513         }
10514 
10515         RegisterInfo base_reg;
10516         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10517         RegisterInfo offset_reg;
10518         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10519         RegisterInfo data_reg;
10520 
10521         uint32_t Rn = ReadCoreReg (n, &success);
10522         if (!success)
10523             return false;
10524 
10525         uint32_t Rm = ReadCoreReg (m, &success);
10526         if (!success)
10527             return false;
10528 
10529         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10530         addr_t offset_addr;
10531         if (add)
10532             offset_addr = Rn + Rm;
10533         else
10534             offset_addr = Rn - Rm;
10535 
10536         // address = if index then offset_addr else R[n];
10537         addr_t address;
10538         if (index)
10539             address = offset_addr;
10540         else
10541             address = Rn;
10542                           // MemA[address,4] = R[t];
10543         uint32_t Rt = ReadCoreReg (t, &success);
10544         if (!success)
10545             return false;
10546 
10547         EmulateInstruction::Context context;
10548         context.type = eContextRegisterStore;
10549         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10550         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10551 
10552         const uint32_t addr_byte_size = GetAddressByteSize();
10553 
10554         if (!MemAWrite (context, address, Rt, addr_byte_size))
10555             return false;
10556 
10557         // MemA[address+4,4] = R[t2];
10558         uint32_t Rt2 = ReadCoreReg (t2, &success);
10559         if (!success)
10560             return false;
10561 
10562         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10563 
10564         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10565 
10566         if (!MemAWrite (context, address + 4, Rt2, addr_byte_size))
10567             return false;
10568 
10569         // if wback then R[n] = offset_addr;
10570         if (wback)
10571         {
10572             context.type = eContextAdjustBaseRegister;
10573             context.SetAddress (offset_addr);
10574 
10575             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10576                 return false;
10577 
10578         }
10579     }
10580     return true;
10581 }
10582 
10583 // A8.6.319 VLDM
10584 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from
10585 // an ARM core register.
10586 bool
10587 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding)
10588 {
10589 #if 0
10590     if ConditionPassed() then
10591         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10592         address = if add then R[n] else R[n]-imm32;
10593         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10594         for r = 0 to regs-1
10595             if single_regs then
10596                 S[d+r] = MemA[address,4]; address = address+4;
10597             else
10598                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10599                 // Combine the word-aligned words in the correct order for current endianness.
10600                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10601 #endif
10602 
10603     bool success = false;
10604 
10605     if (ConditionPassed(opcode))
10606     {
10607         bool single_regs;
10608         bool add;
10609         bool wback;
10610         uint32_t d;
10611         uint32_t n;
10612         uint32_t imm32;
10613         uint32_t regs;
10614 
10615         switch (encoding)
10616         {
10617             case eEncodingT1:
10618             case eEncodingA1:
10619                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10620                 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10621                 // if P == �1� && W == �0� then SEE VLDR;
10622                 // if P == U && W == �1� then UNDEFINED;
10623                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10624                     return false;
10625 
10626                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10627                 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10628                 single_regs = false;
10629                 add = BitIsSet (opcode, 23);
10630                 wback = BitIsSet (opcode, 21);
10631 
10632                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10633                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10634                 n = Bits32 (opcode, 19, 16);
10635                 imm32 = Bits32 (opcode, 7, 0) << 2;
10636 
10637                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�.
10638                 regs = Bits32 (opcode, 7, 0) / 2;
10639 
10640                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10641                 if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
10642                     return false;
10643 
10644                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10645                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10646                     return false;
10647 
10648                 break;
10649 
10650             case eEncodingT2:
10651             case eEncodingA2:
10652                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10653                 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10654                 // if P == �1� && W == �0� then SEE VLDR;
10655                 // if P == U && W == �1� then UNDEFINED;
10656                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10657                     return false;
10658 
10659                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10660                 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10661                 single_regs = true;
10662                 add = BitIsSet (opcode, 23);
10663                 wback = BitIsSet (opcode, 21);
10664                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10665                 n = Bits32 (opcode, 19, 16);
10666 
10667                 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10668                 imm32 = Bits32 (opcode, 7, 0) << 2;
10669                 regs = Bits32 (opcode, 7, 0);
10670 
10671                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10672                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10673                     return false;
10674 
10675                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10676                 if ((regs == 0) || ((d + regs) > 32))
10677                     return false;
10678                 break;
10679 
10680             default:
10681                 return false;
10682         }
10683 
10684         RegisterInfo base_reg;
10685         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10686 
10687         uint32_t Rn = ReadCoreReg (n, &success);
10688         if (!success)
10689             return false;
10690 
10691         // address = if add then R[n] else R[n]-imm32;
10692         addr_t address;
10693         if (add)
10694             address = Rn;
10695         else
10696             address = Rn - imm32;
10697 
10698         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10699         EmulateInstruction::Context context;
10700 
10701         if (wback)
10702         {
10703             uint32_t value;
10704             if (add)
10705                 value = Rn + imm32;
10706             else
10707                 value = Rn - imm32;
10708 
10709             context.type = eContextAdjustBaseRegister;
10710             context.SetImmediateSigned (value - Rn);
10711             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10712                 return false;
10713 
10714         }
10715 
10716         const uint32_t addr_byte_size = GetAddressByteSize();
10717         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10718 
10719         context.type = eContextRegisterLoad;
10720 
10721         // for r = 0 to regs-1
10722         for (uint32_t r = 0; r < regs; ++r)
10723         {
10724             if (single_regs)
10725             {
10726                 // S[d+r] = MemA[address,4]; address = address+4;
10727                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10728 
10729                 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10730                 if (!success)
10731                     return false;
10732 
10733                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10734                     return false;
10735 
10736                 address = address + 4;
10737             }
10738             else
10739             {
10740                 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10741                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10742                 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10743                 if (!success)
10744                     return false;
10745 
10746                 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10747                 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10748                 if (!success)
10749                     return false;
10750 
10751                 address = address + 8;
10752                 // // Combine the word-aligned words in the correct order for current endianness.
10753                 // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10754                 uint64_t data;
10755                 if (GetByteOrder() == eByteOrderBig)
10756                 {
10757                     data = word1;
10758                     data = (data << 32) | word2;
10759                 }
10760                 else
10761                 {
10762                     data = word2;
10763                     data = (data << 32) | word1;
10764                 }
10765 
10766                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10767                     return false;
10768             }
10769         }
10770     }
10771     return true;
10772 }
10773 
10774 // A8.6.399 VSTM
10775 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an
10776 // ARM core register.
10777 bool
10778 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding)
10779 {
10780 #if 0
10781     if ConditionPassed() then
10782         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10783         address = if add then R[n] else R[n]-imm32;
10784         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10785         for r = 0 to regs-1
10786             if single_regs then
10787                 MemA[address,4] = S[d+r]; address = address+4;
10788             else
10789                 // Store as two word-aligned words in the correct order for current endianness.
10790                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10791                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10792                 address = address+8;
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 == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10813                 // if P == �1� && W == �0� then SEE VSTR;
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 �FSTMX�.
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 == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10846                 // if P == �1� && W == �0� then SEE VSTR;
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 
10871                 break;
10872 
10873             default:
10874                 return false;
10875         }
10876 
10877         RegisterInfo base_reg;
10878         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10879 
10880         uint32_t Rn = ReadCoreReg (n, &success);
10881         if (!success)
10882             return false;
10883 
10884         // address = if add then R[n] else R[n]-imm32;
10885         addr_t address;
10886         if (add)
10887             address = Rn;
10888         else
10889             address = Rn - imm32;
10890 
10891         EmulateInstruction::Context context;
10892         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
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.SetRegisterPlusOffset (base_reg, value - Rn);
10903 
10904             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10905                 return false;
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 = eContextRegisterStore;
10912         // for r = 0 to regs-1
10913         for (int r = 0; r < regs; ++r)
10914         {
10915 
10916             if (single_regs)
10917             {
10918                 // MemA[address,4] = S[d+r]; address = address+4;
10919                 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10920                 if (!success)
10921                     return false;
10922 
10923                 RegisterInfo data_reg;
10924                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
10925                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10926                 if (!MemAWrite (context, address, data, addr_byte_size))
10927                     return false;
10928 
10929                 address = address + 4;
10930             }
10931             else
10932             {
10933                 // // Store as two word-aligned words in the correct order for current endianness.
10934                 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10935                 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10936                 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10937                 if (!success)
10938                     return false;
10939 
10940                 RegisterInfo data_reg;
10941                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
10942 
10943                 if (GetByteOrder() == eByteOrderBig)
10944                 {
10945                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10946                     if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
10947                         return false;
10948 
10949                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10950                     if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size))
10951                         return false;
10952                 }
10953                 else
10954                 {
10955                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10956                     if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
10957                         return false;
10958 
10959                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10960                     if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
10961                         return false;
10962                 }
10963                 // address = address+8;
10964                 address = address + 8;
10965             }
10966         }
10967     }
10968     return true;
10969 }
10970 
10971 // A8.6.320
10972 // This instruciton loads a single extension register fronm memory, using an address from an ARM core register, with
10973 // an optional offset.
10974 bool
10975 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
10976 {
10977 #if 0
10978     if ConditionPassed() then
10979         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10980         base = if n == 15 then Align(PC,4) else R[n];
10981         address = if add then (base + imm32) else (base - imm32);
10982         if single_reg then
10983             S[d] = MemA[address,4];
10984         else
10985             word1 = MemA[address,4]; word2 = MemA[address+4,4];
10986             // Combine the word-aligned words in the correct order for current endianness.
10987             D[d] = if BigEndian() then word1:word2 else word2:word1;
10988 #endif
10989 
10990     bool success = false;
10991 
10992     if (ConditionPassed (opcode))
10993     {
10994         bool single_reg;
10995         bool add;
10996         uint32_t imm32;
10997         uint32_t d;
10998         uint32_t n;
10999 
11000         switch (encoding)
11001         {
11002             case eEncodingT1:
11003             case eEncodingA1:
11004                 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11005                 single_reg = false;
11006                 add = BitIsSet (opcode, 23);
11007                 imm32 = Bits32 (opcode, 7, 0) << 2;
11008 
11009                 // d = UInt(D:Vd); n = UInt(Rn);
11010                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11011                 n = Bits32 (opcode, 19, 16);
11012 
11013                 break;
11014 
11015             case eEncodingT2:
11016             case eEncodingA2:
11017                 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11018                 single_reg = true;
11019                 add = BitIsSet (opcode, 23);
11020                 imm32 = Bits32 (opcode, 7, 0) << 2;
11021 
11022                 // d = UInt(Vd:D); n = UInt(Rn);
11023                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11024                 n = Bits32 (opcode, 19, 16);
11025 
11026                 break;
11027 
11028             default:
11029                 return false;
11030         }
11031         RegisterInfo base_reg;
11032         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11033 
11034         uint32_t Rn = ReadCoreReg (n, &success);
11035         if (!success)
11036             return false;
11037 
11038         // base = if n == 15 then Align(PC,4) else R[n];
11039         uint32_t base;
11040         if (n == 15)
11041             base = AlignPC (Rn);
11042         else
11043             base = Rn;
11044 
11045         // address = if add then (base + imm32) else (base - imm32);
11046         addr_t address;
11047         if (add)
11048             address = base + imm32;
11049         else
11050             address = base - imm32;
11051 
11052         const uint32_t addr_byte_size = GetAddressByteSize();
11053         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11054 
11055         EmulateInstruction::Context context;
11056         context.type = eContextRegisterLoad;
11057         context.SetRegisterPlusOffset (base_reg, address - base);
11058 
11059         if (single_reg)
11060         {
11061             // S[d] = MemA[address,4];
11062             uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
11063             if (!success)
11064                 return false;
11065 
11066             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data))
11067                 return false;
11068         }
11069         else
11070         {
11071             // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11072             uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
11073             if (!success)
11074                 return false;
11075 
11076             context.SetRegisterPlusOffset (base_reg, (address + 4) - base);
11077             uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
11078             if (!success)
11079                 return false;
11080             // // Combine the word-aligned words in the correct order for current endianness.
11081             // D[d] = if BigEndian() then word1:word2 else word2:word1;
11082             uint64_t data64;
11083             if (GetByteOrder() == eByteOrderBig)
11084             {
11085                 data64 = word1;
11086                 data64 = (data64 << 32) | word2;
11087             }
11088             else
11089             {
11090                 data64 = word2;
11091                 data64 = (data64 << 32) | word1;
11092             }
11093 
11094             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64))
11095                 return false;
11096         }
11097     }
11098     return true;
11099 }
11100 
11101 // A8.6.400 VSTR
11102 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an
11103 // optional offset.
11104 bool
11105 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
11106 {
11107 #if 0
11108     if ConditionPassed() then
11109         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11110         address = if add then (R[n] + imm32) else (R[n] - imm32);
11111         if single_reg then
11112             MemA[address,4] = S[d];
11113         else
11114             // Store as two word-aligned words in the correct order for current endianness.
11115             MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11116             MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11117 #endif
11118 
11119     bool success = false;
11120 
11121     if (ConditionPassed (opcode))
11122     {
11123         bool single_reg;
11124         bool add;
11125         uint32_t imm32;
11126         uint32_t d;
11127         uint32_t n;
11128 
11129         switch (encoding)
11130         {
11131             case eEncodingT1:
11132             case eEncodingA1:
11133                 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11134                 single_reg = false;
11135                 add = BitIsSet (opcode, 23);
11136                 imm32 = Bits32 (opcode, 7, 0) << 2;
11137 
11138                 // d = UInt(D:Vd); n = UInt(Rn);
11139                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11140                 n = Bits32 (opcode, 19, 16);
11141 
11142                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11143                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11144                     return false;
11145 
11146                 break;
11147 
11148             case eEncodingT2:
11149             case eEncodingA2:
11150                 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11151                 single_reg = true;
11152                 add = BitIsSet (opcode, 23);
11153                 imm32 = Bits32 (opcode, 7, 0) << 2;
11154 
11155                 // d = UInt(Vd:D); n = UInt(Rn);
11156                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11157                 n = Bits32 (opcode, 19, 16);
11158 
11159                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11160                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11161                     return false;
11162 
11163                 break;
11164 
11165             default:
11166                 return false;
11167         }
11168 
11169         RegisterInfo base_reg;
11170         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11171 
11172         uint32_t Rn = ReadCoreReg (n, &success);
11173         if (!success)
11174             return false;
11175 
11176         // address = if add then (R[n] + imm32) else (R[n] - imm32);
11177         addr_t address;
11178         if (add)
11179             address = Rn + imm32;
11180         else
11181             address = Rn - imm32;
11182 
11183         const uint32_t addr_byte_size = GetAddressByteSize();
11184         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11185 
11186         RegisterInfo data_reg;
11187         GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg);
11188         EmulateInstruction::Context context;
11189         context.type = eContextRegisterStore;
11190         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11191 
11192         if (single_reg)
11193         {
11194             // MemA[address,4] = S[d];
11195             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11196             if (!success)
11197                 return false;
11198 
11199             if (!MemAWrite (context, address, data, addr_byte_size))
11200                 return false;
11201         }
11202         else
11203         {
11204             // // Store as two word-aligned words in the correct order for current endianness.
11205             // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11206             // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11207             uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11208             if (!success)
11209                 return false;
11210 
11211             if (GetByteOrder() == eByteOrderBig)
11212             {
11213                 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11214                     return false;
11215 
11216                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11217                 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size))
11218                     return false;
11219             }
11220             else
11221             {
11222                 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11223                     return false;
11224 
11225                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11226                 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11227                     return false;
11228             }
11229         }
11230     }
11231     return true;
11232 }
11233 
11234 // A8.6.307 VLDI1 (multiple single elements)
11235 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving.  Every
11236 // element of each register is loaded.
11237 bool
11238 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding)
11239 {
11240 #if 0
11241     if ConditionPassed() then
11242         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11243         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11244         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11245         for r = 0 to regs-1
11246             for e = 0 to elements-1
11247                 Elem[D[d+r],e,esize] = MemU[address,ebytes];
11248                 address = address + ebytes;
11249 #endif
11250 
11251     bool success = false;
11252 
11253     if (ConditionPassed (opcode))
11254     {
11255         uint32_t regs;
11256         uint32_t alignment;
11257         uint32_t ebytes;
11258         uint32_t esize;
11259         uint32_t elements;
11260         uint32_t d;
11261         uint32_t n;
11262         uint32_t m;
11263         bool wback;
11264         bool register_index;
11265 
11266         switch (encoding)
11267         {
11268             case eEncodingT1:
11269             case eEncodingA1:
11270             {
11271                 // case type of
11272                     // when �0111�
11273                         // regs = 1; if align<1> == �1� then UNDEFINED;
11274                     // when �1010�
11275                         // regs = 2; if align == �11� then UNDEFINED;
11276                     // when �0110�
11277                         // regs = 3; if align<1> == �1� then UNDEFINED;
11278                     // when �0010�
11279                         // regs = 4;
11280                     // otherwise
11281                         // SEE �Related encodings�;
11282                 uint32_t type = Bits32 (opcode, 11, 8);
11283                 uint32_t align = Bits32 (opcode, 5, 4);
11284                 if (type == 7) // '0111'
11285                 {
11286                     regs = 1;
11287                     if (BitIsSet (align, 1))
11288                         return false;
11289                 }
11290                 else if (type == 10) // '1010'
11291                 {
11292                     regs = 2;
11293                     if (align == 3)
11294                         return false;
11295 
11296                 }
11297                 else if (type == 6) // '0110'
11298                 {
11299                     regs = 3;
11300                     if (BitIsSet (align, 1))
11301                         return false;
11302                 }
11303                 else if (type == 2) // '0010'
11304                 {
11305                     regs = 4;
11306                 }
11307                 else
11308                     return false;
11309 
11310                 // alignment = if align == �00� then 1 else 4 << UInt(align);
11311                 if (align == 0)
11312                     alignment = 1;
11313                 else
11314                     alignment = 4 << align;
11315 
11316                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11317                 ebytes = 1 << Bits32 (opcode, 7, 6);
11318                 esize = 8 * ebytes;
11319                 elements = 8 / ebytes;
11320 
11321                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11322                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11323                 n = Bits32 (opcode, 19, 15);
11324                 m = Bits32 (opcode, 3, 0);
11325 
11326                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11327                 wback = (m != 15);
11328                 register_index = ((m != 15) && (m != 13));
11329 
11330                 // if d+regs > 32 then UNPREDICTABLE;
11331                 if ((d + regs) > 32)
11332                     return false;
11333             }
11334                 break;
11335 
11336             default:
11337                 return false;
11338         }
11339 
11340         RegisterInfo base_reg;
11341         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11342 
11343         uint32_t Rn = ReadCoreReg (n, &success);
11344         if (!success)
11345             return false;
11346 
11347         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11348         addr_t address = Rn;
11349         if ((address % alignment) != 0)
11350             return false;
11351 
11352         EmulateInstruction::Context context;
11353         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11354         if (wback)
11355         {
11356             uint32_t Rm = ReadCoreReg (m, &success);
11357             if (!success)
11358                 return false;
11359 
11360             uint32_t offset;
11361             if (register_index)
11362                 offset = Rm;
11363             else
11364                 offset = 8 * regs;
11365 
11366             uint32_t value = Rn + offset;
11367             context.type = eContextAdjustBaseRegister;
11368             context.SetRegisterPlusOffset (base_reg, offset);
11369 
11370             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11371                 return false;
11372 
11373         }
11374 
11375         // for r = 0 to regs-1
11376         for (int r = 0; r < regs; ++r)
11377         {
11378             // for e = 0 to elements-1
11379             uint64_t assembled_data = 0;
11380             for (int e = 0; e < elements; ++e)
11381             {
11382                 // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11383                 context.type = eContextRegisterLoad;
11384                 context.SetRegisterPlusOffset (base_reg, address - Rn);
11385                 uint64_t data = MemURead (context, address, ebytes, 0, &success);
11386                 if (!success)
11387                     return false;
11388 
11389                 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data
11390 
11391                 // address = address + ebytes;
11392                 address = address + ebytes;
11393             }
11394             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data))
11395                 return false;
11396         }
11397     }
11398     return true;
11399 }
11400 
11401 // A8.6.308 VLD1 (single element to one lane)
11402 //
11403 bool
11404 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding)
11405 {
11406 #if 0
11407     if ConditionPassed() then
11408         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11409         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11410         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11411         Elem[D[d],index,esize] = MemU[address,ebytes];
11412 #endif
11413 
11414     bool success = false;
11415 
11416     if (ConditionPassed (opcode))
11417     {
11418         uint32_t ebytes;
11419         uint32_t esize;
11420         uint32_t index;
11421         uint32_t alignment;
11422         uint32_t d;
11423         uint32_t n;
11424         uint32_t m;
11425         bool wback;
11426         bool register_index;
11427 
11428         switch (encoding)
11429         {
11430             case eEncodingT1:
11431             case eEncodingA1:
11432             {
11433                 uint32_t size = Bits32 (opcode, 11, 10);
11434                 uint32_t index_align = Bits32 (opcode, 7, 4);
11435                 // if size == �11� then SEE VLD1 (single element to all lanes);
11436                 if (size == 3)
11437                    return EmulateVLD1SingleAll (opcode, encoding);
11438                 // case size of
11439                 if (size == 0) // when '00'
11440                 {
11441                     // if index_align<0> != �0� then UNDEFINED;
11442                     if (BitIsClear (index_align, 0))
11443                         return false;
11444 
11445                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11446                     ebytes = 1;
11447                     esize = 8;
11448                     index = Bits32 (index_align, 3, 1);
11449                     alignment = 1;
11450                 }
11451                 else if (size == 1) // when �01�
11452                 {
11453                     // if index_align<1> != �0� then UNDEFINED;
11454                     if (BitIsClear (index_align, 1))
11455                         return false;
11456 
11457                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11458                     ebytes = 2;
11459                     esize = 16;
11460                     index = Bits32 (index_align, 3, 2);
11461 
11462                     // alignment = if index_align<0> == �0� then 1 else 2;
11463                     if (BitIsClear (index_align, 0))
11464                         alignment = 1;
11465                     else
11466                         alignment = 2;
11467                 }
11468                 else if (size == 2) // when �10�
11469                 {
11470                     // if index_align<2> != �0� then UNDEFINED;
11471                     if (BitIsClear (index_align, 2))
11472                         return false;
11473 
11474                     // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11475                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11476                         return false;
11477 
11478                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11479                     ebytes = 4;
11480                     esize = 32;
11481                     index = Bit32 (index_align, 3);
11482 
11483                     // alignment = if index_align<1:0> == �00� then 1 else 4;
11484                     if (Bits32 (index_align, 1, 0) == 0)
11485                         alignment = 1;
11486                     else
11487                         alignment = 4;
11488                 }
11489                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11490                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11491                 n = Bits32 (opcode, 19, 16);
11492                 m = Bits32 (opcode, 3, 0);
11493 
11494                 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
11495                 wback = (m != 15);
11496                 register_index = ((m != 15) && (m != 13));
11497 
11498                 if (n == 15)
11499                     return false;
11500 
11501             }
11502                 break;
11503 
11504             default:
11505                 return false;
11506         }
11507 
11508         RegisterInfo base_reg;
11509         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11510 
11511         uint32_t Rn = ReadCoreReg (n, &success);
11512         if (!success)
11513             return false;
11514 
11515         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11516         addr_t address = Rn;
11517         if ((address % alignment) != 0)
11518             return false;
11519 
11520         EmulateInstruction::Context context;
11521         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11522         if (wback)
11523         {
11524             uint32_t Rm = ReadCoreReg (m, &success);
11525             if (!success)
11526                 return false;
11527 
11528             uint32_t offset;
11529             if (register_index)
11530                 offset = Rm;
11531             else
11532                 offset = ebytes;
11533 
11534             uint32_t value = Rn + offset;
11535 
11536             context.type = eContextAdjustBaseRegister;
11537             context.SetRegisterPlusOffset (base_reg, offset);
11538 
11539             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11540                 return false;
11541         }
11542 
11543         // Elem[D[d],index,esize] = MemU[address,ebytes];
11544         uint32_t element = MemURead (context, address, esize, 0, &success);
11545         if (!success)
11546             return false;
11547 
11548         element = element << (index * esize);
11549 
11550         uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11551         if (!success)
11552             return false;
11553 
11554         uint64_t all_ones = -1;
11555         uint64_t mask = all_ones << ((index+1) * esize);  // mask is all 1's to left of where 'element' goes, & all 0's
11556                                                           // at element & to the right of element.
11557         if (index > 0)
11558             mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes.
11559                                                                      // now mask should be 0's where element goes & 1's
11560                                                                      // everywhere else.
11561 
11562         uint64_t masked_reg = reg_data & mask;  // Take original reg value & zero out 'element' bits
11563         reg_data = masked_reg & element;        // Put 'element' into those bits in reg_data.
11564 
11565         context.type = eContextRegisterLoad;
11566         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data))
11567             return false;
11568     }
11569     return true;
11570 }
11571 
11572 // A8.6.391 VST1 (multiple single elements)
11573 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four regsiters, without
11574 // interleaving.  Every element of each register is stored.
11575 bool
11576 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding)
11577 {
11578 #if 0
11579     if ConditionPassed() then
11580         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11581         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11582         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11583         for r = 0 to regs-1
11584             for e = 0 to elements-1
11585                 MemU[address,ebytes] = Elem[D[d+r],e,esize];
11586                 address = address + ebytes;
11587 #endif
11588 
11589     bool success = false;
11590 
11591     if (ConditionPassed (opcode))
11592     {
11593         uint32_t regs;
11594         uint32_t alignment;
11595         uint32_t ebytes;
11596         uint32_t esize;
11597         uint32_t elements;
11598         uint32_t d;
11599         uint32_t n;
11600         uint32_t m;
11601         bool wback;
11602         bool register_index;
11603 
11604         switch (encoding)
11605         {
11606             case eEncodingT1:
11607             case eEncodingA1:
11608             {
11609                 uint32_t type = Bits32 (opcode, 11, 8);
11610                 uint32_t align = Bits32 (opcode, 5, 4);
11611 
11612                 // case type of
11613                 if (type == 7)    // when �0111�
11614                 {
11615                     // regs = 1; if align<1> == �1� then UNDEFINED;
11616                     regs = 1;
11617                     if (BitIsSet (align, 1))
11618                         return false;
11619                 }
11620                 else if (type == 10) // when �1010�
11621                 {
11622                     // regs = 2; if align == �11� then UNDEFINED;
11623                     regs = 2;
11624                     if (align == 3)
11625                         return false;
11626                 }
11627                 else if (type == 6) // when �0110�
11628                 {
11629                     // regs = 3; if align<1> == �1� then UNDEFINED;
11630                     regs = 3;
11631                     if (BitIsSet (align, 1))
11632                         return false;
11633                 }
11634                 else if (type == 2) // when �0010�
11635                     // regs = 4;
11636                     regs = 4;
11637                 else // otherwise
11638                     // SEE �Related encodings�;
11639                     return false;
11640 
11641                 // alignment = if align == �00� then 1 else 4 << UInt(align);
11642                 if (align == 0)
11643                     alignment = 1;
11644                 else
11645                     alignment = 4 << align;
11646 
11647                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11648                 ebytes = 1 << Bits32 (opcode,7, 6);
11649                 esize = 8 * ebytes;
11650                 elements = 8 / ebytes;
11651 
11652                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11653                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11654                 n = Bits32 (opcode, 19, 16);
11655                 m = Bits32 (opcode, 3, 0);
11656 
11657                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11658                 wback = (m != 15);
11659                 register_index = ((m != 15) && (m != 13));
11660 
11661                 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11662                 if ((d + regs) > 32)
11663                     return false;
11664 
11665                 if (n == 15)
11666                     return false;
11667 
11668             }
11669                 break;
11670 
11671             default:
11672                 return false;
11673         }
11674 
11675         RegisterInfo base_reg;
11676         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11677 
11678         uint32_t Rn = ReadCoreReg (n, &success);
11679         if (!success)
11680             return false;
11681 
11682         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11683         addr_t address = Rn;
11684         if ((address % alignment) != 0)
11685             return false;
11686 
11687         EmulateInstruction::Context context;
11688         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11689         if (wback)
11690         {
11691             uint32_t Rm = ReadCoreReg (m, &success);
11692             if (!success)
11693                 return false;
11694 
11695             uint32_t offset;
11696             if (register_index)
11697                 offset = Rm;
11698             else
11699                 offset = 8 * regs;
11700 
11701             context.type = eContextAdjustBaseRegister;
11702             context.SetRegisterPlusOffset (base_reg, offset);
11703 
11704             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11705                 return false;
11706         }
11707 
11708         RegisterInfo data_reg;
11709         context.type = eContextRegisterStore;
11710         // for r = 0 to regs-1
11711         for (int r = 0; r < regs; ++r)
11712         {
11713             GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
11714             uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
11715             if (!success)
11716                 return false;
11717 
11718              // for e = 0 to elements-1
11719             for (int e = 0; e < elements; ++e)
11720             {
11721                 // MemU[address,ebytes] = Elem[D[d+r],e,esize];
11722                 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize);
11723 
11724                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11725                 if (!MemUWrite (context, address, word, ebytes))
11726                     return false;
11727 
11728                 // address = address + ebytes;
11729                 address = address + ebytes;
11730             }
11731         }
11732     }
11733     return true;
11734 }
11735 
11736 // A8.6.392 VST1 (single element from one lane)
11737 // This instruction stores one element to memory from one element of a register.
11738 bool
11739 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding)
11740 {
11741 #if 0
11742     if ConditionPassed() then
11743         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11744         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11745         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11746         MemU[address,ebytes] = Elem[D[d],index,esize];
11747 #endif
11748 
11749     bool success = false;
11750 
11751     if (ConditionPassed (opcode))
11752     {
11753         uint32_t ebytes;
11754         uint32_t esize;
11755         uint32_t index;
11756         uint32_t alignment;
11757         uint32_t d;
11758         uint32_t n;
11759         uint32_t m;
11760         bool wback;
11761         bool register_index;
11762 
11763         switch (encoding)
11764         {
11765             case eEncodingT1:
11766             case eEncodingA1:
11767             {
11768                 uint32_t size = Bits32 (opcode, 11, 10);
11769                 uint32_t index_align = Bits32 (opcode, 7, 4);
11770 
11771                 // if size == �11� then UNDEFINED;
11772                 if (size == 3)
11773                     return false;
11774 
11775                 // case size of
11776                 if (size == 0) // when �00�
11777                 {
11778                     // if index_align<0> != �0� then UNDEFINED;
11779                     if (BitIsClear (index_align, 0))
11780                         return false;
11781                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11782                     ebytes = 1;
11783                     esize = 8;
11784                     index = Bits32 (index_align, 3, 1);
11785                     alignment = 1;
11786                 }
11787                 else if (size == 1) // when �01�
11788                 {
11789                     // if index_align<1> != �0� then UNDEFINED;
11790                     if (BitIsClear (index_align, 1))
11791                         return false;
11792 
11793                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11794                     ebytes = 2;
11795                     esize = 16;
11796                     index = Bits32 (index_align, 3, 2);
11797 
11798                     // alignment = if index_align<0> == �0� then 1 else 2;
11799                     if (BitIsClear (index_align, 0))
11800                         alignment = 1;
11801                     else
11802                         alignment = 2;
11803                 }
11804                 else if (size == 2) // when �10�
11805                 {
11806                     // if index_align<2> != �0� then UNDEFINED;
11807                     if (BitIsClear (index_align, 2))
11808                         return false;
11809 
11810                     // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11811                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11812                         return false;
11813 
11814                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11815                     ebytes = 4;
11816                     esize = 32;
11817                     index = Bit32 (index_align, 3);
11818 
11819                     // alignment = if index_align<1:0> == �00� then 1 else 4;
11820                     if (Bits32 (index_align, 1, 0) == 0)
11821                         alignment = 1;
11822                     else
11823                         alignment = 4;
11824                 }
11825                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11826                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11827                 n = Bits32 (opcode, 19, 16);
11828                 m = Bits32 (opcode, 3, 0);
11829 
11830                 // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15 then UNPREDICTABLE;
11831                 wback = (m != 15);
11832                 register_index = ((m != 15) && (m != 13));
11833 
11834                 if (n == 15)
11835                     return false;
11836             }
11837                 break;
11838 
11839             default:
11840                 return false;
11841         }
11842 
11843         RegisterInfo base_reg;
11844         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11845 
11846         uint32_t Rn = ReadCoreReg (n, &success);
11847         if (!success)
11848             return false;
11849 
11850         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11851         addr_t address = Rn;
11852         if ((address % alignment) != 0)
11853             return false;
11854 
11855         EmulateInstruction::Context context;
11856         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11857         if (wback)
11858         {
11859             uint32_t Rm = ReadCoreReg (m, &success);
11860             if (!success)
11861                 return false;
11862 
11863             uint32_t offset;
11864             if (register_index)
11865                 offset = Rm;
11866             else
11867                 offset = ebytes;
11868 
11869             context.type = eContextAdjustBaseRegister;
11870             context.SetRegisterPlusOffset (base_reg, offset);
11871 
11872             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11873                 return false;
11874         }
11875 
11876         // MemU[address,ebytes] = Elem[D[d],index,esize];
11877         uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11878         if (!success)
11879             return false;
11880 
11881         uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1,  index * esize);
11882 
11883         RegisterInfo data_reg;
11884         GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg);
11885         context.type = eContextRegisterStore;
11886         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11887 
11888         if (!MemUWrite (context, address, word, ebytes))
11889             return false;
11890     }
11891     return true;
11892 }
11893 
11894 // A8.6.309 VLD1 (single element to all lanes)
11895 // This instruction loads one element from memory into every element of one or two vectors.
11896 bool
11897 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding)
11898 {
11899 #if 0
11900     if ConditionPassed() then
11901         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11902         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11903         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11904         replicated_element = Replicate(MemU[address,ebytes], elements);
11905         for r = 0 to regs-1
11906             D[d+r] = replicated_element;
11907 #endif
11908 
11909     bool success = false;
11910 
11911     if (ConditionPassed (opcode))
11912     {
11913         uint32_t ebytes;
11914         uint32_t elements;
11915         uint32_t regs;
11916         uint32_t alignment;
11917         uint32_t d;
11918         uint32_t n;
11919         uint32_t m;
11920         bool wback;
11921         bool register_index;
11922 
11923         switch (encoding)
11924         {
11925             case eEncodingT1:
11926             case eEncodingA1:
11927             {
11928                 //if size == �11� || (size == �00� && a == �1�) then UNDEFINED;
11929                 uint32_t size = Bits32 (opcode, 7, 6);
11930                 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4)))
11931                     return false;
11932 
11933                 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2;
11934                 ebytes = 1 << size;
11935                 elements = 8 / ebytes;
11936                 if (BitIsClear (opcode, 5))
11937                     regs = 1;
11938                 else
11939                     regs = 2;
11940 
11941                 //alignment = if a == �0� then 1 else ebytes;
11942                 if (BitIsClear (opcode, 4))
11943                     alignment = 1;
11944                 else
11945                     alignment = ebytes;
11946 
11947                 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11948                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11949                 n = Bits32 (opcode, 19, 16);
11950                 m = Bits32 (opcode, 3, 0);
11951 
11952                 //wback = (m != 15); register_index = (m != 15 && m != 13);
11953                 wback = (m != 15);
11954                 register_index = ((m != 15) && (m != 13));
11955 
11956                 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11957                 if ((d + regs) > 32)
11958                     return false;
11959 
11960                 if (n == 15)
11961                     return false;
11962             }
11963             break;
11964 
11965             default:
11966                 return false;
11967         }
11968 
11969         RegisterInfo base_reg;
11970         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11971 
11972         uint32_t Rn = ReadCoreReg (n, &success);
11973         if (!success)
11974             return false;
11975 
11976         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11977         addr_t address = Rn;
11978         if ((address % alignment) != 0)
11979             return false;
11980 
11981         EmulateInstruction::Context context;
11982         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11983         if (wback)
11984         {
11985             uint32_t Rm = ReadCoreReg (m, &success);
11986             if (!success)
11987                 return false;
11988 
11989             uint32_t offset;
11990             if (register_index)
11991                 offset = Rm;
11992             else
11993                 offset = ebytes;
11994 
11995             context.type = eContextAdjustBaseRegister;
11996             context.SetRegisterPlusOffset (base_reg, offset);
11997 
11998             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11999                 return false;
12000         }
12001 
12002         // replicated_element = Replicate(MemU[address,ebytes], elements);
12003 
12004         context.type = eContextRegisterLoad;
12005         uint64_t word = MemURead (context, address, ebytes, 0, &success);
12006         if (!success)
12007             return false;
12008 
12009         uint64_t replicated_element = 0;
12010         uint32_t esize = ebytes * 8;
12011         for (int e = 0; e < elements; ++e)
12012             replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0);
12013 
12014         // for r = 0 to regs-1
12015         for (int r = 0; r < regs; ++r)
12016         {
12017             // D[d+r] = replicated_element;
12018             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element))
12019                 return false;
12020         }
12021     }
12022     return true;
12023 }
12024 
12025 // B6.2.13 SUBS PC, LR and related instructions
12026 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack.  It subtracts the
12027 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR.
12028 bool
12029 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding)
12030 {
12031 #if 0
12032     if ConditionPassed() then
12033         EncodingSpecificOperations();
12034         if CurrentInstrSet() == InstrSet_ThumbEE then
12035             UNPREDICTABLE;
12036         operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12037         case opcode of
12038             when0000result = R[n] AND operand2; // AND
12039             when0001result = R[n] EOR operand2; // EOR
12040             when0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12041             when0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12042             when0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12043             when0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12044             when0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12045             when0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12046             when1100result = R[n] OR operand2; // ORR
12047             when1101result = operand2; // MOV
12048             when1110result = R[n] AND NOT(operand2); // BIC
12049             when1111result = NOT(operand2); // MVN
12050         CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12051         BranchWritePC(result);
12052 #endif
12053 
12054     bool success = false;
12055 
12056     if (ConditionPassed (opcode))
12057     {
12058         uint32_t n;
12059         uint32_t m;
12060         uint32_t imm32;
12061         bool register_form;
12062         ARM_ShifterType shift_t;
12063         uint32_t shift_n;
12064         uint32_t code;
12065 
12066         switch (encoding)
12067         {
12068             case eEncodingT1:
12069                 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
12070                 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB
12071                 n = 14;
12072                 imm32 = Bits32 (opcode, 7, 0);
12073                 register_form = false;
12074                 code = 2;
12075 
12076                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12077                 if (InITBlock() && !LastInITBlock())
12078                     return false;
12079 
12080                 break;
12081 
12082             case eEncodingA1:
12083                 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12084                 n = Bits32 (opcode, 19, 16);
12085                 imm32 = ARMExpandImm (opcode);
12086                 register_form = false;
12087                 code = Bits32 (opcode, 24, 21);
12088 
12089                 break;
12090 
12091             case eEncodingA2:
12092                 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12093                 n = Bits32 (opcode, 19, 16);
12094                 m = Bits32 (opcode, 3, 0);
12095                 register_form = true;
12096 
12097                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12098                 shift_n = DecodeImmShiftARM (opcode, shift_t);
12099 
12100                 break;
12101 
12102             default:
12103                 return false;
12104         }
12105 
12106         // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12107         uint32_t operand2;
12108         if (register_form)
12109         {
12110             uint32_t Rm = ReadCoreReg (m, &success);
12111             if (!success)
12112                 return false;
12113 
12114             operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success);
12115             if (!success)
12116                 return false;
12117         }
12118         else
12119         {
12120             operand2 = imm32;
12121         }
12122 
12123         uint32_t Rn = ReadCoreReg (n, &success);
12124         if (!success)
12125             return false;
12126 
12127         AddWithCarryResult result;
12128 
12129         // case opcode of
12130         switch (code)
12131         {
12132             case 0: // when �0000�
12133                 // result = R[n] AND operand2; // AND
12134                 result.result = Rn & operand2;
12135                 break;
12136 
12137             case 1: // when �0001�
12138                 // result = R[n] EOR operand2; // EOR
12139                 result.result = Rn ^ operand2;
12140                 break;
12141 
12142             case 2: // when �0010�
12143                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12144                 result = AddWithCarry (Rn, ~(operand2), 1);
12145                 break;
12146 
12147             case 3: // when �0011�
12148                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12149                 result = AddWithCarry (~(Rn), operand2, 1);
12150                 break;
12151 
12152             case 4: // when �0100�
12153                 // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12154                 result = AddWithCarry (Rn, operand2, 0);
12155                 break;
12156 
12157             case 5: // when �0101�
12158                 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12159                 result = AddWithCarry (Rn, operand2, APSR_C);
12160                 break;
12161 
12162             case 6: // when �0110�
12163                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12164                 result = AddWithCarry (Rn, ~(operand2), APSR_C);
12165                 break;
12166 
12167             case 7: // when �0111�
12168                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12169                 result = AddWithCarry (~(Rn), operand2, APSR_C);
12170                 break;
12171 
12172             case 10: // when �1100�
12173                 // result = R[n] OR operand2; // ORR
12174                 result.result = Rn | operand2;
12175                 break;
12176 
12177             case 11: // when �1101�
12178                 // result = operand2; // MOV
12179                 result.result = operand2;
12180                 break;
12181 
12182             case 12: // when �1110�
12183                 // result = R[n] AND NOT(operand2); // BIC
12184                 result.result = Rn & ~(operand2);
12185                 break;
12186 
12187             case 15: // when �1111�
12188                 // result = NOT(operand2); // MVN
12189                 result.result = ~(operand2);
12190                 break;
12191 
12192             default:
12193                 return false;
12194         }
12195         // CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12196 
12197         // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for
12198         // the best.
12199         uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12200         if (!success)
12201             return false;
12202 
12203         CPSRWriteByInstr (spsr, 15, true);
12204 
12205         // BranchWritePC(result);
12206         EmulateInstruction::Context context;
12207         context.type = eContextAdjustPC;
12208         context.SetImmediate (result.result);
12209 
12210         BranchWritePC (context, result.result);
12211     }
12212     return true;
12213 }
12214 
12215 EmulateInstructionARM::ARMOpcode*
12216 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12217 {
12218     static ARMOpcode
12219     g_arm_opcodes[] =
12220     {
12221         //----------------------------------------------------------------------
12222         // Prologue instructions
12223         //----------------------------------------------------------------------
12224 
12225         // push register(s)
12226         { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12227         { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
12228 
12229         // set r7 to point to a stack offset
12230         { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
12231         { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12232         // copy the stack pointer to ip
12233         { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
12234         { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
12235         { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12236 
12237         // adjust the stack pointer
12238         { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12239         { 0x0fef0010, 0x004d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12240 
12241         // push one register
12242         // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12243         { 0x0e5f0000, 0x040d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
12244 
12245         // vector push consecutive extension register(s)
12246         { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12247         { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12248 
12249         //----------------------------------------------------------------------
12250         // Epilogue instructions
12251         //----------------------------------------------------------------------
12252 
12253         { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12254         { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12255         { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12256         { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12257 
12258         //----------------------------------------------------------------------
12259         // Supervisor Call (previously Software Interrupt)
12260         //----------------------------------------------------------------------
12261         { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12262 
12263         //----------------------------------------------------------------------
12264         // Branch instructions
12265         //----------------------------------------------------------------------
12266         { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
12267         // To resolve ambiguity, "blx <label>" should come before "bl <label>".
12268         { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12269         { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12270         { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12271         // for example, "bx lr"
12272         { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12273         // bxj
12274         { 0x0ffffff0, 0x012fff20, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12275 
12276         //----------------------------------------------------------------------
12277         // Data-processing instructions
12278         //----------------------------------------------------------------------
12279         // adc (immediate)
12280         { 0x0fe00000, 0x02a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12281         // adc (register)
12282         { 0x0fe00010, 0x00a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12283         // add (immediate)
12284         { 0x0fe00000, 0x02800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
12285         // add (register)
12286         { 0x0fe00010, 0x00800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12287         // add (register-shifted register)
12288         { 0x0fe00090, 0x00800010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12289         // adr
12290         { 0x0fff0000, 0x028f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12291         { 0x0fff0000, 0x024f0000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12292         // and (immediate)
12293         { 0x0fe00000, 0x02000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12294         // and (register)
12295         { 0x0fe00010, 0x00000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12296         // bic (immediate)
12297         { 0x0fe00000, 0x03c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12298         // bic (register)
12299         { 0x0fe00010, 0x01c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12300         // eor (immediate)
12301         { 0x0fe00000, 0x02200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12302         // eor (register)
12303         { 0x0fe00010, 0x00200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12304         // orr (immediate)
12305         { 0x0fe00000, 0x03800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12306         // orr (register)
12307         { 0x0fe00010, 0x01800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12308         // rsb (immediate)
12309         { 0x0fe00000, 0x02600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12310         // rsb (register)
12311         { 0x0fe00010, 0x00600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12312         // rsc (immediate)
12313         { 0x0fe00000, 0x02e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12314         // rsc (register)
12315         { 0x0fe00010, 0x00e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12316         // sbc (immediate)
12317         { 0x0fe00000, 0x02c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12318         // sbc (register)
12319         { 0x0fe00010, 0x00c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12320         // sub (immediate, ARM)
12321         { 0x0fe00000, 0x02400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
12322         // sub (sp minus immediate)
12323         { 0x0fef0000, 0x024d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12324         // sub (register)
12325         { 0x0fe00010, 0x00400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12326         // teq (immediate)
12327         { 0x0ff0f000, 0x03300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12328         // teq (register)
12329         { 0x0ff0f010, 0x01300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12330         // tst (immediate)
12331         { 0x0ff0f000, 0x03100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12332         // tst (register)
12333         { 0x0ff0f010, 0x01100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12334 
12335         // mov (immediate)
12336         { 0x0fef0000, 0x03a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12337         { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
12338         // mov (register)
12339         { 0x0fef0ff0, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12340         // mvn (immediate)
12341         { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12342         // mvn (register)
12343         { 0x0fef0010, 0x01e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12344         // cmn (immediate)
12345         { 0x0ff0f000, 0x03700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12346         // cmn (register)
12347         { 0x0ff0f010, 0x01700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12348         // cmp (immediate)
12349         { 0x0ff0f000, 0x03500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
12350         // cmp (register)
12351         { 0x0ff0f010, 0x01500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
12352         // asr (immediate)
12353         { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
12354         // asr (register)
12355         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
12356         // lsl (immediate)
12357         { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
12358         // lsl (register)
12359         { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
12360         // lsr (immediate)
12361         { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
12362         // lsr (register)
12363         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
12364         // rrx is a special case encoding of ror (immediate)
12365         { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
12366         // ror (immediate)
12367         { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
12368         // ror (register)
12369         { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
12370         // mul
12371         { 0x0fe000f0, 0x00000090, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
12372 
12373         // subs pc, lr and related instructions
12374         { 0x0e10f000, 0x0210f000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" },
12375         { 0x0e10f010, 0x0010f000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" },
12376 
12377         //----------------------------------------------------------------------
12378         // Load instructions
12379         //----------------------------------------------------------------------
12380         { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12381         { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
12382         { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12383         { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
12384         { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
12385         { 0x0e500010, 0x06100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
12386         { 0x0e5f0000, 0x045f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
12387         { 0xfe500010, 0x06500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
12388         { 0x0e5f00f0, 0x005f00b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12389         { 0x0e5000f0, 0x001000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"  },
12390         { 0x0e5000f0, 0x005000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
12391         { 0x0e5f00f0, 0x005f00d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
12392         { 0x0e5000f0, 0x001000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12393         { 0x0e5000f0, 0x005000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
12394         { 0x0e5f00f0, 0x005f00f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12395         { 0x0e5000f0, 0x001000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12396         { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
12397         { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12398         { 0x0e100f00, 0x0c100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12399         { 0x0e100f00, 0x0c100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12400         { 0x0f300f00, 0x0d100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12401         { 0x0f300f00, 0x0d100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12402         { 0xffb00000, 0xf4200000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12403         { 0xffb00300, 0xf4a00000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12404         { 0xffb00f00, 0xf4a00c00, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12405 
12406         //----------------------------------------------------------------------
12407         // Store instructions
12408         //----------------------------------------------------------------------
12409         { 0x0fd00000, 0x08800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12410         { 0x0fd00000, 0x08000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
12411         { 0x0fd00000, 0x09000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12412         { 0x0fd00000, 0x09800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
12413         { 0x0e500010, 0x06000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
12414         { 0x0e5000f0, 0x000000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
12415         { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
12416         { 0x0e500000, 0x04400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12417         { 0x0e500000, 0x04000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12418         { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
12419         { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12420         { 0x0e100f00, 0x0c000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12421         { 0x0e100f00, 0x0c000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12422         { 0x0f300f00, 0x0d000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
12423         { 0x0f300f00, 0x0d000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
12424         { 0xffb00000, 0xf4000000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12425         { 0xffb00300, 0xf4800000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12426 
12427         //----------------------------------------------------------------------
12428         // Other instructions
12429         //----------------------------------------------------------------------
12430         { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
12431         { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
12432         { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
12433         { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
12434         { 0xfe500000, 0xf8100000, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
12435 
12436     };
12437     static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode);
12438 
12439     for (size_t i=0; i<k_num_arm_opcodes; ++i)
12440     {
12441         if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
12442             (g_arm_opcodes[i].variants & arm_isa) != 0)
12443             return &g_arm_opcodes[i];
12444     }
12445     return NULL;
12446 }
12447 
12448 
12449 EmulateInstructionARM::ARMOpcode*
12450 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12451 {
12452 
12453     static ARMOpcode
12454     g_thumb_opcodes[] =
12455     {
12456         //----------------------------------------------------------------------
12457         // Prologue instructions
12458         //----------------------------------------------------------------------
12459 
12460         // push register(s)
12461         { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12462         { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
12463         { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
12464 
12465         // set r7 to point to a stack offset
12466         { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
12467         // copy the stack pointer to r7
12468         { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
12469         // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
12470         { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
12471 
12472         // PC-relative load into register (see also EmulateADDSPRm)
12473         { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
12474 
12475         // adjust the stack pointer
12476         { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
12477         { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
12478         { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
12479         { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
12480         { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12481 
12482         // vector push consecutive extension register(s)
12483         { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12484         { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12485 
12486         //----------------------------------------------------------------------
12487         // Epilogue instructions
12488         //----------------------------------------------------------------------
12489 
12490         { 0xfffff800, 0x0000a800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
12491         { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
12492         { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12493         { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
12494         { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
12495         { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12496         { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12497 
12498         //----------------------------------------------------------------------
12499         // Supervisor Call (previously Software Interrupt)
12500         //----------------------------------------------------------------------
12501         { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
12502 
12503         //----------------------------------------------------------------------
12504         // If Then makes up to four following instructions conditional.
12505         //----------------------------------------------------------------------
12506         // The next 5 opcode _must_ come before the if then instruction
12507         { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"},
12508         { 0xffffffff, 0x0000bf10, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
12509         { 0xffffffff, 0x0000bf20, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
12510         { 0xffffffff, 0x0000bf30, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
12511         { 0xffffffff, 0x0000bf40, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
12512         { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
12513 
12514         //----------------------------------------------------------------------
12515         // Branch instructions
12516         //----------------------------------------------------------------------
12517         // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
12518         { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
12519         { 0xfffff800, 0x0000e000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
12520         { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
12521         { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
12522         // J1 == J2 == 1
12523         { 0xf800d000, 0xf000d000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12524         // J1 == J2 == 1
12525         { 0xf800d001, 0xf000c000, ARMV5_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12526         { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12527         // for example, "bx lr"
12528         { 0xffffff87, 0x00004700, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12529         // bxj
12530         { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12531         // compare and branch
12532         { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
12533         // table branch byte
12534         { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
12535         // table branch halfword
12536         { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
12537 
12538         //----------------------------------------------------------------------
12539         // Data-processing instructions
12540         //----------------------------------------------------------------------
12541         // adc (immediate)
12542         { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
12543         // adc (register)
12544         { 0xffffffc0, 0x00004140, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
12545         { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12546         // add (register)
12547         { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
12548         // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
12549         { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
12550         // adr
12551         { 0xfffff800, 0x0000a000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12552         { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12553         { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12554         // and (immediate)
12555         { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
12556         // and (register)
12557         { 0xffffffc0, 0x00004000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
12558         { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12559         // bic (immediate)
12560         { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
12561         // bic (register)
12562         { 0xffffffc0, 0x00004380, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
12563         { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12564         // eor (immediate)
12565         { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
12566         // eor (register)
12567         { 0xffffffc0, 0x00004040, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
12568         { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12569         // orr (immediate)
12570         { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
12571         // orr (register)
12572         { 0xffffffc0, 0x00004300, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
12573         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12574         // rsb (immediate)
12575         { 0xffffffc0, 0x00004240, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
12576         { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
12577         // rsb (register)
12578         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12579         // sbc (immediate)
12580         { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12581         // sbc (register)
12582         { 0xffffffc0, 0x00004180, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
12583         { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12584         // add (immediate, Thumb)
12585         { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
12586         { 0xfffff800, 0x00003000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
12587         { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
12588         { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
12589         // sub (immediate, Thumb)
12590         { 0xfffffe00, 0x00001e00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
12591         { 0xfffff800, 0x00003800, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
12592         { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
12593         { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
12594         // sub (sp minus immediate)
12595         { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
12596         { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
12597         // sub (register)
12598         { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
12599         { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
12600         // teq (immediate)
12601         { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
12602         // teq (register)
12603         { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12604         // tst (immediate)
12605         { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
12606         // tst (register)
12607         { 0xffffffc0, 0x00004200, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
12608         { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
12609 
12610 
12611         // move from high register to high register
12612         { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
12613         // move from low register to low register
12614         { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
12615         // mov{s}<c>.w <Rd>, <Rm>
12616         { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
12617         // move immediate
12618         { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
12619         { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
12620         { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
12621         // mvn (immediate)
12622         { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
12623         // mvn (register)
12624         { 0xffffffc0, 0x000043c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
12625         { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
12626         // cmn (immediate)
12627         { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12628         // cmn (register)
12629         { 0xffffffc0, 0x000042c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
12630         { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12631         // cmp (immediate)
12632         { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
12633         { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
12634         // cmp (register) (Rn and Rm both from r0-r7)
12635         { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12636         // cmp (register) (Rn and Rm not both from r0-r7)
12637         { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12638         // asr (immediate)
12639         { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
12640         { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
12641         // asr (register)
12642         { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
12643         { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12644         // lsl (immediate)
12645         { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
12646         { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
12647         // lsl (register)
12648         { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
12649         { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
12650         // lsr (immediate)
12651         { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
12652         { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
12653         // lsr (register)
12654         { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
12655         { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12656         // rrx is a special case encoding of ror (immediate)
12657         { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
12658         // ror (immediate)
12659         { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
12660         // ror (register)
12661         { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
12662         { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
12663         // mul
12664         { 0xffffffc0, 0x00004340, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
12665         // mul
12666         { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
12667 
12668         // subs pc, lr and related instructions
12669         { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" },
12670 
12671         //----------------------------------------------------------------------
12672         // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table;
12673         // otherwise the wrong instructions will be selected.
12674         //----------------------------------------------------------------------
12675 
12676         { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
12677         { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
12678 
12679         //----------------------------------------------------------------------
12680         // Load instructions
12681         //----------------------------------------------------------------------
12682         { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12683         { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
12684         { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12685         { 0xfffff800, 0x00006800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
12686         { 0xfffff800, 0x00009800, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
12687         { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
12688         { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
12689                   // Thumb2 PC-relative load into register
12690         { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
12691         { 0xfffffe00, 0x00005800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
12692         { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
12693         { 0xfffff800, 0x00007800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
12694         { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12695         { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" },
12696         { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
12697         { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
12698         { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
12699         { 0xfffff800, 0x00008800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"  },
12700         { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12701         { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"  },
12702         { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12703         { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
12704         { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12705         { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
12706         { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12707         { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
12708         { 0xfffffe00, 0x00005600, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
12709         { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"  },
12710         { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
12711         { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12712         { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12713         { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
12714         { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12715         { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
12716         { 0xfe100f00, 0xec100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12717         { 0xfe100f00, 0xec100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
12718         { 0xffe00f00, 0xed100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12719         { 0xff300f00, 0xed100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
12720         { 0xffb00000, 0xf9200000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12721         { 0xffb00300, 0xf9a00000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12722         { 0xffb00f00, 0xf9a00c00, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12723 
12724         //----------------------------------------------------------------------
12725         // Store instructions
12726         //----------------------------------------------------------------------
12727         { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12728         { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
12729         { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12730         { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
12731         { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
12732         { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
12733         { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
12734         { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
12735         { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
12736         { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
12737         { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
12738         { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
12739         { 0xfffffe00, 0x00005200, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
12740         { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12741         { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
12742         { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
12743         { 0xfe100f00, 0xec000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12744         { 0xfea00f00, 0xec000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12745         { 0xff300f00, 0xed000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12746         { 0xff300f00, 0xed000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12747         { 0xffb00000, 0xfa000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12748         { 0xffb00300, 0xf9800000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12749 
12750         //----------------------------------------------------------------------
12751         // Other instructions
12752         //----------------------------------------------------------------------
12753         { 0xffffffc0, 0x0000b240, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
12754         { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12755         { 0xffffffc0, 0x0000b200, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
12756         { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12757         { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
12758         { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12759         { 0xffffffc0, 0x0000b280, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
12760         { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12761     };
12762 
12763     const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode);
12764     for (size_t i=0; i<k_num_thumb_opcodes; ++i)
12765     {
12766         if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
12767             (g_thumb_opcodes[i].variants & arm_isa) != 0)
12768             return &g_thumb_opcodes[i];
12769     }
12770     return NULL;
12771 }
12772 
12773 bool
12774 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
12775 {
12776     m_arch = arch;
12777     m_arm_isa = 0;
12778     const char *arch_cstr = arch.GetArchitectureName ();
12779     if (arch_cstr)
12780     {
12781         if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
12782         else if (0 == ::strcasecmp(arch_cstr, "armv4"))     m_arm_isa = ARMv4;
12783         else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
12784         else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
12785         else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
12786         else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
12787         else if (0 == ::strcasecmp(arch_cstr, "armv6"))     m_arm_isa = ARMv6;
12788         else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
12789         else if (0 == ::strcasecmp(arch_cstr, "armv7"))     m_arm_isa = ARMv7;
12790         else if (0 == ::strcasecmp(arch_cstr, "armv8"))     m_arm_isa = ARMv8;
12791         else if (0 == ::strcasecmp(arch_cstr, "arm"))       m_arm_isa = ARMvAll;
12792         else if (0 == ::strcasecmp(arch_cstr, "thumb"))     m_arm_isa = ARMvAll;
12793     }
12794     return m_arm_isa != 0;
12795 }
12796 
12797 bool
12798 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
12799 {
12800     if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
12801     {
12802         if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
12803             m_opcode_mode = eModeThumb;
12804         else
12805         {
12806             AddressClass addr_class = inst_addr.GetAddressClass();
12807 
12808             if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
12809                 m_opcode_mode = eModeARM;
12810             else if (addr_class == eAddressClassCodeAlternateISA)
12811                 m_opcode_mode = eModeThumb;
12812             else
12813                 return false;
12814         }
12815         if (m_opcode_mode == eModeThumb)
12816             m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
12817         else
12818             m_opcode_cpsr = CPSR_MODE_USR;
12819         return true;
12820     }
12821     return false;
12822 }
12823 
12824 bool
12825 EmulateInstructionARM::ReadInstruction ()
12826 {
12827     bool success = false;
12828     m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
12829     if (success)
12830     {
12831         addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
12832         if (success)
12833         {
12834             Context read_inst_context;
12835             read_inst_context.type = eContextReadOpcode;
12836             read_inst_context.SetNoArgs ();
12837 
12838             if (m_opcode_cpsr & MASK_CPSR_T)
12839             {
12840                 m_opcode_mode = eModeThumb;
12841                 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
12842 
12843                 if (success)
12844                 {
12845                     if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
12846                     {
12847                         m_opcode.SetOpcode16 (thumb_opcode);
12848                     }
12849                     else
12850                     {
12851                         m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success));
12852                     }
12853                 }
12854             }
12855             else
12856             {
12857                 m_opcode_mode = eModeARM;
12858                 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success));
12859             }
12860         }
12861     }
12862     if (!success)
12863     {
12864         m_opcode_mode = eModeInvalid;
12865         m_addr = LLDB_INVALID_ADDRESS;
12866     }
12867     return success;
12868 }
12869 
12870 uint32_t
12871 EmulateInstructionARM::ArchVersion ()
12872 {
12873     return m_arm_isa;
12874 }
12875 
12876 bool
12877 EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional)
12878 {
12879    // If we are ignoring conditions, then always return true.
12880    // this allows us to iterate over disassembly code and still
12881    // emulate an instruction even if we don't have all the right
12882    // bits set in the CPSR register...
12883     if (m_ignore_conditions)
12884         return true;
12885 
12886     if (is_conditional)
12887         *is_conditional = true;
12888 
12889     const uint32_t cond = CurrentCond (opcode);
12890 
12891     if (cond == UINT32_MAX)
12892         return false;
12893 
12894     bool result = false;
12895     switch (UnsignedBits(cond, 3, 1))
12896     {
12897     case 0:
12898 		if (m_opcode_cpsr == 0)
12899 			result = true;
12900         else
12901             result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
12902 		break;
12903     case 1:
12904         if (m_opcode_cpsr == 0)
12905             result = true;
12906         else
12907             result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
12908 		break;
12909     case 2:
12910         if (m_opcode_cpsr == 0)
12911             result = true;
12912         else
12913             result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
12914 		break;
12915     case 3:
12916         if (m_opcode_cpsr == 0)
12917             result = true;
12918         else
12919             result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
12920 		break;
12921     case 4:
12922         if (m_opcode_cpsr == 0)
12923             result = true;
12924         else
12925             result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12926 		break;
12927     case 5:
12928         if (m_opcode_cpsr == 0)
12929             result = true;
12930         else
12931 		{
12932             bool n = (m_opcode_cpsr & MASK_CPSR_N);
12933             bool v = (m_opcode_cpsr & MASK_CPSR_V);
12934             result = n == v;
12935         }
12936         break;
12937     case 6:
12938         if (m_opcode_cpsr == 0)
12939             result = true;
12940         else
12941 		{
12942             bool n = (m_opcode_cpsr & MASK_CPSR_N);
12943             bool v = (m_opcode_cpsr & MASK_CPSR_V);
12944             result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12945         }
12946         break;
12947     case 7:
12948         // Always execute (cond == 0b1110, or the special 0b1111 which gives
12949         // opcodes different meanings, but always means execution happpens.
12950         if (is_conditional)
12951             *is_conditional = false;
12952         result = true;
12953         break;
12954     }
12955 
12956     if (cond & 1)
12957         result = !result;
12958     return result;
12959 }
12960 
12961 uint32_t
12962 EmulateInstructionARM::CurrentCond (const uint32_t opcode)
12963 {
12964     switch (m_opcode_mode)
12965     {
12966     default:
12967     case eModeInvalid:
12968         break;
12969 
12970     case eModeARM:
12971         return UnsignedBits(opcode, 31, 28);
12972 
12973     case eModeThumb:
12974         // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
12975         // 'cond' field of the encoding.
12976         {
12977             const uint32_t byte_size = m_opcode.GetByteSize();
12978             if (byte_size == 2)
12979             {
12980                 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f)
12981                     return Bits32(opcode, 11, 7);
12982             }
12983             else if (byte_size == 4)
12984             {
12985                 if (Bits32(opcode, 31, 27) == 0x1e &&
12986                     Bits32(opcode, 15, 14) == 0x02 &&
12987                     Bits32(opcode, 12, 12) == 0x00 &&
12988                     Bits32(opcode, 25, 22) <= 0x0d)
12989                 {
12990                     return Bits32(opcode, 25, 22);
12991                 }
12992             }
12993             else
12994                 // We have an invalid thumb instruction, let's bail out.
12995                 break;
12996 
12997             return m_it_session.GetCond();
12998         }
12999     }
13000     return UINT32_MAX;  // Return invalid value
13001 }
13002 
13003 bool
13004 EmulateInstructionARM::InITBlock()
13005 {
13006     return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13007 }
13008 
13009 bool
13010 EmulateInstructionARM::LastInITBlock()
13011 {
13012     return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13013 }
13014 
13015 bool
13016 EmulateInstructionARM::BadMode (uint32_t mode)
13017 {
13018 
13019     switch (mode)
13020     {
13021         case 16: return false; // '10000'
13022         case 17: return false; // '10001'
13023         case 18: return false; // '10010'
13024         case 19: return false; // '10011'
13025         case 22: return false; // '10110'
13026         case 23: return false; // '10111'
13027         case 27: return false; // '11011'
13028         case 31: return false; // '11111'
13029         default: return true;
13030     }
13031     return true;
13032 }
13033 
13034 bool
13035 EmulateInstructionARM::CurrentModeIsPrivileged ()
13036 {
13037     uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
13038 
13039     if (BadMode (mode))
13040         return false;
13041 
13042     if (mode == 16)
13043         return false;
13044 
13045     return true;
13046 }
13047 
13048 void
13049 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
13050 {
13051     bool privileged = CurrentModeIsPrivileged();
13052 
13053     uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20;
13054 
13055     if (BitIsSet (bytemask, 3))
13056     {
13057         tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
13058         if (affect_execstate)
13059             tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
13060     }
13061 
13062     if (BitIsSet (bytemask, 2))
13063     {
13064         tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
13065     }
13066 
13067     if (BitIsSet (bytemask, 1))
13068     {
13069         if (affect_execstate)
13070             tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
13071         tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
13072         if (privileged)
13073             tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
13074     }
13075 
13076     if (BitIsSet (bytemask, 0))
13077     {
13078         if (privileged)
13079             tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
13080         if (affect_execstate)
13081             tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
13082         if (privileged)
13083             tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
13084     }
13085 
13086     m_opcode_cpsr = tmp_cpsr;
13087 }
13088 
13089 
13090 bool
13091 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
13092 {
13093     addr_t target;
13094 
13095     // Check the current instruction set.
13096     if (CurrentInstrSet() == eModeARM)
13097         target = addr & 0xfffffffc;
13098     else
13099         target = addr & 0xfffffffe;
13100 
13101     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13102         return false;
13103 
13104     return true;
13105 }
13106 
13107 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
13108 bool
13109 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
13110 {
13111     addr_t target;
13112     // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
13113     // we want to record it and issue a WriteRegister callback so the clients
13114     // can track the mode changes accordingly.
13115     bool cpsr_changed = false;
13116 
13117     if (BitIsSet(addr, 0))
13118     {
13119         if (CurrentInstrSet() != eModeThumb)
13120         {
13121             SelectInstrSet(eModeThumb);
13122             cpsr_changed = true;
13123         }
13124         target = addr & 0xfffffffe;
13125         context.SetISA (eModeThumb);
13126     }
13127     else if (BitIsClear(addr, 1))
13128     {
13129         if (CurrentInstrSet() != eModeARM)
13130         {
13131             SelectInstrSet(eModeARM);
13132             cpsr_changed = true;
13133         }
13134         target = addr & 0xfffffffc;
13135         context.SetISA (eModeARM);
13136     }
13137     else
13138         return false; // address<1:0> == '10' => UNPREDICTABLE
13139 
13140     if (cpsr_changed)
13141     {
13142         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13143             return false;
13144     }
13145     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13146         return false;
13147 
13148     return true;
13149 }
13150 
13151 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
13152 bool
13153 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
13154 {
13155     if (ArchVersion() >= ARMv5T)
13156         return BXWritePC(context, addr);
13157     else
13158         return BranchWritePC((const Context)context, addr);
13159 }
13160 
13161 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
13162 bool
13163 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
13164 {
13165     if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
13166         return BXWritePC(context, addr);
13167     else
13168         return BranchWritePC((const Context)context, addr);
13169 }
13170 
13171 EmulateInstructionARM::Mode
13172 EmulateInstructionARM::CurrentInstrSet ()
13173 {
13174     return m_opcode_mode;
13175 }
13176 
13177 // Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
13178 // ReadInstruction() is performed.  This function has a side effect of updating
13179 // the m_new_inst_cpsr member variable if necessary.
13180 bool
13181 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
13182 {
13183     m_new_inst_cpsr = m_opcode_cpsr;
13184     switch (arm_or_thumb)
13185     {
13186     default:
13187         return false;
13188     eModeARM:
13189         // Clear the T bit.
13190         m_new_inst_cpsr &= ~MASK_CPSR_T;
13191         break;
13192     eModeThumb:
13193         // Set the T bit.
13194         m_new_inst_cpsr |= MASK_CPSR_T;
13195         break;
13196     }
13197     return true;
13198 }
13199 
13200 // This function returns TRUE if the processor currently provides support for
13201 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
13202 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
13203 bool
13204 EmulateInstructionARM::UnalignedSupport()
13205 {
13206     return (ArchVersion() >= ARMv7);
13207 }
13208 
13209 // The main addition and subtraction instructions can produce status information
13210 // about both unsigned carry and signed overflow conditions.  This status
13211 // information can be used to synthesize multi-word additions and subtractions.
13212 EmulateInstructionARM::AddWithCarryResult
13213 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
13214 {
13215     uint32_t result;
13216     uint8_t carry_out;
13217     uint8_t overflow;
13218 
13219     uint64_t unsigned_sum = x + y + carry_in;
13220     int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
13221 
13222     result = UnsignedBits(unsigned_sum, 31, 0);
13223 //    carry_out = (result == unsigned_sum ? 0 : 1);
13224     overflow = ((int32_t)result == signed_sum ? 0 : 1);
13225 
13226     if (carry_in)
13227         carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0;
13228     else
13229         carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0;
13230 
13231     AddWithCarryResult res = { result, carry_out, overflow };
13232     return res;
13233 }
13234 
13235 uint32_t
13236 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
13237 {
13238     uint32_t reg_kind, reg_num;
13239     switch (num)
13240     {
13241     case SP_REG:
13242         reg_kind = eRegisterKindGeneric;
13243         reg_num  = LLDB_REGNUM_GENERIC_SP;
13244         break;
13245     case LR_REG:
13246         reg_kind = eRegisterKindGeneric;
13247         reg_num  = LLDB_REGNUM_GENERIC_RA;
13248         break;
13249     case PC_REG:
13250         reg_kind = eRegisterKindGeneric;
13251         reg_num  = LLDB_REGNUM_GENERIC_PC;
13252         break;
13253     default:
13254         if (num < SP_REG)
13255         {
13256             reg_kind = eRegisterKindDWARF;
13257             reg_num  = dwarf_r0 + num;
13258         }
13259         else
13260         {
13261             //assert(0 && "Invalid register number");
13262             *success = false;
13263             return UINT32_MAX;
13264         }
13265         break;
13266     }
13267 
13268     // Read our register.
13269     uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
13270 
13271     // When executing an ARM instruction , PC reads as the address of the current
13272     // instruction plus 8.
13273     // When executing a Thumb instruction , PC reads as the address of the current
13274     // instruction plus 4.
13275     if (num == 15)
13276     {
13277         if (CurrentInstrSet() == eModeARM)
13278             val += 8;
13279         else
13280             val += 4;
13281     }
13282 
13283     return val;
13284 }
13285 
13286 // Write the result to the ARM core register Rd, and optionally update the
13287 // condition flags based on the result.
13288 //
13289 // This helper method tries to encapsulate the following pseudocode from the
13290 // ARM Architecture Reference Manual:
13291 //
13292 // if d == 15 then         // Can only occur for encoding A1
13293 //     ALUWritePC(result); // setflags is always FALSE here
13294 // else
13295 //     R[d] = result;
13296 //     if setflags then
13297 //         APSR.N = result<31>;
13298 //         APSR.Z = IsZeroBit(result);
13299 //         APSR.C = carry;
13300 //         // APSR.V unchanged
13301 //
13302 // In the above case, the API client does not pass in the overflow arg, which
13303 // defaults to ~0u.
13304 bool
13305 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
13306                                                   const uint32_t result,
13307                                                   const uint32_t Rd,
13308                                                   bool setflags,
13309                                                   const uint32_t carry,
13310                                                   const uint32_t overflow)
13311 {
13312     if (Rd == 15)
13313     {
13314         if (!ALUWritePC (context, result))
13315             return false;
13316     }
13317     else
13318     {
13319         uint32_t reg_kind, reg_num;
13320         switch (Rd)
13321         {
13322         case SP_REG:
13323             reg_kind = eRegisterKindGeneric;
13324             reg_num  = LLDB_REGNUM_GENERIC_SP;
13325             break;
13326         case LR_REG:
13327             reg_kind = eRegisterKindGeneric;
13328             reg_num  = LLDB_REGNUM_GENERIC_RA;
13329             break;
13330         default:
13331             reg_kind = eRegisterKindDWARF;
13332             reg_num  = dwarf_r0 + Rd;
13333         }
13334         if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
13335             return false;
13336         if (setflags)
13337             return WriteFlags (context, result, carry, overflow);
13338     }
13339     return true;
13340 }
13341 
13342 // This helper method tries to encapsulate the following pseudocode from the
13343 // ARM Architecture Reference Manual:
13344 //
13345 // APSR.N = result<31>;
13346 // APSR.Z = IsZeroBit(result);
13347 // APSR.C = carry;
13348 // APSR.V = overflow
13349 //
13350 // Default arguments can be specified for carry and overflow parameters, which means
13351 // not to update the respective flags.
13352 bool
13353 EmulateInstructionARM::WriteFlags (Context &context,
13354                                    const uint32_t result,
13355                                    const uint32_t carry,
13356                                    const uint32_t overflow)
13357 {
13358     m_new_inst_cpsr = m_opcode_cpsr;
13359     SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
13360     SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
13361     if (carry != ~0u)
13362         SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
13363     if (overflow != ~0u)
13364         SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
13365     if (m_new_inst_cpsr != m_opcode_cpsr)
13366     {
13367         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13368             return false;
13369     }
13370     return true;
13371 }
13372 
13373 bool
13374 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
13375 {
13376     // Advance the ITSTATE bits to their values for the next instruction.
13377     if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
13378         m_it_session.ITAdvance();
13379 
13380     ARMOpcode *opcode_data = NULL;
13381 
13382     if (m_opcode_mode == eModeThumb)
13383         opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13384     else if (m_opcode_mode == eModeARM)
13385         opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13386 
13387     if (opcode_data == NULL)
13388         return false;
13389 
13390     const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
13391     m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
13392 
13393     bool success = false;
13394     if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
13395     {
13396         m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF,
13397                                                 dwarf_cpsr,
13398                                                 0,
13399                                                 &success);
13400     }
13401 
13402     // Only return false if we are unable to read the CPSR if we care about conditions
13403     if (success == false && m_ignore_conditions == false)
13404         return false;
13405 
13406     uint32_t orig_pc_value = 0;
13407     if (auto_advance_pc)
13408     {
13409         orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13410         if (!success)
13411             return false;
13412     }
13413 
13414     // Call the Emulate... function.
13415     success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
13416     if (!success)
13417         return false;
13418 
13419     if (auto_advance_pc)
13420     {
13421         uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13422         if (!success)
13423             return false;
13424 
13425         if (auto_advance_pc && (after_pc_value == orig_pc_value))
13426         {
13427             if (opcode_data->size == eSize32)
13428                 after_pc_value += 4;
13429             else if (opcode_data->size == eSize16)
13430                 after_pc_value += 2;
13431 
13432             EmulateInstruction::Context context;
13433             context.type = eContextAdvancePC;
13434             context.SetNoArgs();
13435             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
13436                 return false;
13437 
13438         }
13439     }
13440     return true;
13441 }
13442 
13443 bool
13444 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data)
13445 {
13446     if (!test_data)
13447     {
13448         out_stream->Printf ("TestEmulation: Missing test data.\n");
13449         return false;
13450     }
13451 
13452     static ConstString opcode_key ("opcode");
13453     static ConstString before_key ("before_state");
13454     static ConstString after_key ("after_state");
13455 
13456     OptionValueSP value_sp = test_data->GetValueForKey (opcode_key);
13457 
13458     uint32_t test_opcode;
13459     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64))
13460     {
13461         out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n");
13462         return false;
13463     }
13464     test_opcode = value_sp->GetUInt64Value ();
13465 
13466     if (arch.GetTriple().getArch() == llvm::Triple::arm)
13467     {
13468         m_opcode_mode = eModeARM;
13469         m_opcode.SetOpcode32 (test_opcode);
13470     }
13471     else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
13472     {
13473         m_opcode_mode = eModeThumb;
13474         if (test_opcode < 0x10000)
13475             m_opcode.SetOpcode16 (test_opcode);
13476         else
13477             m_opcode.SetOpcode32 (test_opcode);
13478 
13479     }
13480     else
13481     {
13482         out_stream->Printf ("TestEmulation:  Invalid arch.\n");
13483         return false;
13484     }
13485 
13486     EmulationStateARM before_state;
13487     EmulationStateARM after_state;
13488 
13489     value_sp = test_data->GetValueForKey (before_key);
13490     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13491     {
13492         out_stream->Printf ("TestEmulation:  Failed to find 'before' state.\n");
13493         return false;
13494     }
13495 
13496     OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary ();
13497     if (!before_state.LoadStateFromDictionary (state_dictionary))
13498     {
13499         out_stream->Printf ("TestEmulation:  Failed loading 'before' state.\n");
13500         return false;
13501     }
13502 
13503     value_sp = test_data->GetValueForKey (after_key);
13504     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13505     {
13506         out_stream->Printf ("TestEmulation:  Failed to find 'after' state.\n");
13507         return false;
13508     }
13509 
13510     state_dictionary = value_sp->GetAsDictionary ();
13511     if (!after_state.LoadStateFromDictionary (state_dictionary))
13512     {
13513         out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n");
13514         return false;
13515     }
13516 
13517     SetBaton ((void *) &before_state);
13518     SetCallbacks (&EmulationStateARM::ReadPseudoMemory,
13519                   &EmulationStateARM::WritePseudoMemory,
13520                   &EmulationStateARM::ReadPseudoRegister,
13521                   &EmulationStateARM::WritePseudoRegister);
13522 
13523     bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC);
13524     if (!success)
13525     {
13526         out_stream->Printf ("TestEmulation:  EvaluateInstruction() failed.\n");
13527         return false;
13528     }
13529 
13530     success = before_state.CompareState (after_state);
13531     if (!success)
13532         out_stream->Printf ("TestEmulation:  'before' and 'after' states do not match.\n");
13533 
13534     return success;
13535 }
13536 //
13537 //
13538 //const char *
13539 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
13540 //{
13541 //    if (reg_kind == eRegisterKindGeneric)
13542 //    {
13543 //        switch (reg_num)
13544 //        {
13545 //        case LLDB_REGNUM_GENERIC_PC:    return "pc";
13546 //        case LLDB_REGNUM_GENERIC_SP:    return "sp";
13547 //        case LLDB_REGNUM_GENERIC_FP:    return "fp";
13548 //        case LLDB_REGNUM_GENERIC_RA:    return "lr";
13549 //        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
13550 //        default: return NULL;
13551 //        }
13552 //    }
13553 //    else if (reg_kind == eRegisterKindDWARF)
13554 //    {
13555 //        return GetARMDWARFRegisterName (reg_num);
13556 //    }
13557 //    return NULL;
13558 //}
13559 //
13560 bool
13561 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
13562 {
13563     unwind_plan.Clear();
13564     unwind_plan.SetRegisterKind (eRegisterKindDWARF);
13565 
13566     UnwindPlan::Row row;
13567 
13568     // Our previous Call Frame Address is the stack pointer
13569     row.SetCFARegister (dwarf_sp);
13570 
13571     // Our previous PC is in the LR
13572     row.SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true);
13573     unwind_plan.AppendRow (row);
13574 
13575     // All other registers are the same.
13576 
13577     unwind_plan.SetSourceName ("EmulateInstructionARM");
13578     return true;
13579 }
13580 
13581 
13582 
13583 
13584