1 //===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include <stdlib.h>
11 
12 #include "EmulateInstructionARM.h"
13 #include "EmulationStateARM.h"
14 #include "lldb/Core/ArchSpec.h"
15 #include "lldb/Core/Address.h"
16 #include "lldb/Core/ConstString.h"
17 #include "lldb/Core/PluginManager.h"
18 #include "lldb/Core/Stream.h"
19 #include "lldb/Interpreter/OptionValueArray.h"
20 #include "lldb/Interpreter/OptionValueDictionary.h"
21 #include "lldb/Symbol/UnwindPlan.h"
22 
23 #include "Plugins/Process/Utility/ARMDefines.h"
24 #include "Plugins/Process/Utility/ARMUtils.h"
25 #include "Utility/ARM_DWARF_Registers.h"
26 
27 #include "llvm/Support/MathExtras.h" // for SignExtend32 template function
28                                      // and countTrailingZeros function
29 
30 using namespace lldb;
31 using namespace lldb_private;
32 
33 // Convenient macro definitions.
34 #define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS)
35 #define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS)
36 
37 #define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
38 
39 //----------------------------------------------------------------------
40 //
41 // ITSession implementation
42 //
43 //----------------------------------------------------------------------
44 
45 // A8.6.50
46 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
47 static uint32_t
48 CountITSize (uint32_t ITMask) {
49     // First count the trailing zeros of the IT mask.
50     uint32_t TZ = llvm::countTrailingZeros(ITMask);
51     if (TZ > 3)
52     {
53         printf("Encoding error: IT Mask '0000'\n");
54         return 0;
55     }
56     return (4 - TZ);
57 }
58 
59 // Init ITState.  Note that at least one bit is always 1 in mask.
60 bool ITSession::InitIT(uint32_t bits7_0)
61 {
62     ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
63     if (ITCounter == 0)
64         return false;
65 
66     // A8.6.50 IT
67     unsigned short FirstCond = Bits32(bits7_0, 7, 4);
68     if (FirstCond == 0xF)
69     {
70         printf("Encoding error: IT FirstCond '1111'\n");
71         return false;
72     }
73     if (FirstCond == 0xE && ITCounter != 1)
74     {
75         printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
76         return false;
77     }
78 
79     ITState = bits7_0;
80     return true;
81 }
82 
83 // Update ITState if necessary.
84 void ITSession::ITAdvance()
85 {
86     //assert(ITCounter);
87     --ITCounter;
88     if (ITCounter == 0)
89         ITState = 0;
90     else
91     {
92         unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
93         SetBits32(ITState, 4, 0, NewITState4_0);
94     }
95 }
96 
97 // Return true if we're inside an IT Block.
98 bool ITSession::InITBlock()
99 {
100     return ITCounter != 0;
101 }
102 
103 // Return true if we're the last instruction inside an IT Block.
104 bool ITSession::LastInITBlock()
105 {
106     return ITCounter == 1;
107 }
108 
109 // Get condition bits for the current thumb instruction.
110 uint32_t ITSession::GetCond()
111 {
112     if (InITBlock())
113         return Bits32(ITState, 7, 4);
114     else
115         return COND_AL;
116 }
117 
118 // ARM constants used during decoding
119 #define REG_RD          0
120 #define LDM_REGLIST     1
121 #define SP_REG          13
122 #define LR_REG          14
123 #define PC_REG          15
124 #define PC_REGLIST_BIT  0x8000
125 
126 #define ARMv4     (1u << 0)
127 #define ARMv4T    (1u << 1)
128 #define ARMv5T    (1u << 2)
129 #define ARMv5TE   (1u << 3)
130 #define ARMv5TEJ  (1u << 4)
131 #define ARMv6     (1u << 5)
132 #define ARMv6K    (1u << 6)
133 #define ARMv6T2   (1u << 7)
134 #define ARMv7     (1u << 8)
135 #define ARMv7S    (1u << 9)
136 #define ARMv8     (1u << 10)
137 #define ARMvAll   (0xffffffffu)
138 
139 #define ARMV4T_ABOVE  (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
140 #define ARMV5_ABOVE   (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
141 #define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
142 #define ARMV5J_ABOVE  (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
143 #define ARMV6_ABOVE   (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
144 #define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv7S|ARMv8)
145 #define ARMV7_ABOVE   (ARMv7|ARMv7S|ARMv8)
146 
147 #define No_VFP  0
148 #define VFPv1   (1u << 1)
149 #define VFPv2   (1u << 2)
150 #define VFPv3   (1u << 3)
151 #define AdvancedSIMD (1u << 4)
152 
153 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
154 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
155 #define VFPv2v3     (VFPv2 | VFPv3)
156 
157 //----------------------------------------------------------------------
158 //
159 // EmulateInstructionARM implementation
160 //
161 //----------------------------------------------------------------------
162 
163 void
164 EmulateInstructionARM::Initialize ()
165 {
166     PluginManager::RegisterPlugin (GetPluginNameStatic (),
167                                    GetPluginDescriptionStatic (),
168                                    CreateInstance);
169 }
170 
171 void
172 EmulateInstructionARM::Terminate ()
173 {
174     PluginManager::UnregisterPlugin (CreateInstance);
175 }
176 
177 ConstString
178 EmulateInstructionARM::GetPluginNameStatic ()
179 {
180     static ConstString g_name("arm");
181     return g_name;
182 }
183 
184 const char *
185 EmulateInstructionARM::GetPluginDescriptionStatic ()
186 {
187     return "Emulate instructions for the ARM architecture.";
188 }
189 
190 EmulateInstruction *
191 EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type)
192 {
193     if (EmulateInstructionARM::SupportsEmulatingIntructionsOfTypeStatic(inst_type))
194     {
195         if (arch.GetTriple().getArch() == llvm::Triple::arm)
196         {
197             std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
198 
199             if (emulate_insn_ap.get())
200                 return emulate_insn_ap.release();
201         }
202         else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
203         {
204             std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
205 
206             if (emulate_insn_ap.get())
207                 return emulate_insn_ap.release();
208         }
209     }
210 
211     return NULL;
212 }
213 
214 bool
215 EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch)
216 {
217     if (arch.GetTriple().getArch () == llvm::Triple::arm)
218         return true;
219     else if (arch.GetTriple().getArch () == llvm::Triple::thumb)
220         return true;
221 
222     return false;
223 }
224 
225 // Write "bits (32) UNKNOWN" to memory address "address".  Helper function for many ARM instructions.
226 bool
227 EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address)
228 {
229     EmulateInstruction::Context context;
230     context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
231     context.SetNoArgs ();
232 
233     uint32_t random_data = rand ();
234     const uint32_t addr_byte_size = GetAddressByteSize();
235 
236     if (!MemAWrite (context, address, random_data, addr_byte_size))
237         return false;
238 
239     return true;
240 }
241 
242 // Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM instructions.
243 bool
244 EmulateInstructionARM::WriteBits32Unknown (int n)
245 {
246     EmulateInstruction::Context context;
247     context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
248     context.SetNoArgs ();
249 
250     bool success;
251     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
252 
253     if (!success)
254         return false;
255 
256     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
257         return false;
258 
259     return true;
260 }
261 
262 bool
263 EmulateInstructionARM::GetRegisterInfo (uint32_t reg_kind, uint32_t reg_num, RegisterInfo &reg_info)
264 {
265     if (reg_kind == eRegisterKindGeneric)
266     {
267         switch (reg_num)
268         {
269             case LLDB_REGNUM_GENERIC_PC:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break;
270             case LLDB_REGNUM_GENERIC_SP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break;
271             case LLDB_REGNUM_GENERIC_FP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break;
272             case LLDB_REGNUM_GENERIC_RA:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break;
273             case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break;
274             default: return false;
275         }
276     }
277 
278     if (reg_kind == eRegisterKindDWARF)
279         return GetARMDWARFRegisterInfo(reg_num, reg_info);
280     return false;
281 }
282 
283 uint32_t
284 EmulateInstructionARM::GetFramePointerRegisterNumber () const
285 {
286     if (m_opcode_mode == eModeThumb)
287     {
288         switch (m_arch.GetTriple().getOS())
289         {
290             case llvm::Triple::Darwin:
291             case llvm::Triple::MacOSX:
292             case llvm::Triple::IOS:
293                 return 7;
294             default:
295                 break;
296         }
297     }
298     return 11;
299 }
300 
301 uint32_t
302 EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const
303 {
304     if (m_opcode_mode == eModeThumb)
305     {
306         switch (m_arch.GetTriple().getOS())
307         {
308             case llvm::Triple::Darwin:
309             case llvm::Triple::MacOSX:
310             case llvm::Triple::IOS:
311                 return dwarf_r7;
312             default:
313                 break;
314         }
315     }
316     return dwarf_r11;
317 }
318 
319 // Push Multiple Registers stores multiple registers to the stack, storing to
320 // consecutive memory locations ending just below the address in SP, and updates
321 // SP to point to the start of the stored data.
322 bool
323 EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding)
324 {
325 #if 0
326     // ARM pseudo code...
327     if (ConditionPassed())
328     {
329         EncodingSpecificOperations();
330         NullCheckIfThumbEE(13);
331         address = SP - 4*BitCount(registers);
332 
333         for (i = 0 to 14)
334         {
335             if (registers<i> == '1')
336             {
337                 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
338                     MemA[address,4] = bits(32) UNKNOWN;
339                 else
340                     MemA[address,4] = R[i];
341                 address = address + 4;
342             }
343         }
344 
345         if (registers<15> == '1') // Only possible for encoding A1 or A2
346             MemA[address,4] = PCStoreValue();
347 
348         SP = SP - 4*BitCount(registers);
349     }
350 #endif
351 
352     bool conditional = false;
353     bool success = false;
354     if (ConditionPassed(opcode, &conditional))
355     {
356         const uint32_t addr_byte_size = GetAddressByteSize();
357         const addr_t sp = ReadCoreReg (SP_REG, &success);
358         if (!success)
359             return false;
360         uint32_t registers = 0;
361         uint32_t Rt; // the source register
362         switch (encoding) {
363         case eEncodingT1:
364             registers = Bits32(opcode, 7, 0);
365             // The M bit represents LR.
366             if (Bit32(opcode, 8))
367                 registers |= (1u << 14);
368             // if BitCount(registers) < 1 then UNPREDICTABLE;
369             if (BitCount(registers) < 1)
370                 return false;
371             break;
372         case eEncodingT2:
373             // Ignore bits 15 & 13.
374             registers = Bits32(opcode, 15, 0) & ~0xa000;
375             // if BitCount(registers) < 2 then UNPREDICTABLE;
376             if (BitCount(registers) < 2)
377                 return false;
378             break;
379         case eEncodingT3:
380             Rt = Bits32(opcode, 15, 12);
381             // if BadReg(t) then UNPREDICTABLE;
382             if (BadReg(Rt))
383                 return false;
384             registers = (1u << Rt);
385             break;
386         case eEncodingA1:
387             registers = Bits32(opcode, 15, 0);
388             // Instead of return false, let's handle the following case as well,
389             // which amounts to pushing one reg onto the full descending stacks.
390             // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
391             break;
392         case eEncodingA2:
393             Rt = Bits32(opcode, 15, 12);
394             // if t == 13 then UNPREDICTABLE;
395             if (Rt == dwarf_sp)
396                 return false;
397             registers = (1u << Rt);
398             break;
399         default:
400             return false;
401         }
402         addr_t sp_offset = addr_byte_size * BitCount (registers);
403         addr_t addr = sp - sp_offset;
404         uint32_t i;
405 
406         EmulateInstruction::Context context;
407         if (conditional)
408             context.type = EmulateInstruction::eContextRegisterStore;
409         else
410             context.type = EmulateInstruction::eContextPushRegisterOnStack;
411         RegisterInfo reg_info;
412         RegisterInfo sp_reg;
413         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
414         for (i=0; i<15; ++i)
415         {
416             if (BitIsSet (registers, i))
417             {
418                 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info);
419                 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
420                 uint32_t reg_value = ReadCoreReg(i, &success);
421                 if (!success)
422                     return false;
423                 if (!MemAWrite (context, addr, reg_value, addr_byte_size))
424                     return false;
425                 addr += addr_byte_size;
426             }
427         }
428 
429         if (BitIsSet (registers, 15))
430         {
431             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info);
432             context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
433             const uint32_t pc = ReadCoreReg(PC_REG, &success);
434             if (!success)
435                 return false;
436             if (!MemAWrite (context, addr, pc, addr_byte_size))
437                 return false;
438         }
439 
440         context.type = EmulateInstruction::eContextAdjustStackPointer;
441         context.SetImmediateSigned (-sp_offset);
442 
443         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
444             return false;
445     }
446     return true;
447 }
448 
449 // Pop Multiple Registers loads multiple registers from the stack, loading from
450 // consecutive memory locations staring at the address in SP, and updates
451 // SP to point just above the loaded data.
452 bool
453 EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding)
454 {
455 #if 0
456     // ARM pseudo code...
457     if (ConditionPassed())
458     {
459         EncodingSpecificOperations(); NullCheckIfThumbEE(13);
460         address = SP;
461         for i = 0 to 14
462             if registers<i> == '1' then
463                 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
464         if registers<15> == '1' then
465             if UnalignedAllowed then
466                 LoadWritePC(MemU[address,4]);
467             else
468                 LoadWritePC(MemA[address,4]);
469         if registers<13> == '0' then SP = SP + 4*BitCount(registers);
470         if registers<13> == '1' then SP = bits(32) UNKNOWN;
471     }
472 #endif
473 
474     bool success = false;
475 
476     bool conditional = false;
477     if (ConditionPassed(opcode, &conditional))
478     {
479         const uint32_t addr_byte_size = GetAddressByteSize();
480         const addr_t sp = ReadCoreReg (SP_REG, &success);
481         if (!success)
482             return false;
483         uint32_t registers = 0;
484         uint32_t Rt; // the destination register
485         switch (encoding) {
486         case eEncodingT1:
487             registers = Bits32(opcode, 7, 0);
488             // The P bit represents PC.
489             if (Bit32(opcode, 8))
490                 registers |= (1u << 15);
491             // if BitCount(registers) < 1 then UNPREDICTABLE;
492             if (BitCount(registers) < 1)
493                 return false;
494             break;
495         case eEncodingT2:
496             // Ignore bit 13.
497             registers = Bits32(opcode, 15, 0) & ~0x2000;
498             // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
499             if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
500                 return false;
501             // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
502             if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
503                 return false;
504             break;
505         case eEncodingT3:
506             Rt = Bits32(opcode, 15, 12);
507             // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
508             if (Rt == 13)
509                 return false;
510             if (Rt == 15 && InITBlock() && !LastInITBlock())
511                 return false;
512             registers = (1u << Rt);
513             break;
514         case eEncodingA1:
515             registers = Bits32(opcode, 15, 0);
516             // Instead of return false, let's handle the following case as well,
517             // which amounts to popping one reg from the full descending stacks.
518             // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
519 
520             // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
521             if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
522                 return false;
523             break;
524         case eEncodingA2:
525             Rt = Bits32(opcode, 15, 12);
526             // if t == 13 then UNPREDICTABLE;
527             if (Rt == dwarf_sp)
528                 return false;
529             registers = (1u << Rt);
530             break;
531         default:
532             return false;
533         }
534         addr_t sp_offset = addr_byte_size * BitCount (registers);
535         addr_t addr = sp;
536         uint32_t i, data;
537 
538         EmulateInstruction::Context context;
539         if (conditional)
540             context.type = EmulateInstruction::eContextRegisterLoad;
541         else
542             context.type = EmulateInstruction::eContextPopRegisterOffStack;
543 
544         RegisterInfo sp_reg;
545         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
546 
547         for (i=0; i<15; ++i)
548         {
549             if (BitIsSet (registers, i))
550             {
551                 context.SetRegisterPlusOffset (sp_reg, addr - sp);
552                 data = MemARead(context, addr, 4, 0, &success);
553                 if (!success)
554                     return false;
555                 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data))
556                     return false;
557                 addr += addr_byte_size;
558             }
559         }
560 
561         if (BitIsSet (registers, 15))
562         {
563             context.SetRegisterPlusOffset (sp_reg, addr - sp);
564             data = MemARead(context, addr, 4, 0, &success);
565             if (!success)
566                 return false;
567             // In ARMv5T and above, this is an interworking branch.
568             if (!LoadWritePC(context, data))
569                 return false;
570             //addr += addr_byte_size;
571         }
572 
573         context.type = EmulateInstruction::eContextAdjustStackPointer;
574         context.SetImmediateSigned (sp_offset);
575 
576         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
577             return false;
578     }
579     return true;
580 }
581 
582 // Set r7 or ip to point to saved value residing within the stack.
583 // ADD (SP plus immediate)
584 bool
585 EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding)
586 {
587 #if 0
588     // ARM pseudo code...
589     if (ConditionPassed())
590     {
591         EncodingSpecificOperations();
592         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
593         if d == 15 then
594            ALUWritePC(result); // setflags is always FALSE here
595         else
596             R[d] = result;
597             if setflags then
598                 APSR.N = result<31>;
599                 APSR.Z = IsZeroBit(result);
600                 APSR.C = carry;
601                 APSR.V = overflow;
602     }
603 #endif
604 
605     bool success = false;
606 
607     if (ConditionPassed(opcode))
608     {
609         const addr_t sp = ReadCoreReg (SP_REG, &success);
610         if (!success)
611             return false;
612         uint32_t Rd; // the destination register
613         uint32_t imm32;
614         switch (encoding) {
615         case eEncodingT1:
616             Rd = 7;
617             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
618             break;
619         case eEncodingA1:
620             Rd = Bits32(opcode, 15, 12);
621             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
622             break;
623         default:
624             return false;
625         }
626         addr_t sp_offset = imm32;
627         addr_t addr = sp + sp_offset; // a pointer to the stack area
628 
629         EmulateInstruction::Context context;
630         context.type = eContextSetFramePointer;
631         RegisterInfo sp_reg;
632         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
633         context.SetRegisterPlusOffset (sp_reg, sp_offset);
634 
635         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
636             return false;
637     }
638     return true;
639 }
640 
641 // Set r7 or ip to the current stack pointer.
642 // MOV (register)
643 bool
644 EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding)
645 {
646 #if 0
647     // ARM pseudo code...
648     if (ConditionPassed())
649     {
650         EncodingSpecificOperations();
651         result = R[m];
652         if d == 15 then
653             ALUWritePC(result); // setflags is always FALSE here
654         else
655             R[d] = result;
656             if setflags then
657                 APSR.N = result<31>;
658                 APSR.Z = IsZeroBit(result);
659                 // APSR.C unchanged
660                 // APSR.V unchanged
661     }
662 #endif
663 
664     bool success = false;
665 
666     if (ConditionPassed(opcode))
667     {
668         const addr_t sp = ReadCoreReg (SP_REG, &success);
669         if (!success)
670             return false;
671         uint32_t Rd; // the destination register
672         switch (encoding) {
673         case eEncodingT1:
674             Rd = 7;
675             break;
676         case eEncodingA1:
677             Rd = 12;
678             break;
679         default:
680             return false;
681         }
682 
683         EmulateInstruction::Context context;
684         if (Rd == GetFramePointerRegisterNumber())
685             context.type = EmulateInstruction::eContextSetFramePointer;
686         else
687             context.type = EmulateInstruction::eContextRegisterPlusOffset;
688         RegisterInfo sp_reg;
689         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
690         context.SetRegisterPlusOffset (sp_reg, 0);
691 
692         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
693             return false;
694     }
695     return true;
696 }
697 
698 // Move from high register (r8-r15) to low register (r0-r7).
699 // MOV (register)
700 bool
701 EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding)
702 {
703     return EmulateMOVRdRm (opcode, encoding);
704 }
705 
706 // Move from register to register.
707 // MOV (register)
708 bool
709 EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding)
710 {
711 #if 0
712     // ARM pseudo code...
713     if (ConditionPassed())
714     {
715         EncodingSpecificOperations();
716         result = R[m];
717         if d == 15 then
718             ALUWritePC(result); // setflags is always FALSE here
719         else
720             R[d] = result;
721             if setflags then
722                 APSR.N = result<31>;
723                 APSR.Z = IsZeroBit(result);
724                 // APSR.C unchanged
725                 // APSR.V unchanged
726     }
727 #endif
728 
729     bool success = false;
730 
731     if (ConditionPassed(opcode))
732     {
733         uint32_t Rm; // the source register
734         uint32_t Rd; // the destination register
735         bool setflags;
736         switch (encoding) {
737         case eEncodingT1:
738             Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
739             Rm = Bits32(opcode, 6, 3);
740             setflags = false;
741             if (Rd == 15 && InITBlock() && !LastInITBlock())
742                 return false;
743             break;
744         case eEncodingT2:
745             Rd = Bits32(opcode, 2, 0);
746             Rm = Bits32(opcode, 5, 3);
747             setflags = true;
748             if (InITBlock())
749                 return false;
750             break;
751         case eEncodingT3:
752             Rd = Bits32(opcode, 11, 8);
753             Rm = Bits32(opcode, 3, 0);
754             setflags = BitIsSet(opcode, 20);
755             // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
756             if (setflags && (BadReg(Rd) || BadReg(Rm)))
757                 return false;
758             // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE;
759             if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
760                 return false;
761             break;
762         case eEncodingA1:
763             Rd = Bits32(opcode, 15, 12);
764             Rm = Bits32(opcode, 3, 0);
765             setflags = BitIsSet(opcode, 20);
766 
767             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
768             if (Rd == 15 && setflags)
769                 return EmulateSUBSPcLrEtc (opcode, encoding);
770             break;
771         default:
772             return false;
773         }
774         uint32_t result = ReadCoreReg(Rm, &success);
775         if (!success)
776             return false;
777 
778         // The context specifies that Rm is to be moved into Rd.
779         EmulateInstruction::Context context;
780         context.type = EmulateInstruction::eContextRegisterLoad;
781         RegisterInfo dwarf_reg;
782         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
783         context.SetRegister (dwarf_reg);
784 
785         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
786             return false;
787     }
788     return true;
789 }
790 
791 // Move (immediate) writes an immediate value to the destination register.  It
792 // can optionally update the condition flags based on the value.
793 // MOV (immediate)
794 bool
795 EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding)
796 {
797 #if 0
798     // ARM pseudo code...
799     if (ConditionPassed())
800     {
801         EncodingSpecificOperations();
802         result = imm32;
803         if d == 15 then         // Can only occur for ARM encoding
804             ALUWritePC(result); // setflags is always FALSE here
805         else
806             R[d] = result;
807             if setflags then
808                 APSR.N = result<31>;
809                 APSR.Z = IsZeroBit(result);
810                 APSR.C = carry;
811                 // APSR.V unchanged
812     }
813 #endif
814 
815     if (ConditionPassed(opcode))
816     {
817         uint32_t Rd; // the destination register
818         uint32_t imm32; // the immediate value to be written to Rd
819         uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
820                             // for setflags == false, this value is a don't care
821                             // initialized to 0 to silence the static analyzer
822         bool setflags;
823         switch (encoding) {
824             case eEncodingT1:
825                 Rd = Bits32(opcode, 10, 8);
826                 setflags = !InITBlock();
827                 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
828                 carry = APSR_C;
829 
830                 break;
831 
832             case eEncodingT2:
833                 Rd = Bits32(opcode, 11, 8);
834                 setflags = BitIsSet(opcode, 20);
835                 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
836                 if (BadReg(Rd))
837                   return false;
838 
839                 break;
840 
841             case eEncodingT3:
842             {
843                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32);
844                 Rd = Bits32 (opcode, 11, 8);
845                 setflags = false;
846                 uint32_t imm4 = Bits32 (opcode, 19, 16);
847                 uint32_t imm3 = Bits32 (opcode, 14, 12);
848                 uint32_t i = Bit32 (opcode, 26);
849                 uint32_t imm8 = Bits32 (opcode, 7, 0);
850                 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
851 
852                 // if BadReg(d) then UNPREDICTABLE;
853                 if (BadReg (Rd))
854                     return false;
855             }
856                 break;
857 
858             case eEncodingA1:
859                 // d = UInt(Rd); setflags = (S == �1�); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C);
860                 Rd = Bits32 (opcode, 15, 12);
861                 setflags = BitIsSet (opcode, 20);
862                 imm32 = ARMExpandImm_C (opcode, APSR_C, carry);
863 
864                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
865                 if ((Rd == 15) && setflags)
866                     return EmulateSUBSPcLrEtc (opcode, encoding);
867 
868                 break;
869 
870             case eEncodingA2:
871             {
872                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
873                 Rd = Bits32 (opcode, 15, 12);
874                 setflags = false;
875                 uint32_t imm4 = Bits32 (opcode, 19, 16);
876                 uint32_t imm12 = Bits32 (opcode, 11, 0);
877                 imm32 = (imm4 << 12) | imm12;
878 
879                 // if d == 15 then UNPREDICTABLE;
880                 if (Rd == 15)
881                     return false;
882             }
883                 break;
884 
885             default:
886                 return false;
887         }
888         uint32_t result = imm32;
889 
890         // The context specifies that an immediate is to be moved into Rd.
891         EmulateInstruction::Context context;
892         context.type = EmulateInstruction::eContextImmediate;
893         context.SetNoArgs ();
894 
895         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
896             return false;
897     }
898     return true;
899 }
900 
901 // MUL multiplies two register values.  The least significant 32 bits of the result are written to the destination
902 // register.  These 32 bits do not depend on whether the source register values are considered to be signed values or
903 // unsigned values.
904 //
905 // Optionally, it can update the condition flags based on the result.  In the Thumb instruction set, this option is
906 // limited to only a few forms of the instruction.
907 bool
908 EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding)
909 {
910 #if 0
911     if ConditionPassed() then
912         EncodingSpecificOperations();
913         operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
914         operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
915         result = operand1 * operand2;
916         R[d] = result<31:0>;
917         if setflags then
918             APSR.N = result<31>;
919             APSR.Z = IsZeroBit(result);
920             if ArchVersion() == 4 then
921                 APSR.C = bit UNKNOWN;
922             // else APSR.C unchanged
923             // APSR.V always unchanged
924 #endif
925 
926     if (ConditionPassed(opcode))
927     {
928         uint32_t d;
929         uint32_t n;
930         uint32_t m;
931         bool setflags;
932 
933         // EncodingSpecificOperations();
934         switch (encoding)
935         {
936             case eEncodingT1:
937                 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
938                 d = Bits32 (opcode, 2, 0);
939                 n = Bits32 (opcode, 5, 3);
940                 m = Bits32 (opcode, 2, 0);
941                 setflags = !InITBlock();
942 
943                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
944                 if ((ArchVersion() < ARMv6) && (d == n))
945                     return false;
946 
947                 break;
948 
949             case eEncodingT2:
950                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
951                 d = Bits32 (opcode, 11, 8);
952                 n = Bits32 (opcode, 19, 16);
953                 m = Bits32 (opcode, 3, 0);
954                 setflags = false;
955 
956                 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
957                 if (BadReg (d) || BadReg (n) || BadReg (m))
958                     return false;
959 
960                 break;
961 
962             case eEncodingA1:
963                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
964                 d = Bits32 (opcode, 19, 16);
965                 n = Bits32 (opcode, 3, 0);
966                 m = Bits32 (opcode, 11, 8);
967                 setflags = BitIsSet (opcode, 20);
968 
969                 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
970                 if ((d == 15) ||  (n == 15) || (m == 15))
971                     return false;
972 
973                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
974                 if ((ArchVersion() < ARMv6) && (d == n))
975                     return false;
976 
977                 break;
978 
979             default:
980                 return false;
981         }
982 
983         bool success = false;
984 
985         // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
986         uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
987         if (!success)
988             return false;
989 
990         // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
991         uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
992         if (!success)
993             return false;
994 
995         // result = operand1 * operand2;
996         uint64_t result = operand1 * operand2;
997 
998         // R[d] = result<31:0>;
999         RegisterInfo op1_reg;
1000         RegisterInfo op2_reg;
1001         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
1002         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
1003 
1004         EmulateInstruction::Context context;
1005         context.type = eContextArithmetic;
1006         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
1007 
1008         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result)))
1009             return false;
1010 
1011         // if setflags then
1012         if (setflags)
1013         {
1014             // APSR.N = result<31>;
1015             // APSR.Z = IsZeroBit(result);
1016             m_new_inst_cpsr = m_opcode_cpsr;
1017             SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31));
1018             SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1019             if (m_new_inst_cpsr != m_opcode_cpsr)
1020             {
1021                 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1022                     return false;
1023             }
1024 
1025             // if ArchVersion() == 4 then
1026                 // APSR.C = bit UNKNOWN;
1027         }
1028     }
1029     return true;
1030 }
1031 
1032 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register.
1033 // It can optionally update the condition flags based on the value.
1034 bool
1035 EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding)
1036 {
1037 #if 0
1038     // ARM pseudo code...
1039     if (ConditionPassed())
1040     {
1041         EncodingSpecificOperations();
1042         result = NOT(imm32);
1043         if d == 15 then         // Can only occur for ARM encoding
1044             ALUWritePC(result); // setflags is always FALSE here
1045         else
1046             R[d] = result;
1047             if setflags then
1048                 APSR.N = result<31>;
1049                 APSR.Z = IsZeroBit(result);
1050                 APSR.C = carry;
1051                 // APSR.V unchanged
1052     }
1053 #endif
1054 
1055     if (ConditionPassed(opcode))
1056     {
1057         uint32_t Rd; // the destination register
1058         uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1059         uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1060         bool setflags;
1061         switch (encoding) {
1062         case eEncodingT1:
1063             Rd = Bits32(opcode, 11, 8);
1064             setflags = BitIsSet(opcode, 20);
1065             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1066             break;
1067         case eEncodingA1:
1068             Rd = Bits32(opcode, 15, 12);
1069             setflags = BitIsSet(opcode, 20);
1070             imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1071 
1072             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1073             if (Rd == 15 && setflags)
1074                 return EmulateSUBSPcLrEtc (opcode, encoding);
1075             break;
1076         default:
1077             return false;
1078         }
1079         uint32_t result = ~imm32;
1080 
1081         // The context specifies that an immediate is to be moved into Rd.
1082         EmulateInstruction::Context context;
1083         context.type = EmulateInstruction::eContextImmediate;
1084         context.SetNoArgs ();
1085 
1086         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1087             return false;
1088     }
1089     return true;
1090 }
1091 
1092 // Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register.
1093 // It can optionally update the condition flags based on the result.
1094 bool
1095 EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding)
1096 {
1097 #if 0
1098     // ARM pseudo code...
1099     if (ConditionPassed())
1100     {
1101         EncodingSpecificOperations();
1102         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1103         result = NOT(shifted);
1104         if d == 15 then         // Can only occur for ARM encoding
1105             ALUWritePC(result); // setflags is always FALSE here
1106         else
1107             R[d] = result;
1108             if setflags then
1109                 APSR.N = result<31>;
1110                 APSR.Z = IsZeroBit(result);
1111                 APSR.C = carry;
1112                 // APSR.V unchanged
1113     }
1114 #endif
1115 
1116     if (ConditionPassed(opcode))
1117     {
1118         uint32_t Rm; // the source register
1119         uint32_t Rd; // the destination register
1120         ARM_ShifterType shift_t;
1121         uint32_t shift_n; // the shift applied to the value read from Rm
1122         bool setflags;
1123         uint32_t carry; // the carry bit after the shift operation
1124         switch (encoding) {
1125         case eEncodingT1:
1126             Rd = Bits32(opcode, 2, 0);
1127             Rm = Bits32(opcode, 5, 3);
1128             setflags = !InITBlock();
1129             shift_t = SRType_LSL;
1130             shift_n = 0;
1131             if (InITBlock())
1132                 return false;
1133             break;
1134         case eEncodingT2:
1135             Rd = Bits32(opcode, 11, 8);
1136             Rm = Bits32(opcode, 3, 0);
1137             setflags = BitIsSet(opcode, 20);
1138             shift_n = DecodeImmShiftThumb(opcode, shift_t);
1139             // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1140             if (BadReg(Rd) || BadReg(Rm))
1141                 return false;
1142             break;
1143         case eEncodingA1:
1144             Rd = Bits32(opcode, 15, 12);
1145             Rm = Bits32(opcode, 3, 0);
1146             setflags = BitIsSet(opcode, 20);
1147             shift_n = DecodeImmShiftARM(opcode, shift_t);
1148             break;
1149         default:
1150             return false;
1151         }
1152         bool success = false;
1153         uint32_t value = ReadCoreReg(Rm, &success);
1154         if (!success)
1155             return false;
1156 
1157         uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1158         if (!success)
1159             return false;
1160         uint32_t result = ~shifted;
1161 
1162         // The context specifies that an immediate is to be moved into Rd.
1163         EmulateInstruction::Context context;
1164         context.type = EmulateInstruction::eContextImmediate;
1165         context.SetNoArgs ();
1166 
1167         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1168             return false;
1169     }
1170     return true;
1171 }
1172 
1173 // PC relative immediate load into register, possibly followed by ADD (SP plus register).
1174 // LDR (literal)
1175 bool
1176 EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding)
1177 {
1178 #if 0
1179     // ARM pseudo code...
1180     if (ConditionPassed())
1181     {
1182         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1183         base = Align(PC,4);
1184         address = if add then (base + imm32) else (base - imm32);
1185         data = MemU[address,4];
1186         if t == 15 then
1187             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1188         elsif UnalignedSupport() || address<1:0> = '00' then
1189             R[t] = data;
1190         else // Can only apply before ARMv7
1191             if CurrentInstrSet() == InstrSet_ARM then
1192                 R[t] = ROR(data, 8*UInt(address<1:0>));
1193             else
1194                 R[t] = bits(32) UNKNOWN;
1195     }
1196 #endif
1197 
1198     if (ConditionPassed(opcode))
1199     {
1200         bool success = false;
1201         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1202         if (!success)
1203             return false;
1204 
1205         // PC relative immediate load context
1206         EmulateInstruction::Context context;
1207         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1208         RegisterInfo pc_reg;
1209         GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
1210         context.SetRegisterPlusOffset (pc_reg, 0);
1211 
1212         uint32_t Rt;    // the destination register
1213         uint32_t imm32; // immediate offset from the PC
1214         bool add;       // +imm32 or -imm32?
1215         addr_t base;    // the base address
1216         addr_t address; // the PC relative address
1217         uint32_t data;  // the literal data value from the PC relative load
1218         switch (encoding) {
1219         case eEncodingT1:
1220             Rt = Bits32(opcode, 10, 8);
1221             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1222             add = true;
1223             break;
1224         case eEncodingT2:
1225             Rt = Bits32(opcode, 15, 12);
1226             imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1227             add = BitIsSet(opcode, 23);
1228             if (Rt == 15 && InITBlock() && !LastInITBlock())
1229                 return false;
1230             break;
1231         default:
1232             return false;
1233         }
1234 
1235         base = Align(pc, 4);
1236         if (add)
1237             address = base + imm32;
1238         else
1239             address = base - imm32;
1240 
1241         context.SetRegisterPlusOffset(pc_reg, address - base);
1242         data = MemURead(context, address, 4, 0, &success);
1243         if (!success)
1244             return false;
1245 
1246         if (Rt == 15)
1247         {
1248             if (Bits32(address, 1, 0) == 0)
1249             {
1250                 // In ARMv5T and above, this is an interworking branch.
1251                 if (!LoadWritePC(context, data))
1252                     return false;
1253             }
1254             else
1255                 return false;
1256         }
1257         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
1258         {
1259             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
1260                 return false;
1261         }
1262         else // We don't handle ARM for now.
1263             return false;
1264 
1265     }
1266     return true;
1267 }
1268 
1269 // An add operation to adjust the SP.
1270 // ADD (SP plus immediate)
1271 bool
1272 EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding)
1273 {
1274 #if 0
1275     // ARM pseudo code...
1276     if (ConditionPassed())
1277     {
1278         EncodingSpecificOperations();
1279         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1280         if d == 15 then // Can only occur for ARM encoding
1281             ALUWritePC(result); // setflags is always FALSE here
1282         else
1283             R[d] = result;
1284             if setflags then
1285                 APSR.N = result<31>;
1286                 APSR.Z = IsZeroBit(result);
1287                 APSR.C = carry;
1288                 APSR.V = overflow;
1289     }
1290 #endif
1291 
1292     bool success = false;
1293 
1294     if (ConditionPassed(opcode))
1295     {
1296         const addr_t sp = ReadCoreReg (SP_REG, &success);
1297         if (!success)
1298             return false;
1299         uint32_t imm32; // the immediate operand
1300         uint32_t d;
1301         //bool setflags = false; // Add this back if/when support eEncodingT3 eEncodingA1
1302         switch (encoding)
1303         {
1304             case eEncodingT1:
1305                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1306                 d = Bits32 (opcode, 10, 8);
1307                 imm32 = (Bits32 (opcode, 7, 0) << 2);
1308 
1309                 break;
1310 
1311             case eEncodingT2:
1312                 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1313                 d = 13;
1314                 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1315 
1316                 break;
1317 
1318             default:
1319                 return false;
1320         }
1321         addr_t sp_offset = imm32;
1322         addr_t addr = sp + sp_offset; // the adjusted stack pointer value
1323 
1324         EmulateInstruction::Context context;
1325         context.type = EmulateInstruction::eContextAdjustStackPointer;
1326         RegisterInfo sp_reg;
1327         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1328         context.SetRegisterPlusOffset (sp_reg, sp_offset);
1329 
1330         if (d == 15)
1331         {
1332             if (!ALUWritePC (context, addr))
1333                 return false;
1334         }
1335         else
1336         {
1337             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr))
1338                 return false;
1339 
1340             // Add this back if/when support eEncodingT3 eEncodingA1
1341             //if (setflags)
1342             //{
1343             //    APSR.N = result<31>;
1344             //    APSR.Z = IsZeroBit(result);
1345             //    APSR.C = carry;
1346             //    APSR.V = overflow;
1347             //}
1348         }
1349     }
1350     return true;
1351 }
1352 
1353 // An add operation to adjust the SP.
1354 // ADD (SP plus register)
1355 bool
1356 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding)
1357 {
1358 #if 0
1359     // ARM pseudo code...
1360     if (ConditionPassed())
1361     {
1362         EncodingSpecificOperations();
1363         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1364         (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1365         if d == 15 then
1366             ALUWritePC(result); // setflags is always FALSE here
1367         else
1368             R[d] = result;
1369             if setflags then
1370                 APSR.N = result<31>;
1371                 APSR.Z = IsZeroBit(result);
1372                 APSR.C = carry;
1373                 APSR.V = overflow;
1374     }
1375 #endif
1376 
1377     bool success = false;
1378 
1379     if (ConditionPassed(opcode))
1380     {
1381         const addr_t sp = ReadCoreReg (SP_REG, &success);
1382         if (!success)
1383             return false;
1384         uint32_t Rm; // the second operand
1385         switch (encoding) {
1386         case eEncodingT2:
1387             Rm = Bits32(opcode, 6, 3);
1388             break;
1389         default:
1390             return false;
1391         }
1392         int32_t reg_value = ReadCoreReg(Rm, &success);
1393         if (!success)
1394             return false;
1395 
1396         addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1397 
1398         EmulateInstruction::Context context;
1399         context.type = eContextArithmetic;
1400         RegisterInfo sp_reg;
1401         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1402 
1403         RegisterInfo other_reg;
1404         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1405         context.SetRegisterRegisterOperands (sp_reg, other_reg);
1406 
1407         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
1408             return false;
1409     }
1410     return true;
1411 }
1412 
1413 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
1414 // at a PC-relative address, and changes instruction set from ARM to Thumb, or
1415 // from Thumb to ARM.
1416 // BLX (immediate)
1417 bool
1418 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding)
1419 {
1420 #if 0
1421     // ARM pseudo code...
1422     if (ConditionPassed())
1423     {
1424         EncodingSpecificOperations();
1425         if CurrentInstrSet() == InstrSet_ARM then
1426             LR = PC - 4;
1427         else
1428             LR = PC<31:1> : '1';
1429         if targetInstrSet == InstrSet_ARM then
1430             targetAddress = Align(PC,4) + imm32;
1431         else
1432             targetAddress = PC + imm32;
1433         SelectInstrSet(targetInstrSet);
1434         BranchWritePC(targetAddress);
1435     }
1436 #endif
1437 
1438     bool success = true;
1439 
1440     if (ConditionPassed(opcode))
1441     {
1442         EmulateInstruction::Context context;
1443         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1444         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1445         if (!success)
1446             return false;
1447         addr_t lr; // next instruction address
1448         addr_t target; // target address
1449         int32_t imm32; // PC-relative offset
1450         switch (encoding) {
1451         case eEncodingT1:
1452             {
1453             lr = pc | 1u; // return address
1454             uint32_t S = Bit32(opcode, 26);
1455             uint32_t imm10 = Bits32(opcode, 25, 16);
1456             uint32_t J1 = Bit32(opcode, 13);
1457             uint32_t J2 = Bit32(opcode, 11);
1458             uint32_t imm11 = Bits32(opcode, 10, 0);
1459             uint32_t I1 = !(J1 ^ S);
1460             uint32_t I2 = !(J2 ^ S);
1461             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1462             imm32 = llvm::SignExtend32<25>(imm25);
1463             target = pc + imm32;
1464             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
1465             if (InITBlock() && !LastInITBlock())
1466                 return false;
1467             break;
1468             }
1469         case eEncodingT2:
1470             {
1471             lr = pc | 1u; // return address
1472             uint32_t S = Bit32(opcode, 26);
1473             uint32_t imm10H = Bits32(opcode, 25, 16);
1474             uint32_t J1 = Bit32(opcode, 13);
1475             uint32_t J2 = Bit32(opcode, 11);
1476             uint32_t imm10L = Bits32(opcode, 10, 1);
1477             uint32_t I1 = !(J1 ^ S);
1478             uint32_t I2 = !(J2 ^ S);
1479             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
1480             imm32 = llvm::SignExtend32<25>(imm25);
1481             target = Align(pc, 4) + imm32;
1482             context.SetISAAndImmediateSigned (eModeARM, 4 + imm32);
1483             if (InITBlock() && !LastInITBlock())
1484                 return false;
1485             break;
1486             }
1487         case eEncodingA1:
1488             lr = pc - 4; // return address
1489             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1490             target = Align(pc, 4) + imm32;
1491             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
1492             break;
1493         case eEncodingA2:
1494             lr = pc - 4; // return address
1495             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
1496             target = pc + imm32;
1497             context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32);
1498             break;
1499         default:
1500             return false;
1501         }
1502         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1503             return false;
1504         if (!BranchWritePC(context, target))
1505             return false;
1506     }
1507     return true;
1508 }
1509 
1510 // Branch with Link and Exchange (register) calls a subroutine at an address and
1511 // instruction set specified by a register.
1512 // BLX (register)
1513 bool
1514 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding)
1515 {
1516 #if 0
1517     // ARM pseudo code...
1518     if (ConditionPassed())
1519     {
1520         EncodingSpecificOperations();
1521         target = R[m];
1522         if CurrentInstrSet() == InstrSet_ARM then
1523             next_instr_addr = PC - 4;
1524             LR = next_instr_addr;
1525         else
1526             next_instr_addr = PC - 2;
1527             LR = next_instr_addr<31:1> : '1';
1528         BXWritePC(target);
1529     }
1530 #endif
1531 
1532     bool success = false;
1533 
1534     if (ConditionPassed(opcode))
1535     {
1536         EmulateInstruction::Context context;
1537         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1538         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1539         addr_t lr; // next instruction address
1540         if (!success)
1541             return false;
1542         uint32_t Rm; // the register with the target address
1543         switch (encoding) {
1544         case eEncodingT1:
1545             lr = (pc - 2) | 1u; // return address
1546             Rm = Bits32(opcode, 6, 3);
1547             // if m == 15 then UNPREDICTABLE;
1548             if (Rm == 15)
1549                 return false;
1550             if (InITBlock() && !LastInITBlock())
1551                 return false;
1552             break;
1553         case eEncodingA1:
1554             lr = pc - 4; // return address
1555             Rm = Bits32(opcode, 3, 0);
1556             // if m == 15 then UNPREDICTABLE;
1557             if (Rm == 15)
1558                 return false;
1559             break;
1560         default:
1561             return false;
1562         }
1563         addr_t target = ReadCoreReg (Rm, &success);
1564         if (!success)
1565             return false;
1566         RegisterInfo dwarf_reg;
1567         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1568         context.SetRegister (dwarf_reg);
1569         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1570             return false;
1571         if (!BXWritePC(context, target))
1572             return false;
1573     }
1574     return true;
1575 }
1576 
1577 // Branch and Exchange causes a branch to an address and instruction set specified by a register.
1578 bool
1579 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding)
1580 {
1581 #if 0
1582     // ARM pseudo code...
1583     if (ConditionPassed())
1584     {
1585         EncodingSpecificOperations();
1586         BXWritePC(R[m]);
1587     }
1588 #endif
1589 
1590     if (ConditionPassed(opcode))
1591     {
1592         EmulateInstruction::Context context;
1593         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1594         uint32_t Rm; // the register with the target address
1595         switch (encoding) {
1596         case eEncodingT1:
1597             Rm = Bits32(opcode, 6, 3);
1598             if (InITBlock() && !LastInITBlock())
1599                 return false;
1600             break;
1601         case eEncodingA1:
1602             Rm = Bits32(opcode, 3, 0);
1603             break;
1604         default:
1605             return false;
1606         }
1607         bool success = false;
1608         addr_t target = ReadCoreReg (Rm, &success);
1609         if (!success)
1610             return false;
1611 
1612         RegisterInfo dwarf_reg;
1613         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1614         context.SetRegister (dwarf_reg);
1615         if (!BXWritePC(context, target))
1616             return false;
1617     }
1618     return true;
1619 }
1620 
1621 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an
1622 // address and instruction set specified by a register as though it were a BX instruction.
1623 //
1624 // TODO: Emulate Jazelle architecture?
1625 //       We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation.
1626 bool
1627 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding)
1628 {
1629 #if 0
1630     // ARM pseudo code...
1631     if (ConditionPassed())
1632     {
1633         EncodingSpecificOperations();
1634         if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
1635             BXWritePC(R[m]);
1636         else
1637             if JazelleAcceptsExecution() then
1638                 SwitchToJazelleExecution();
1639             else
1640                 SUBARCHITECTURE_DEFINED handler call;
1641     }
1642 #endif
1643 
1644     if (ConditionPassed(opcode))
1645     {
1646         EmulateInstruction::Context context;
1647         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1648         uint32_t Rm; // the register with the target address
1649         switch (encoding) {
1650         case eEncodingT1:
1651             Rm = Bits32(opcode, 19, 16);
1652             if (BadReg(Rm))
1653                 return false;
1654             if (InITBlock() && !LastInITBlock())
1655                 return false;
1656             break;
1657         case eEncodingA1:
1658             Rm = Bits32(opcode, 3, 0);
1659             if (Rm == 15)
1660                 return false;
1661             break;
1662         default:
1663             return false;
1664         }
1665         bool success = false;
1666         addr_t target = ReadCoreReg (Rm, &success);
1667         if (!success)
1668             return false;
1669 
1670         RegisterInfo dwarf_reg;
1671         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1672         context.SetRegister (dwarf_reg);
1673         if (!BXWritePC(context, target))
1674             return false;
1675     }
1676     return true;
1677 }
1678 
1679 // Set r7 to point to some ip offset.
1680 // SUB (immediate)
1681 bool
1682 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding)
1683 {
1684 #if 0
1685     // ARM pseudo code...
1686     if (ConditionPassed())
1687     {
1688         EncodingSpecificOperations();
1689         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1690         if d == 15 then // Can only occur for ARM encoding
1691            ALUWritePC(result); // setflags is always FALSE here
1692         else
1693             R[d] = result;
1694             if setflags then
1695                 APSR.N = result<31>;
1696                 APSR.Z = IsZeroBit(result);
1697                 APSR.C = carry;
1698                 APSR.V = overflow;
1699     }
1700 #endif
1701 
1702     if (ConditionPassed(opcode))
1703     {
1704         bool success = false;
1705         const addr_t ip = ReadCoreReg (12, &success);
1706         if (!success)
1707             return false;
1708         uint32_t imm32;
1709         switch (encoding) {
1710         case eEncodingA1:
1711             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1712             break;
1713         default:
1714             return false;
1715         }
1716         addr_t ip_offset = imm32;
1717         addr_t addr = ip - ip_offset; // the adjusted ip value
1718 
1719         EmulateInstruction::Context context;
1720         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1721         RegisterInfo dwarf_reg;
1722         GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg);
1723         context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
1724 
1725         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
1726             return false;
1727     }
1728     return true;
1729 }
1730 
1731 // Set ip to point to some stack offset.
1732 // SUB (SP minus immediate)
1733 bool
1734 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding)
1735 {
1736 #if 0
1737     // ARM pseudo code...
1738     if (ConditionPassed())
1739     {
1740         EncodingSpecificOperations();
1741         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1742         if d == 15 then // Can only occur for ARM encoding
1743            ALUWritePC(result); // setflags is always FALSE here
1744         else
1745             R[d] = result;
1746             if setflags then
1747                 APSR.N = result<31>;
1748                 APSR.Z = IsZeroBit(result);
1749                 APSR.C = carry;
1750                 APSR.V = overflow;
1751     }
1752 #endif
1753 
1754     if (ConditionPassed(opcode))
1755     {
1756         bool success = false;
1757         const addr_t sp = ReadCoreReg (SP_REG, &success);
1758         if (!success)
1759             return false;
1760         uint32_t imm32;
1761         switch (encoding) {
1762         case eEncodingA1:
1763             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1764             break;
1765         default:
1766             return false;
1767         }
1768         addr_t sp_offset = imm32;
1769         addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1770 
1771         EmulateInstruction::Context context;
1772         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1773         RegisterInfo dwarf_reg;
1774         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
1775         context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
1776 
1777         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
1778             return false;
1779     }
1780     return true;
1781 }
1782 
1783 // This instruction subtracts an immediate value from the SP value, and writes
1784 // the result to the destination register.
1785 //
1786 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage.
1787 bool
1788 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding)
1789 {
1790 #if 0
1791     // ARM pseudo code...
1792     if (ConditionPassed())
1793     {
1794         EncodingSpecificOperations();
1795         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1796         if d == 15 then        // Can only occur for ARM encoding
1797            ALUWritePC(result); // setflags is always FALSE here
1798         else
1799             R[d] = result;
1800             if setflags then
1801                 APSR.N = result<31>;
1802                 APSR.Z = IsZeroBit(result);
1803                 APSR.C = carry;
1804                 APSR.V = overflow;
1805     }
1806 #endif
1807 
1808     bool success = false;
1809     if (ConditionPassed(opcode))
1810     {
1811         const addr_t sp = ReadCoreReg (SP_REG, &success);
1812         if (!success)
1813             return false;
1814 
1815         uint32_t Rd;
1816         bool setflags;
1817         uint32_t imm32;
1818         switch (encoding) {
1819         case eEncodingT1:
1820             Rd = 13;
1821             setflags = false;
1822             imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1823             break;
1824         case eEncodingT2:
1825             Rd = Bits32(opcode, 11, 8);
1826             setflags = BitIsSet(opcode, 20);
1827             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1828             if (Rd == 15 && setflags)
1829                 return EmulateCMPImm(opcode, eEncodingT2);
1830             if (Rd == 15 && !setflags)
1831                 return false;
1832             break;
1833         case eEncodingT3:
1834             Rd = Bits32(opcode, 11, 8);
1835             setflags = false;
1836             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
1837             if (Rd == 15)
1838                 return false;
1839             break;
1840         case eEncodingA1:
1841             Rd = Bits32(opcode, 15, 12);
1842             setflags = BitIsSet(opcode, 20);
1843             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1844 
1845             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1846             if (Rd == 15 && setflags)
1847                 return EmulateSUBSPcLrEtc (opcode, encoding);
1848             break;
1849         default:
1850             return false;
1851         }
1852         AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
1853 
1854         EmulateInstruction::Context context;
1855         if (Rd == 13)
1856         {
1857             uint64_t imm64 = imm32;  // Need to expand it to 64 bits before attempting to negate it, or the wrong
1858                                      // value gets passed down to context.SetImmediateSigned.
1859             context.type = EmulateInstruction::eContextAdjustStackPointer;
1860             context.SetImmediateSigned (-imm64); // the stack pointer offset
1861         }
1862         else
1863         {
1864             context.type = EmulateInstruction::eContextImmediate;
1865             context.SetNoArgs ();
1866         }
1867 
1868         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
1869             return false;
1870     }
1871     return true;
1872 }
1873 
1874 // A store operation to the stack that also updates the SP.
1875 bool
1876 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding)
1877 {
1878 #if 0
1879     // ARM pseudo code...
1880     if (ConditionPassed())
1881     {
1882         EncodingSpecificOperations();
1883         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1884         address = if index then offset_addr else R[n];
1885         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1886         if wback then R[n] = offset_addr;
1887     }
1888 #endif
1889 
1890     bool conditional = false;
1891     bool success = false;
1892     if (ConditionPassed(opcode, &conditional))
1893     {
1894         const uint32_t addr_byte_size = GetAddressByteSize();
1895         const addr_t sp = ReadCoreReg (SP_REG, &success);
1896         if (!success)
1897             return false;
1898         uint32_t Rt; // the source register
1899         uint32_t imm12;
1900         uint32_t Rn;  // This function assumes Rn is the SP, but we should verify that.
1901 
1902         bool index;
1903         bool add;
1904         bool wback;
1905         switch (encoding) {
1906         case eEncodingA1:
1907             Rt = Bits32(opcode, 15, 12);
1908             imm12 = Bits32(opcode, 11, 0);
1909             Rn = Bits32 (opcode, 19, 16);
1910 
1911             if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
1912                 return false;
1913 
1914             index = BitIsSet (opcode, 24);
1915             add = BitIsSet (opcode, 23);
1916             wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
1917 
1918             if (wback && ((Rn == 15) || (Rn == Rt)))
1919                 return false;
1920             break;
1921         default:
1922             return false;
1923         }
1924         addr_t offset_addr;
1925         if (add)
1926             offset_addr = sp + imm12;
1927         else
1928             offset_addr = sp - imm12;
1929 
1930         addr_t addr;
1931         if (index)
1932             addr = offset_addr;
1933         else
1934             addr = sp;
1935 
1936         EmulateInstruction::Context context;
1937         if (conditional)
1938             context.type = EmulateInstruction::eContextRegisterStore;
1939         else
1940             context.type = EmulateInstruction::eContextPushRegisterOnStack;
1941         RegisterInfo sp_reg;
1942         RegisterInfo dwarf_reg;
1943 
1944         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1945         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
1946         context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
1947         if (Rt != 15)
1948         {
1949             uint32_t reg_value = ReadCoreReg(Rt, &success);
1950             if (!success)
1951                 return false;
1952             if (!MemUWrite (context, addr, reg_value, addr_byte_size))
1953                 return false;
1954         }
1955         else
1956         {
1957             const uint32_t pc = ReadCoreReg(PC_REG, &success);
1958             if (!success)
1959                 return false;
1960             if (!MemUWrite (context, addr, pc, addr_byte_size))
1961                 return false;
1962         }
1963 
1964 
1965         if (wback)
1966         {
1967             context.type = EmulateInstruction::eContextAdjustStackPointer;
1968             context.SetImmediateSigned (addr - sp);
1969             if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr))
1970                 return false;
1971         }
1972     }
1973     return true;
1974 }
1975 
1976 // Vector Push stores multiple extension registers to the stack.
1977 // It also updates SP to point to the start of the stored data.
1978 bool
1979 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding)
1980 {
1981 #if 0
1982     // ARM pseudo code...
1983     if (ConditionPassed())
1984     {
1985         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1986         address = SP - imm32;
1987         SP = SP - imm32;
1988         if single_regs then
1989             for r = 0 to regs-1
1990                 MemA[address,4] = S[d+r]; address = address+4;
1991         else
1992             for r = 0 to regs-1
1993                 // Store as two word-aligned words in the correct order for current endianness.
1994                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
1995                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
1996                 address = address+8;
1997     }
1998 #endif
1999 
2000     bool success = false;
2001     bool conditional = false;
2002     if (ConditionPassed(opcode, &conditional))
2003     {
2004         const uint32_t addr_byte_size = GetAddressByteSize();
2005         const addr_t sp = ReadCoreReg (SP_REG, &success);
2006         if (!success)
2007             return false;
2008         bool single_regs;
2009         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2010         uint32_t imm32; // stack offset
2011         uint32_t regs;  // number of registers
2012         switch (encoding) {
2013         case eEncodingT1:
2014         case eEncodingA1:
2015             single_regs = false;
2016             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2017             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2018             // If UInt(imm8) is odd, see "FSTMX".
2019             regs = Bits32(opcode, 7, 0) / 2;
2020             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2021             if (regs == 0 || regs > 16 || (d + regs) > 32)
2022                 return false;
2023             break;
2024         case eEncodingT2:
2025         case eEncodingA2:
2026             single_regs = true;
2027             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2028             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2029             regs = Bits32(opcode, 7, 0);
2030             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2031             if (regs == 0 || regs > 16 || (d + regs) > 32)
2032                 return false;
2033             break;
2034         default:
2035             return false;
2036         }
2037         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2038         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2039         addr_t sp_offset = imm32;
2040         addr_t addr = sp - sp_offset;
2041         uint32_t i;
2042 
2043         EmulateInstruction::Context context;
2044         if (conditional)
2045             context.type = EmulateInstruction::eContextRegisterStore;
2046         else
2047             context.type = EmulateInstruction::eContextPushRegisterOnStack;
2048         RegisterInfo dwarf_reg;
2049         RegisterInfo sp_reg;
2050         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2051         for (i=0; i<regs; ++i)
2052         {
2053             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2054             context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
2055             // uint64_t to accommodate 64-bit registers.
2056             uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success);
2057             if (!success)
2058                 return false;
2059             if (!MemAWrite (context, addr, reg_value, reg_byte_size))
2060                 return false;
2061             addr += reg_byte_size;
2062         }
2063 
2064         context.type = EmulateInstruction::eContextAdjustStackPointer;
2065         context.SetImmediateSigned (-sp_offset);
2066 
2067         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2068             return false;
2069     }
2070     return true;
2071 }
2072 
2073 // Vector Pop loads multiple extension registers from the stack.
2074 // It also updates SP to point just above the loaded data.
2075 bool
2076 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding)
2077 {
2078 #if 0
2079     // ARM pseudo code...
2080     if (ConditionPassed())
2081     {
2082         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2083         address = SP;
2084         SP = SP + imm32;
2085         if single_regs then
2086             for r = 0 to regs-1
2087                 S[d+r] = MemA[address,4]; address = address+4;
2088         else
2089             for r = 0 to regs-1
2090                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2091                 // Combine the word-aligned words in the correct order for current endianness.
2092                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2093     }
2094 #endif
2095 
2096     bool success = false;
2097     bool conditional = false;
2098     if (ConditionPassed(opcode, &conditional))
2099     {
2100         const uint32_t addr_byte_size = GetAddressByteSize();
2101         const addr_t sp = ReadCoreReg (SP_REG, &success);
2102         if (!success)
2103             return false;
2104         bool single_regs;
2105         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2106         uint32_t imm32; // stack offset
2107         uint32_t regs;  // number of registers
2108         switch (encoding) {
2109         case eEncodingT1:
2110         case eEncodingA1:
2111             single_regs = false;
2112             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2113             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2114             // If UInt(imm8) is odd, see "FLDMX".
2115             regs = Bits32(opcode, 7, 0) / 2;
2116             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2117             if (regs == 0 || regs > 16 || (d + regs) > 32)
2118                 return false;
2119             break;
2120         case eEncodingT2:
2121         case eEncodingA2:
2122             single_regs = true;
2123             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2124             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2125             regs = Bits32(opcode, 7, 0);
2126             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2127             if (regs == 0 || regs > 16 || (d + regs) > 32)
2128                 return false;
2129             break;
2130         default:
2131             return false;
2132         }
2133         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2134         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2135         addr_t sp_offset = imm32;
2136         addr_t addr = sp;
2137         uint32_t i;
2138         uint64_t data; // uint64_t to accomodate 64-bit registers.
2139 
2140         EmulateInstruction::Context context;
2141         if (conditional)
2142             context.type = EmulateInstruction::eContextRegisterLoad;
2143         else
2144             context.type = EmulateInstruction::eContextPopRegisterOffStack;
2145         RegisterInfo dwarf_reg;
2146         RegisterInfo sp_reg;
2147         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2148         for (i=0; i<regs; ++i)
2149         {
2150             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2151             context.SetRegisterPlusOffset (sp_reg, addr - sp);
2152             data = MemARead(context, addr, reg_byte_size, 0, &success);
2153             if (!success)
2154                 return false;
2155             if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2156                 return false;
2157             addr += reg_byte_size;
2158         }
2159 
2160         context.type = EmulateInstruction::eContextAdjustStackPointer;
2161         context.SetImmediateSigned (sp_offset);
2162 
2163         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2164             return false;
2165     }
2166     return true;
2167 }
2168 
2169 // SVC (previously SWI)
2170 bool
2171 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding)
2172 {
2173 #if 0
2174     // ARM pseudo code...
2175     if (ConditionPassed())
2176     {
2177         EncodingSpecificOperations();
2178         CallSupervisor();
2179     }
2180 #endif
2181 
2182     bool success = false;
2183 
2184     if (ConditionPassed(opcode))
2185     {
2186         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2187         addr_t lr; // next instruction address
2188         if (!success)
2189             return false;
2190         uint32_t imm32; // the immediate constant
2191         uint32_t mode;  // ARM or Thumb mode
2192         switch (encoding) {
2193         case eEncodingT1:
2194             lr = (pc + 2) | 1u; // return address
2195             imm32 = Bits32(opcode, 7, 0);
2196             mode = eModeThumb;
2197             break;
2198         case eEncodingA1:
2199             lr = pc + 4; // return address
2200             imm32 = Bits32(opcode, 23, 0);
2201             mode = eModeARM;
2202             break;
2203         default:
2204             return false;
2205         }
2206 
2207         EmulateInstruction::Context context;
2208         context.type = EmulateInstruction::eContextSupervisorCall;
2209         context.SetISAAndImmediate (mode, imm32);
2210         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
2211             return false;
2212     }
2213     return true;
2214 }
2215 
2216 // If Then makes up to four following instructions (the IT block) conditional.
2217 bool
2218 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding)
2219 {
2220 #if 0
2221     // ARM pseudo code...
2222     EncodingSpecificOperations();
2223     ITSTATE.IT<7:0> = firstcond:mask;
2224 #endif
2225 
2226     m_it_session.InitIT(Bits32(opcode, 7, 0));
2227     return true;
2228 }
2229 
2230 bool
2231 EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding)
2232 {
2233     // NOP, nothing to do...
2234     return true;
2235 }
2236 
2237 // Branch causes a branch to a target address.
2238 bool
2239 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding)
2240 {
2241 #if 0
2242     // ARM pseudo code...
2243     if (ConditionPassed())
2244     {
2245         EncodingSpecificOperations();
2246         BranchWritePC(PC + imm32);
2247     }
2248 #endif
2249 
2250     bool success = false;
2251 
2252     if (ConditionPassed(opcode))
2253     {
2254         EmulateInstruction::Context context;
2255         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2256         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2257         if (!success)
2258             return false;
2259         addr_t target; // target address
2260         int32_t imm32; // PC-relative offset
2261         switch (encoding) {
2262         case eEncodingT1:
2263             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2264             imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2265             target = pc + imm32;
2266             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2267             break;
2268         case eEncodingT2:
2269             imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0));
2270             target = pc + imm32;
2271             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2272             break;
2273         case eEncodingT3:
2274             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2275             {
2276             uint32_t S = Bit32(opcode, 26);
2277             uint32_t imm6 = Bits32(opcode, 21, 16);
2278             uint32_t J1 = Bit32(opcode, 13);
2279             uint32_t J2 = Bit32(opcode, 11);
2280             uint32_t imm11 = Bits32(opcode, 10, 0);
2281             uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2282             imm32 = llvm::SignExtend32<21>(imm21);
2283             target = pc + imm32;
2284             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2285             break;
2286             }
2287         case eEncodingT4:
2288             {
2289             uint32_t S = Bit32(opcode, 26);
2290             uint32_t imm10 = Bits32(opcode, 25, 16);
2291             uint32_t J1 = Bit32(opcode, 13);
2292             uint32_t J2 = Bit32(opcode, 11);
2293             uint32_t imm11 = Bits32(opcode, 10, 0);
2294             uint32_t I1 = !(J1 ^ S);
2295             uint32_t I2 = !(J2 ^ S);
2296             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2297             imm32 = llvm::SignExtend32<25>(imm25);
2298             target = pc + imm32;
2299             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2300             break;
2301             }
2302         case eEncodingA1:
2303             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2304             target = pc + imm32;
2305             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
2306             break;
2307         default:
2308             return false;
2309         }
2310         if (!BranchWritePC(context, target))
2311             return false;
2312     }
2313     return true;
2314 }
2315 
2316 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
2317 // zero and conditionally branch forward a constant value.  They do not affect the condition flags.
2318 // CBNZ, CBZ
2319 bool
2320 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding)
2321 {
2322 #if 0
2323     // ARM pseudo code...
2324     EncodingSpecificOperations();
2325     if nonzero ^ IsZero(R[n]) then
2326         BranchWritePC(PC + imm32);
2327 #endif
2328 
2329     bool success = false;
2330 
2331     // Read the register value from the operand register Rn.
2332     uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2333     if (!success)
2334         return false;
2335 
2336     EmulateInstruction::Context context;
2337     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2338     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2339     if (!success)
2340         return false;
2341 
2342     addr_t target;  // target address
2343     uint32_t imm32; // PC-relative offset to branch forward
2344     bool nonzero;
2345     switch (encoding) {
2346     case eEncodingT1:
2347         imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2348         nonzero = BitIsSet(opcode, 11);
2349         target = pc + imm32;
2350         context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2351         break;
2352     default:
2353         return false;
2354     }
2355     if (nonzero ^ (reg_val == 0))
2356         if (!BranchWritePC(context, target))
2357             return false;
2358 
2359     return true;
2360 }
2361 
2362 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
2363 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2364 // The branch length is twice the value of the byte returned from the table.
2365 //
2366 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
2367 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2368 // The branch length is twice the value of the halfword returned from the table.
2369 // TBB, TBH
2370 bool
2371 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding)
2372 {
2373 #if 0
2374     // ARM pseudo code...
2375     EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2376     if is_tbh then
2377         halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2378     else
2379         halfwords = UInt(MemU[R[n]+R[m], 1]);
2380     BranchWritePC(PC + 2*halfwords);
2381 #endif
2382 
2383     bool success = false;
2384 
2385     uint32_t Rn;     // the base register which contains the address of the table of branch lengths
2386     uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
2387     bool is_tbh;     // true if table branch halfword
2388     switch (encoding) {
2389     case eEncodingT1:
2390         Rn = Bits32(opcode, 19, 16);
2391         Rm = Bits32(opcode, 3, 0);
2392         is_tbh = BitIsSet(opcode, 4);
2393         if (Rn == 13 || BadReg(Rm))
2394             return false;
2395         if (InITBlock() && !LastInITBlock())
2396             return false;
2397         break;
2398     default:
2399         return false;
2400     }
2401 
2402     // Read the address of the table from the operand register Rn.
2403     // The PC can be used, in which case the table immediately follows this instruction.
2404     uint32_t base = ReadCoreReg(Rm, &success);
2405     if (!success)
2406         return false;
2407 
2408     // the table index
2409     uint32_t index = ReadCoreReg(Rm, &success);
2410     if (!success)
2411         return false;
2412 
2413     // the offsetted table address
2414     addr_t addr = base + (is_tbh ? index*2 : index);
2415 
2416     // PC-relative offset to branch forward
2417     EmulateInstruction::Context context;
2418     context.type = EmulateInstruction::eContextTableBranchReadMemory;
2419     uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2420     if (!success)
2421         return false;
2422 
2423     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2424     if (!success)
2425         return false;
2426 
2427     // target address
2428     addr_t target = pc + offset;
2429     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2430     context.SetISAAndImmediateSigned (eModeThumb, 4 + offset);
2431 
2432     if (!BranchWritePC(context, target))
2433         return false;
2434 
2435     return true;
2436 }
2437 
2438 // This instruction adds an immediate value to a register value, and writes the result to the destination register.
2439 // It can optionally update the condition flags based on the result.
2440 bool
2441 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding)
2442 {
2443 #if 0
2444     if ConditionPassed() then
2445         EncodingSpecificOperations();
2446         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2447         R[d] = result;
2448         if setflags then
2449             APSR.N = result<31>;
2450             APSR.Z = IsZeroBit(result);
2451             APSR.C = carry;
2452             APSR.V = overflow;
2453 #endif
2454 
2455     bool success = false;
2456 
2457     if (ConditionPassed(opcode))
2458     {
2459         uint32_t d;
2460         uint32_t n;
2461         bool setflags;
2462         uint32_t imm32;
2463         uint32_t carry_out;
2464 
2465         //EncodingSpecificOperations();
2466         switch (encoding)
2467         {
2468             case eEncodingT1:
2469                 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32);
2470                 d = Bits32 (opcode, 2, 0);
2471                 n = Bits32 (opcode, 5, 3);
2472                 setflags = !InITBlock();
2473                 imm32 = Bits32 (opcode, 8,6);
2474 
2475                 break;
2476 
2477             case eEncodingT2:
2478                 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32);
2479                 d = Bits32 (opcode, 10, 8);
2480                 n = Bits32 (opcode, 10, 8);
2481                 setflags = !InITBlock();
2482                 imm32 = Bits32 (opcode, 7, 0);
2483 
2484                 break;
2485 
2486             case eEncodingT3:
2487                 // if Rd == '1111' && S == '1' then SEE CMN (immediate);
2488                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2489                 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8);
2490                 d = Bits32 (opcode, 11, 8);
2491                 n = Bits32 (opcode, 19, 16);
2492                 setflags = BitIsSet (opcode, 20);
2493                 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out);
2494 
2495                 // if BadReg(d) || n == 15 then UNPREDICTABLE;
2496                 if (BadReg (d) || (n == 15))
2497                     return false;
2498 
2499                 break;
2500 
2501             case eEncodingT4:
2502             {
2503                 // if Rn == '1111' then SEE ADR;
2504                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2505                 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
2506                 d = Bits32 (opcode, 11, 8);
2507                 n = Bits32 (opcode, 19, 16);
2508                 setflags = false;
2509                 uint32_t i = Bit32 (opcode, 26);
2510                 uint32_t imm3 = Bits32 (opcode, 14, 12);
2511                 uint32_t imm8 = Bits32 (opcode, 7, 0);
2512                 imm32 = (i << 11) | (imm3 << 8) | imm8;
2513 
2514                 // if BadReg(d) then UNPREDICTABLE;
2515                 if (BadReg (d))
2516                     return false;
2517 
2518                 break;
2519             }
2520             default:
2521                 return false;
2522         }
2523 
2524         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2525         if (!success)
2526             return false;
2527 
2528         //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2529         AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
2530 
2531         RegisterInfo reg_n;
2532         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
2533 
2534         EmulateInstruction::Context context;
2535         context.type = eContextArithmetic;
2536         context.SetRegisterPlusOffset (reg_n, imm32);
2537 
2538         //R[d] = result;
2539         //if setflags then
2540             //APSR.N = result<31>;
2541             //APSR.Z = IsZeroBit(result);
2542             //APSR.C = carry;
2543             //APSR.V = overflow;
2544         if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
2545             return false;
2546 
2547     }
2548     return true;
2549 }
2550 
2551 // This instruction adds an immediate value to a register value, and writes the result to the destination
2552 // register.  It can optionally update the condition flags based on the result.
2553 bool
2554 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding)
2555 {
2556 #if 0
2557     // ARM pseudo code...
2558     if ConditionPassed() then
2559         EncodingSpecificOperations();
2560         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2561         if d == 15 then
2562             ALUWritePC(result); // setflags is always FALSE here
2563         else
2564             R[d] = result;
2565             if setflags then
2566                 APSR.N = result<31>;
2567                 APSR.Z = IsZeroBit(result);
2568                 APSR.C = carry;
2569                 APSR.V = overflow;
2570 #endif
2571 
2572     bool success = false;
2573 
2574     if (ConditionPassed(opcode))
2575     {
2576         uint32_t Rd, Rn;
2577         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
2578         bool setflags;
2579         switch (encoding)
2580         {
2581         case eEncodingA1:
2582             Rd = Bits32(opcode, 15, 12);
2583             Rn = Bits32(opcode, 19, 16);
2584             setflags = BitIsSet(opcode, 20);
2585             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2586             break;
2587         default:
2588             return false;
2589         }
2590 
2591         // Read the first operand.
2592         uint32_t val1 = ReadCoreReg(Rn, &success);
2593         if (!success)
2594             return false;
2595 
2596         AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
2597 
2598         EmulateInstruction::Context context;
2599         context.type = eContextArithmetic;
2600         RegisterInfo dwarf_reg;
2601         GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
2602         context.SetRegisterPlusOffset (dwarf_reg, imm32);
2603 
2604         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2605             return false;
2606     }
2607     return true;
2608 }
2609 
2610 // This instruction adds a register value and an optionally-shifted register value, and writes the result
2611 // to the destination register. It can optionally update the condition flags based on the result.
2612 bool
2613 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding)
2614 {
2615 #if 0
2616     // ARM pseudo code...
2617     if ConditionPassed() then
2618         EncodingSpecificOperations();
2619         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2620         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2621         if d == 15 then
2622             ALUWritePC(result); // setflags is always FALSE here
2623         else
2624             R[d] = result;
2625             if setflags then
2626                 APSR.N = result<31>;
2627                 APSR.Z = IsZeroBit(result);
2628                 APSR.C = carry;
2629                 APSR.V = overflow;
2630 #endif
2631 
2632     bool success = false;
2633 
2634     if (ConditionPassed(opcode))
2635     {
2636         uint32_t Rd, Rn, Rm;
2637         ARM_ShifterType shift_t;
2638         uint32_t shift_n; // the shift applied to the value read from Rm
2639         bool setflags;
2640         switch (encoding)
2641         {
2642         case eEncodingT1:
2643             Rd = Bits32(opcode, 2, 0);
2644             Rn = Bits32(opcode, 5, 3);
2645             Rm = Bits32(opcode, 8, 6);
2646             setflags = !InITBlock();
2647             shift_t = SRType_LSL;
2648             shift_n = 0;
2649             break;
2650         case eEncodingT2:
2651             Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2652             Rm = Bits32(opcode, 6, 3);
2653             setflags = false;
2654             shift_t = SRType_LSL;
2655             shift_n = 0;
2656             if (Rn == 15 && Rm == 15)
2657                 return false;
2658             if (Rd == 15 && InITBlock() && !LastInITBlock())
2659                 return false;
2660             break;
2661         case eEncodingA1:
2662             Rd = Bits32(opcode, 15, 12);
2663             Rn = Bits32(opcode, 19, 16);
2664             Rm = Bits32(opcode, 3, 0);
2665             setflags = BitIsSet(opcode, 20);
2666             shift_n = DecodeImmShiftARM(opcode, shift_t);
2667             break;
2668         default:
2669             return false;
2670         }
2671 
2672         // Read the first operand.
2673         uint32_t val1 = ReadCoreReg(Rn, &success);
2674         if (!success)
2675             return false;
2676 
2677         // Read the second operand.
2678         uint32_t val2 = ReadCoreReg(Rm, &success);
2679         if (!success)
2680             return false;
2681 
2682         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2683         if (!success)
2684             return false;
2685         AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2686 
2687         EmulateInstruction::Context context;
2688         context.type = eContextArithmetic;
2689         RegisterInfo op1_reg;
2690         RegisterInfo op2_reg;
2691         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
2692         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
2693         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
2694 
2695         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2696             return false;
2697     }
2698     return true;
2699 }
2700 
2701 // Compare Negative (immediate) adds a register value and an immediate value.
2702 // It updates the condition flags based on the result, and discards the result.
2703 bool
2704 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding)
2705 {
2706 #if 0
2707     // ARM pseudo code...
2708     if ConditionPassed() then
2709         EncodingSpecificOperations();
2710         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2711         APSR.N = result<31>;
2712         APSR.Z = IsZeroBit(result);
2713         APSR.C = carry;
2714         APSR.V = overflow;
2715 #endif
2716 
2717     bool success = false;
2718 
2719     uint32_t Rn; // the first operand
2720     uint32_t imm32; // the immediate value to be compared with
2721     switch (encoding) {
2722     case eEncodingT1:
2723         Rn = Bits32(opcode, 19, 16);
2724         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2725         if (Rn == 15)
2726             return false;
2727         break;
2728     case eEncodingA1:
2729         Rn = Bits32(opcode, 19, 16);
2730         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2731         break;
2732     default:
2733         return false;
2734     }
2735     // Read the register value from the operand register Rn.
2736     uint32_t reg_val = ReadCoreReg(Rn, &success);
2737     if (!success)
2738         return false;
2739 
2740     AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
2741 
2742     EmulateInstruction::Context context;
2743     context.type = EmulateInstruction::eContextImmediate;
2744     context.SetNoArgs ();
2745     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2746         return false;
2747 
2748     return true;
2749 }
2750 
2751 // Compare Negative (register) adds a register value and an optionally-shifted register value.
2752 // It updates the condition flags based on the result, and discards the result.
2753 bool
2754 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding)
2755 {
2756 #if 0
2757     // ARM pseudo code...
2758     if ConditionPassed() then
2759         EncodingSpecificOperations();
2760         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2761         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2762         APSR.N = result<31>;
2763         APSR.Z = IsZeroBit(result);
2764         APSR.C = carry;
2765         APSR.V = overflow;
2766 #endif
2767 
2768     bool success = false;
2769 
2770     uint32_t Rn; // the first operand
2771     uint32_t Rm; // the second operand
2772     ARM_ShifterType shift_t;
2773     uint32_t shift_n; // the shift applied to the value read from Rm
2774     switch (encoding) {
2775     case eEncodingT1:
2776         Rn = Bits32(opcode, 2, 0);
2777         Rm = Bits32(opcode, 5, 3);
2778         shift_t = SRType_LSL;
2779         shift_n = 0;
2780         break;
2781     case eEncodingT2:
2782         Rn = Bits32(opcode, 19, 16);
2783         Rm = Bits32(opcode, 3, 0);
2784         shift_n = DecodeImmShiftThumb(opcode, shift_t);
2785         // if n == 15 || BadReg(m) then UNPREDICTABLE;
2786         if (Rn == 15 || BadReg(Rm))
2787             return false;
2788         break;
2789     case eEncodingA1:
2790         Rn = Bits32(opcode, 19, 16);
2791         Rm = Bits32(opcode, 3, 0);
2792         shift_n = DecodeImmShiftARM(opcode, shift_t);
2793         break;
2794     default:
2795         return false;
2796     }
2797     // Read the register value from register Rn.
2798     uint32_t val1 = ReadCoreReg(Rn, &success);
2799     if (!success)
2800         return false;
2801 
2802     // Read the register value from register Rm.
2803     uint32_t val2 = ReadCoreReg(Rm, &success);
2804     if (!success)
2805         return false;
2806 
2807     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2808     if (!success)
2809         return false;
2810     AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2811 
2812     EmulateInstruction::Context context;
2813     context.type = EmulateInstruction::eContextImmediate;
2814     context.SetNoArgs();
2815     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2816         return false;
2817 
2818     return true;
2819 }
2820 
2821 // Compare (immediate) subtracts an immediate value from a register value.
2822 // It updates the condition flags based on the result, and discards the result.
2823 bool
2824 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding)
2825 {
2826 #if 0
2827     // ARM pseudo code...
2828     if ConditionPassed() then
2829         EncodingSpecificOperations();
2830         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2831         APSR.N = result<31>;
2832         APSR.Z = IsZeroBit(result);
2833         APSR.C = carry;
2834         APSR.V = overflow;
2835 #endif
2836 
2837     bool success = false;
2838 
2839     uint32_t Rn; // the first operand
2840     uint32_t imm32; // the immediate value to be compared with
2841     switch (encoding) {
2842     case eEncodingT1:
2843         Rn = Bits32(opcode, 10, 8);
2844         imm32 = Bits32(opcode, 7, 0);
2845         break;
2846     case eEncodingT2:
2847         Rn = Bits32(opcode, 19, 16);
2848         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2849         if (Rn == 15)
2850             return false;
2851         break;
2852     case eEncodingA1:
2853         Rn = Bits32(opcode, 19, 16);
2854         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2855         break;
2856     default:
2857         return false;
2858     }
2859     // Read the register value from the operand register Rn.
2860     uint32_t reg_val = ReadCoreReg(Rn, &success);
2861     if (!success)
2862         return false;
2863 
2864     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
2865 
2866     EmulateInstruction::Context context;
2867     context.type = EmulateInstruction::eContextImmediate;
2868     context.SetNoArgs ();
2869     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2870         return false;
2871 
2872     return true;
2873 }
2874 
2875 // Compare (register) subtracts an optionally-shifted register value from a register value.
2876 // It updates the condition flags based on the result, and discards the result.
2877 bool
2878 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding)
2879 {
2880 #if 0
2881     // ARM pseudo code...
2882     if ConditionPassed() then
2883         EncodingSpecificOperations();
2884         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2885         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2886         APSR.N = result<31>;
2887         APSR.Z = IsZeroBit(result);
2888         APSR.C = carry;
2889         APSR.V = overflow;
2890 #endif
2891 
2892     bool success = false;
2893 
2894     uint32_t Rn; // the first operand
2895     uint32_t Rm; // the second operand
2896     ARM_ShifterType shift_t;
2897     uint32_t shift_n; // the shift applied to the value read from Rm
2898     switch (encoding) {
2899     case eEncodingT1:
2900         Rn = Bits32(opcode, 2, 0);
2901         Rm = Bits32(opcode, 5, 3);
2902         shift_t = SRType_LSL;
2903         shift_n = 0;
2904         break;
2905     case eEncodingT2:
2906         Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2907         Rm = Bits32(opcode, 6, 3);
2908         shift_t = SRType_LSL;
2909         shift_n = 0;
2910         if (Rn < 8 && Rm < 8)
2911             return false;
2912         if (Rn == 15 || Rm == 15)
2913             return false;
2914         break;
2915     case eEncodingA1:
2916         Rn = Bits32(opcode, 19, 16);
2917         Rm = Bits32(opcode, 3, 0);
2918         shift_n = DecodeImmShiftARM(opcode, shift_t);
2919         break;
2920     default:
2921         return false;
2922     }
2923     // Read the register value from register Rn.
2924     uint32_t val1 = ReadCoreReg(Rn, &success);
2925     if (!success)
2926         return false;
2927 
2928     // Read the register value from register Rm.
2929     uint32_t val2 = ReadCoreReg(Rm, &success);
2930     if (!success)
2931         return false;
2932 
2933     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2934     if (!success)
2935         return false;
2936     AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
2937 
2938     EmulateInstruction::Context context;
2939     context.type = EmulateInstruction::eContextImmediate;
2940     context.SetNoArgs();
2941     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2942         return false;
2943 
2944     return true;
2945 }
2946 
2947 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
2948 // shifting in copies of its sign bit, and writes the result to the destination register.  It can
2949 // optionally update the condition flags based on the result.
2950 bool
2951 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding)
2952 {
2953 #if 0
2954     // ARM pseudo code...
2955     if ConditionPassed() then
2956         EncodingSpecificOperations();
2957         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2958         if d == 15 then         // Can only occur for ARM encoding
2959             ALUWritePC(result); // setflags is always FALSE here
2960         else
2961             R[d] = result;
2962             if setflags then
2963                 APSR.N = result<31>;
2964                 APSR.Z = IsZeroBit(result);
2965                 APSR.C = carry;
2966                 // APSR.V unchanged
2967 #endif
2968 
2969     return EmulateShiftImm (opcode, encoding, SRType_ASR);
2970 }
2971 
2972 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
2973 // shifting in copies of its sign bit, and writes the result to the destination register.
2974 // The variable number of bits is read from the bottom byte of a register. It can optionally update
2975 // the condition flags based on the result.
2976 bool
2977 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding)
2978 {
2979 #if 0
2980     // ARM pseudo code...
2981     if ConditionPassed() then
2982         EncodingSpecificOperations();
2983         shift_n = UInt(R[m]<7:0>);
2984         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2985         R[d] = result;
2986         if setflags then
2987             APSR.N = result<31>;
2988             APSR.Z = IsZeroBit(result);
2989             APSR.C = carry;
2990             // APSR.V unchanged
2991 #endif
2992 
2993     return EmulateShiftReg (opcode, encoding, SRType_ASR);
2994 }
2995 
2996 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
2997 // shifting in zeros, and writes the result to the destination register.  It can optionally
2998 // update the condition flags based on the result.
2999 bool
3000 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding)
3001 {
3002 #if 0
3003     // ARM pseudo code...
3004     if ConditionPassed() then
3005         EncodingSpecificOperations();
3006         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3007         if d == 15 then         // Can only occur for ARM encoding
3008             ALUWritePC(result); // setflags is always FALSE here
3009         else
3010             R[d] = result;
3011             if setflags then
3012                 APSR.N = result<31>;
3013                 APSR.Z = IsZeroBit(result);
3014                 APSR.C = carry;
3015                 // APSR.V unchanged
3016 #endif
3017 
3018     return EmulateShiftImm (opcode, encoding, SRType_LSL);
3019 }
3020 
3021 // Logical Shift Left (register) shifts a register value left by a variable number of bits,
3022 // shifting in zeros, and writes the result to the destination register.  The variable number
3023 // of bits is read from the bottom byte of a register. It can optionally update the condition
3024 // flags based on the result.
3025 bool
3026 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding)
3027 {
3028 #if 0
3029     // ARM pseudo code...
3030     if ConditionPassed() then
3031         EncodingSpecificOperations();
3032         shift_n = UInt(R[m]<7:0>);
3033         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3034         R[d] = result;
3035         if setflags then
3036             APSR.N = result<31>;
3037             APSR.Z = IsZeroBit(result);
3038             APSR.C = carry;
3039             // APSR.V unchanged
3040 #endif
3041 
3042     return EmulateShiftReg (opcode, encoding, SRType_LSL);
3043 }
3044 
3045 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
3046 // shifting in zeros, and writes the result to the destination register.  It can optionally
3047 // update the condition flags based on the result.
3048 bool
3049 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding)
3050 {
3051 #if 0
3052     // ARM pseudo code...
3053     if ConditionPassed() then
3054         EncodingSpecificOperations();
3055         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3056         if d == 15 then         // Can only occur for ARM encoding
3057             ALUWritePC(result); // setflags is always FALSE here
3058         else
3059             R[d] = result;
3060             if setflags then
3061                 APSR.N = result<31>;
3062                 APSR.Z = IsZeroBit(result);
3063                 APSR.C = carry;
3064                 // APSR.V unchanged
3065 #endif
3066 
3067     return EmulateShiftImm (opcode, encoding, SRType_LSR);
3068 }
3069 
3070 // Logical Shift Right (register) shifts a register value right by a variable number of bits,
3071 // shifting in zeros, and writes the result to the destination register.  The variable number
3072 // of bits is read from the bottom byte of a register. It can optionally update the condition
3073 // flags based on the result.
3074 bool
3075 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding)
3076 {
3077 #if 0
3078     // ARM pseudo code...
3079     if ConditionPassed() then
3080         EncodingSpecificOperations();
3081         shift_n = UInt(R[m]<7:0>);
3082         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3083         R[d] = result;
3084         if setflags then
3085             APSR.N = result<31>;
3086             APSR.Z = IsZeroBit(result);
3087             APSR.C = carry;
3088             // APSR.V unchanged
3089 #endif
3090 
3091     return EmulateShiftReg (opcode, encoding, SRType_LSR);
3092 }
3093 
3094 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
3095 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3096 // It can optionally update the condition flags based on the result.
3097 bool
3098 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding)
3099 {
3100 #if 0
3101     // ARM pseudo code...
3102     if ConditionPassed() then
3103         EncodingSpecificOperations();
3104         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3105         if d == 15 then         // Can only occur for ARM encoding
3106             ALUWritePC(result); // setflags is always FALSE here
3107         else
3108             R[d] = result;
3109             if setflags then
3110                 APSR.N = result<31>;
3111                 APSR.Z = IsZeroBit(result);
3112                 APSR.C = carry;
3113                 // APSR.V unchanged
3114 #endif
3115 
3116     return EmulateShiftImm (opcode, encoding, SRType_ROR);
3117 }
3118 
3119 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
3120 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3121 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
3122 // flags based on the result.
3123 bool
3124 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding)
3125 {
3126 #if 0
3127     // ARM pseudo code...
3128     if ConditionPassed() then
3129         EncodingSpecificOperations();
3130         shift_n = UInt(R[m]<7:0>);
3131         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3132         R[d] = result;
3133         if setflags then
3134             APSR.N = result<31>;
3135             APSR.Z = IsZeroBit(result);
3136             APSR.C = carry;
3137             // APSR.V unchanged
3138 #endif
3139 
3140     return EmulateShiftReg (opcode, encoding, SRType_ROR);
3141 }
3142 
3143 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
3144 // with the carry flag shifted into bit [31].
3145 //
3146 // RRX can optionally update the condition flags based on the result.
3147 // In that case, bit [0] is shifted into the carry flag.
3148 bool
3149 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding)
3150 {
3151 #if 0
3152     // ARM pseudo code...
3153     if ConditionPassed() then
3154         EncodingSpecificOperations();
3155         (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3156         if d == 15 then         // Can only occur for ARM encoding
3157             ALUWritePC(result); // setflags is always FALSE here
3158         else
3159             R[d] = result;
3160             if setflags then
3161                 APSR.N = result<31>;
3162                 APSR.Z = IsZeroBit(result);
3163                 APSR.C = carry;
3164                 // APSR.V unchanged
3165 #endif
3166 
3167     return EmulateShiftImm (opcode, encoding, SRType_RRX);
3168 }
3169 
3170 bool
3171 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3172 {
3173 //    assert(shift_type == SRType_ASR
3174 //           || shift_type == SRType_LSL
3175 //           || shift_type == SRType_LSR
3176 //           || shift_type == SRType_ROR
3177 //           || shift_type == SRType_RRX);
3178 
3179     bool success = false;
3180 
3181     if (ConditionPassed(opcode))
3182     {
3183         uint32_t Rd;    // the destination register
3184         uint32_t Rm;    // the first operand register
3185         uint32_t imm5;  // encoding for the shift amount
3186         uint32_t carry; // the carry bit after the shift operation
3187         bool setflags;
3188 
3189         // Special case handling!
3190         // A8.6.139 ROR (immediate) -- Encoding T1
3191         ARMEncoding use_encoding = encoding;
3192         if (shift_type == SRType_ROR && use_encoding == eEncodingT1)
3193         {
3194             // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
3195             // have the same decoding of bit fields as the other Thumb2 shift operations.
3196             use_encoding = eEncodingT2;
3197         }
3198 
3199         switch (use_encoding) {
3200         case eEncodingT1:
3201             // Due to the above special case handling!
3202             if (shift_type == SRType_ROR)
3203                 return false;
3204 
3205             Rd = Bits32(opcode, 2, 0);
3206             Rm = Bits32(opcode, 5, 3);
3207             setflags = !InITBlock();
3208             imm5 = Bits32(opcode, 10, 6);
3209             break;
3210         case eEncodingT2:
3211             // A8.6.141 RRX
3212             // There's no imm form of RRX instructions.
3213             if (shift_type == SRType_RRX)
3214                 return false;
3215 
3216             Rd = Bits32(opcode, 11, 8);
3217             Rm = Bits32(opcode, 3, 0);
3218             setflags = BitIsSet(opcode, 20);
3219             imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3220             if (BadReg(Rd) || BadReg(Rm))
3221                 return false;
3222             break;
3223         case eEncodingA1:
3224             Rd = Bits32(opcode, 15, 12);
3225             Rm = Bits32(opcode, 3, 0);
3226             setflags = BitIsSet(opcode, 20);
3227             imm5 = Bits32(opcode, 11, 7);
3228             break;
3229         default:
3230             return false;
3231         }
3232 
3233         // A8.6.139 ROR (immediate)
3234         if (shift_type == SRType_ROR && imm5 == 0)
3235             shift_type = SRType_RRX;
3236 
3237         // Get the first operand.
3238         uint32_t value = ReadCoreReg (Rm, &success);
3239         if (!success)
3240             return false;
3241 
3242         // Decode the shift amount if not RRX.
3243         uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3244 
3245         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3246         if (!success)
3247             return false;
3248 
3249         // The context specifies that an immediate is to be moved into Rd.
3250         EmulateInstruction::Context context;
3251         context.type = EmulateInstruction::eContextImmediate;
3252         context.SetNoArgs ();
3253 
3254         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3255             return false;
3256     }
3257     return true;
3258 }
3259 
3260 bool
3261 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3262 {
3263     // assert(shift_type == SRType_ASR
3264     //        || shift_type == SRType_LSL
3265     //        || shift_type == SRType_LSR
3266     //        || shift_type == SRType_ROR);
3267 
3268     bool success = false;
3269 
3270     if (ConditionPassed(opcode))
3271     {
3272         uint32_t Rd;    // the destination register
3273         uint32_t Rn;    // the first operand register
3274         uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
3275         uint32_t carry; // the carry bit after the shift operation
3276         bool setflags;
3277         switch (encoding) {
3278         case eEncodingT1:
3279             Rd = Bits32(opcode, 2, 0);
3280             Rn = Rd;
3281             Rm = Bits32(opcode, 5, 3);
3282             setflags = !InITBlock();
3283             break;
3284         case eEncodingT2:
3285             Rd = Bits32(opcode, 11, 8);
3286             Rn = Bits32(opcode, 19, 16);
3287             Rm = Bits32(opcode, 3, 0);
3288             setflags = BitIsSet(opcode, 20);
3289             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3290                 return false;
3291             break;
3292         case eEncodingA1:
3293             Rd = Bits32(opcode, 15, 12);
3294             Rn = Bits32(opcode, 3, 0);
3295             Rm = Bits32(opcode, 11, 8);
3296             setflags = BitIsSet(opcode, 20);
3297             if (Rd == 15 || Rn == 15 || Rm == 15)
3298                 return false;
3299             break;
3300         default:
3301             return false;
3302         }
3303 
3304         // Get the first operand.
3305         uint32_t value = ReadCoreReg (Rn, &success);
3306         if (!success)
3307             return false;
3308         // Get the Rm register content.
3309         uint32_t val = ReadCoreReg (Rm, &success);
3310         if (!success)
3311             return false;
3312 
3313         // Get the shift amount.
3314         uint32_t amt = Bits32(val, 7, 0);
3315 
3316         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3317         if (!success)
3318             return false;
3319 
3320         // The context specifies that an immediate is to be moved into Rd.
3321         EmulateInstruction::Context context;
3322         context.type = EmulateInstruction::eContextImmediate;
3323         context.SetNoArgs ();
3324 
3325         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3326             return false;
3327     }
3328     return true;
3329 }
3330 
3331 // LDM loads multiple registers from consecutive memory locations, using an
3332 // address from a base register.  Optionally the address just above the highest of those locations
3333 // can be written back to the base register.
3334 bool
3335 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding)
3336 {
3337 #if 0
3338     // ARM pseudo code...
3339     if ConditionPassed()
3340         EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3341         address = R[n];
3342 
3343         for i = 0 to 14
3344             if registers<i> == '1' then
3345                 R[i] = MemA[address, 4]; address = address + 4;
3346         if registers<15> == '1' then
3347             LoadWritePC (MemA[address, 4]);
3348 
3349         if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3350         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3351 
3352 #endif
3353 
3354     bool success = false;
3355     bool conditional = false;
3356     if (ConditionPassed(opcode, &conditional))
3357     {
3358         uint32_t n;
3359         uint32_t registers = 0;
3360         bool wback;
3361         const uint32_t addr_byte_size = GetAddressByteSize();
3362         switch (encoding)
3363         {
3364             case eEncodingT1:
3365                 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0');
3366                 n = Bits32 (opcode, 10, 8);
3367                 registers = Bits32 (opcode, 7, 0);
3368                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3369                 wback = BitIsClear (registers, n);
3370                 // if BitCount(registers) < 1 then UNPREDICTABLE;
3371                 if (BitCount(registers) < 1)
3372                     return false;
3373                 break;
3374             case eEncodingT2:
3375                 // if W == '1' && Rn == '1101' then SEE POP;
3376                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3377                 n = Bits32 (opcode, 19, 16);
3378                 registers = Bits32 (opcode, 15, 0);
3379                 registers = registers & 0xdfff; // Make sure bit 13 is zero.
3380                 wback = BitIsSet (opcode, 21);
3381 
3382                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3383                 if ((n == 15)
3384                     || (BitCount (registers) < 2)
3385                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3386                     return false;
3387 
3388                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3389                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3390                     return false;
3391 
3392                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3393                 if (wback
3394                     && BitIsSet (registers, n))
3395                     return false;
3396                 break;
3397 
3398             case eEncodingA1:
3399                 n = Bits32 (opcode, 19, 16);
3400                 registers = Bits32 (opcode, 15, 0);
3401                 wback = BitIsSet (opcode, 21);
3402                 if ((n == 15)
3403                     || (BitCount (registers) < 1))
3404                     return false;
3405                 break;
3406             default:
3407                 return false;
3408         }
3409 
3410         int32_t offset = 0;
3411         const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3412         if (!success)
3413             return false;
3414 
3415         EmulateInstruction::Context context;
3416         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3417         RegisterInfo dwarf_reg;
3418         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3419         context.SetRegisterPlusOffset (dwarf_reg, offset);
3420 
3421         for (int i = 0; i < 14; ++i)
3422         {
3423             if (BitIsSet (registers, i))
3424             {
3425                 context.type = EmulateInstruction::eContextRegisterPlusOffset;
3426                 context.SetRegisterPlusOffset (dwarf_reg, offset);
3427                 if (wback && (n == 13)) // Pop Instruction
3428                 {
3429                     if (conditional)
3430                         context.type = EmulateInstruction::eContextRegisterLoad;
3431                     else
3432                         context.type = EmulateInstruction::eContextPopRegisterOffStack;
3433                 }
3434 
3435                 // R[i] = MemA [address, 4]; address = address + 4;
3436                 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3437                 if (!success)
3438                     return false;
3439 
3440                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3441                     return false;
3442 
3443                 offset += addr_byte_size;
3444             }
3445         }
3446 
3447         if (BitIsSet (registers, 15))
3448         {
3449             //LoadWritePC (MemA [address, 4]);
3450             context.type = EmulateInstruction::eContextRegisterPlusOffset;
3451             context.SetRegisterPlusOffset (dwarf_reg, offset);
3452             uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3453             if (!success)
3454                 return false;
3455             // In ARMv5T and above, this is an interworking branch.
3456             if (!LoadWritePC(context, data))
3457                 return false;
3458         }
3459 
3460         if (wback && BitIsClear (registers, n))
3461         {
3462             // R[n] = R[n] + 4 * BitCount (registers)
3463             int32_t offset = addr_byte_size * BitCount (registers);
3464             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3465             context.SetRegisterPlusOffset (dwarf_reg, offset);
3466 
3467             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
3468                 return false;
3469         }
3470         if (wback && BitIsSet (registers, n))
3471             // R[n] bits(32) UNKNOWN;
3472             return WriteBits32Unknown (n);
3473     }
3474     return true;
3475 }
3476 
3477 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register.
3478 // The consecutive memory locations end at this address and the address just below the lowest of those locations
3479 // can optionally be written back to the base register.
3480 bool
3481 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding)
3482 {
3483 #if 0
3484     // ARM pseudo code...
3485     if ConditionPassed() then
3486         EncodingSpecificOperations();
3487         address = R[n] - 4*BitCount(registers) + 4;
3488 
3489         for i = 0 to 14
3490             if registers<i> == '1' then
3491                   R[i] = MemA[address,4]; address = address + 4;
3492 
3493         if registers<15> == '1' then
3494             LoadWritePC(MemA[address,4]);
3495 
3496         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3497         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3498 #endif
3499 
3500     bool success = false;
3501 
3502     if (ConditionPassed(opcode))
3503     {
3504         uint32_t n;
3505         uint32_t registers = 0;
3506         bool wback;
3507         const uint32_t addr_byte_size = GetAddressByteSize();
3508 
3509         // EncodingSpecificOperations();
3510         switch (encoding)
3511         {
3512             case eEncodingA1:
3513                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3514                 n = Bits32 (opcode, 19, 16);
3515                 registers = Bits32 (opcode, 15, 0);
3516                 wback = BitIsSet (opcode, 21);
3517 
3518                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3519                 if ((n == 15) || (BitCount (registers) < 1))
3520                     return false;
3521 
3522                 break;
3523 
3524             default:
3525                 return false;
3526         }
3527         // address = R[n] - 4*BitCount(registers) + 4;
3528 
3529         int32_t offset = 0;
3530         addr_t Rn = ReadCoreReg (n, &success);
3531 
3532         if (!success)
3533             return false;
3534 
3535         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size;
3536 
3537         EmulateInstruction::Context context;
3538         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3539         RegisterInfo dwarf_reg;
3540         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3541         context.SetRegisterPlusOffset (dwarf_reg, offset);
3542 
3543         // for i = 0 to 14
3544         for (int i = 0; i < 14; ++i)
3545         {
3546             // if registers<i> == '1' then
3547             if (BitIsSet (registers, i))
3548             {
3549                   // R[i] = MemA[address,4]; address = address + 4;
3550                   context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3551                   uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3552                   if (!success)
3553                       return false;
3554                   if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3555                       return false;
3556                   offset += addr_byte_size;
3557             }
3558         }
3559 
3560         // if registers<15> == '1' then
3561         //     LoadWritePC(MemA[address,4]);
3562         if (BitIsSet (registers, 15))
3563         {
3564             context.SetRegisterPlusOffset (dwarf_reg, offset);
3565             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3566             if (!success)
3567                 return false;
3568             // In ARMv5T and above, this is an interworking branch.
3569             if (!LoadWritePC(context, data))
3570                 return false;
3571         }
3572 
3573         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3574         if (wback && BitIsClear (registers, n))
3575         {
3576             if (!success)
3577                 return false;
3578 
3579             offset = (addr_byte_size * BitCount (registers)) * -1;
3580             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3581             context.SetImmediateSigned (offset);
3582             addr_t addr = Rn + offset;
3583             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3584                 return false;
3585         }
3586 
3587         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3588         if (wback && BitIsSet (registers, n))
3589             return WriteBits32Unknown (n);
3590     }
3591     return true;
3592 }
3593 
3594 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
3595 // consecutive memory lcoations end just below this address, and the address of the lowest of those locations can
3596 // be optionally written back to the base register.
3597 bool
3598 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding)
3599 {
3600 #if 0
3601     // ARM pseudo code...
3602     if ConditionPassed() then
3603         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3604         address = R[n] - 4*BitCount(registers);
3605 
3606         for i = 0 to 14
3607             if registers<i> == '1' then
3608                   R[i] = MemA[address,4]; address = address + 4;
3609         if registers<15> == '1' then
3610                   LoadWritePC(MemA[address,4]);
3611 
3612         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3613         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3614 #endif
3615 
3616     bool success = false;
3617 
3618     if (ConditionPassed(opcode))
3619     {
3620         uint32_t n;
3621         uint32_t registers = 0;
3622         bool wback;
3623         const uint32_t addr_byte_size = GetAddressByteSize();
3624         switch (encoding)
3625         {
3626             case eEncodingT1:
3627                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3628                 n = Bits32 (opcode, 19, 16);
3629                 registers = Bits32 (opcode, 15, 0);
3630                 registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
3631                 wback = BitIsSet (opcode, 21);
3632 
3633                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3634                 if ((n == 15)
3635                     || (BitCount (registers) < 2)
3636                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3637                     return false;
3638 
3639                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3640                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3641                     return false;
3642 
3643                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3644                 if (wback && BitIsSet (registers, n))
3645                     return false;
3646 
3647                 break;
3648 
3649             case eEncodingA1:
3650                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3651                 n = Bits32 (opcode, 19, 16);
3652                 registers = Bits32 (opcode, 15, 0);
3653                 wback = BitIsSet (opcode, 21);
3654 
3655                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3656                 if ((n == 15) || (BitCount (registers) < 1))
3657                     return false;
3658 
3659                 break;
3660 
3661             default:
3662                 return false;
3663         }
3664 
3665         // address = R[n] - 4*BitCount(registers);
3666 
3667         int32_t offset = 0;
3668         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3669 
3670         if (!success)
3671             return false;
3672 
3673         addr_t address = Rn - (addr_byte_size * BitCount (registers));
3674         EmulateInstruction::Context context;
3675         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3676         RegisterInfo dwarf_reg;
3677         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3678         context.SetRegisterPlusOffset (dwarf_reg, Rn - address);
3679 
3680         for (int i = 0; i < 14; ++i)
3681         {
3682             if (BitIsSet (registers, i))
3683             {
3684                 // R[i] = MemA[address,4]; address = address + 4;
3685                 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3686                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3687                 if (!success)
3688                     return false;
3689 
3690                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3691                     return false;
3692 
3693                 offset += addr_byte_size;
3694             }
3695         }
3696 
3697         // if registers<15> == '1' then
3698         //     LoadWritePC(MemA[address,4]);
3699         if (BitIsSet (registers, 15))
3700         {
3701             context.SetRegisterPlusOffset (dwarf_reg, offset);
3702             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3703             if (!success)
3704                 return false;
3705             // In ARMv5T and above, this is an interworking branch.
3706             if (!LoadWritePC(context, data))
3707                 return false;
3708         }
3709 
3710         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3711         if (wback && BitIsClear (registers, n))
3712         {
3713             if (!success)
3714                 return false;
3715 
3716             offset = (addr_byte_size * BitCount (registers)) * -1;
3717             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3718             context.SetImmediateSigned (offset);
3719             addr_t addr = Rn + offset;
3720             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3721                 return false;
3722         }
3723 
3724         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3725         if (wback && BitIsSet (registers, n))
3726             return WriteBits32Unknown (n);
3727     }
3728     return true;
3729 }
3730 
3731 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
3732 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can
3733 // optinoally be written back to the base register.
3734 bool
3735 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding)
3736 {
3737 #if 0
3738     if ConditionPassed() then
3739         EncodingSpecificOperations();
3740         address = R[n] + 4;
3741 
3742         for i = 0 to 14
3743             if registers<i> == '1' then
3744                   R[i] = MemA[address,4]; address = address + 4;
3745         if registers<15> == '1' then
3746             LoadWritePC(MemA[address,4]);
3747 
3748         if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3749         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3750 #endif
3751 
3752     bool success = false;
3753 
3754     if (ConditionPassed(opcode))
3755     {
3756         uint32_t n;
3757         uint32_t registers = 0;
3758         bool wback;
3759         const uint32_t addr_byte_size = GetAddressByteSize();
3760         switch (encoding)
3761         {
3762             case eEncodingA1:
3763                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3764                 n = Bits32 (opcode, 19, 16);
3765                 registers = Bits32 (opcode, 15, 0);
3766                 wback = BitIsSet (opcode, 21);
3767 
3768                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3769                 if ((n == 15) || (BitCount (registers) < 1))
3770                     return false;
3771 
3772                 break;
3773             default:
3774                 return false;
3775         }
3776         // address = R[n] + 4;
3777 
3778         int32_t offset = 0;
3779         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3780 
3781         if (!success)
3782             return false;
3783 
3784         addr_t address = Rn + addr_byte_size;
3785 
3786         EmulateInstruction::Context context;
3787         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3788         RegisterInfo dwarf_reg;
3789         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3790         context.SetRegisterPlusOffset (dwarf_reg, offset);
3791 
3792         for (int i = 0; i < 14; ++i)
3793         {
3794             if (BitIsSet (registers, i))
3795             {
3796                 // R[i] = MemA[address,4]; address = address + 4;
3797 
3798                 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size);
3799                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3800                 if (!success)
3801                     return false;
3802 
3803                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3804                     return false;
3805 
3806                 offset += addr_byte_size;
3807             }
3808         }
3809 
3810         // if registers<15> == '1' then
3811         //     LoadWritePC(MemA[address,4]);
3812         if (BitIsSet (registers, 15))
3813         {
3814             context.SetRegisterPlusOffset (dwarf_reg, offset);
3815             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3816             if (!success)
3817                 return false;
3818             // In ARMv5T and above, this is an interworking branch.
3819             if (!LoadWritePC(context, data))
3820                 return false;
3821         }
3822 
3823         // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3824         if (wback && BitIsClear (registers, n))
3825         {
3826             if (!success)
3827                 return false;
3828 
3829             offset = addr_byte_size * BitCount (registers);
3830             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3831             context.SetImmediateSigned (offset);
3832             addr_t addr = Rn + offset;
3833             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3834                 return false;
3835         }
3836 
3837         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3838         if (wback && BitIsSet (registers, n))
3839             return WriteBits32Unknown (n);
3840     }
3841     return true;
3842 }
3843 
3844 // Load Register (immediate) calculates an address from a base register value and
3845 // an immediate offset, loads a word from memory, and writes to a register.
3846 // LDR (immediate, Thumb)
3847 bool
3848 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding)
3849 {
3850 #if 0
3851     // ARM pseudo code...
3852     if (ConditionPassed())
3853     {
3854         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3855         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3856         address = if index then offset_addr else R[n];
3857         data = MemU[address,4];
3858         if wback then R[n] = offset_addr;
3859         if t == 15 then
3860             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3861         elsif UnalignedSupport() || address<1:0> = '00' then
3862             R[t] = data;
3863         else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3864     }
3865 #endif
3866 
3867     bool success = false;
3868 
3869     if (ConditionPassed(opcode))
3870     {
3871         uint32_t Rt; // the destination register
3872         uint32_t Rn; // the base register
3873         uint32_t imm32; // the immediate offset used to form the address
3874         addr_t offset_addr; // the offset address
3875         addr_t address; // the calculated address
3876         uint32_t data; // the literal data value from memory load
3877         bool add, index, wback;
3878         switch (encoding) {
3879             case eEncodingT1:
3880                 Rt = Bits32(opcode, 2, 0);
3881                 Rn = Bits32(opcode, 5, 3);
3882                 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3883                 // index = TRUE; add = TRUE; wback = FALSE
3884                 add = true;
3885                 index = true;
3886                 wback = false;
3887 
3888                 break;
3889 
3890             case eEncodingT2:
3891                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
3892                 Rt = Bits32 (opcode, 10, 8);
3893                 Rn = 13;
3894                 imm32 = Bits32 (opcode, 7, 0) << 2;
3895 
3896                 // index = TRUE; add = TRUE; wback = FALSE;
3897                 index = true;
3898                 add = true;
3899                 wback = false;
3900 
3901                 break;
3902 
3903             case eEncodingT3:
3904                 // if Rn == '1111' then SEE LDR (literal);
3905                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
3906                 Rt = Bits32 (opcode, 15, 12);
3907                 Rn = Bits32 (opcode, 19, 16);
3908                 imm32 = Bits32 (opcode, 11, 0);
3909 
3910                 // index = TRUE; add = TRUE; wback = FALSE;
3911                 index = true;
3912                 add = true;
3913                 wback = false;
3914 
3915                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3916                 if ((Rt == 15) && InITBlock() && !LastInITBlock())
3917                     return false;
3918 
3919                 break;
3920 
3921             case eEncodingT4:
3922                 // if Rn == '1111' then SEE LDR (literal);
3923                 // if P == '1' && U == '1' && W == '0' then SEE LDRT;
3924                 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
3925                 // if P == '0' && W == '0' then UNDEFINED;
3926                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
3927                     return false;
3928 
3929                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
3930                 Rt = Bits32 (opcode, 15, 12);
3931                 Rn = Bits32 (opcode, 19, 16);
3932                 imm32 = Bits32 (opcode, 7, 0);
3933 
3934                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
3935                 index = BitIsSet (opcode, 10);
3936                 add = BitIsSet (opcode, 9);
3937                 wback = BitIsSet (opcode, 8);
3938 
3939                 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
3940                 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock()))
3941                     return false;
3942 
3943                 break;
3944 
3945             default:
3946                 return false;
3947         }
3948         uint32_t base = ReadCoreReg (Rn, &success);
3949         if (!success)
3950             return false;
3951         if (add)
3952             offset_addr = base + imm32;
3953         else
3954             offset_addr = base - imm32;
3955 
3956         address = (index ? offset_addr : base);
3957 
3958         RegisterInfo base_reg;
3959         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
3960         if (wback)
3961         {
3962             EmulateInstruction::Context ctx;
3963             ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
3964             ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3965 
3966             if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
3967                 return false;
3968         }
3969 
3970         // Prepare to write to the Rt register.
3971         EmulateInstruction::Context context;
3972         context.type = EmulateInstruction::eContextRegisterLoad;
3973         context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3974 
3975         // Read memory from the address.
3976         data = MemURead(context, address, 4, 0, &success);
3977         if (!success)
3978             return false;
3979 
3980         if (Rt == 15)
3981         {
3982             if (Bits32(address, 1, 0) == 0)
3983             {
3984                 if (!LoadWritePC(context, data))
3985                     return false;
3986             }
3987             else
3988                 return false;
3989         }
3990         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
3991         {
3992             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
3993                 return false;
3994         }
3995         else
3996             WriteBits32Unknown (Rt);
3997     }
3998     return true;
3999 }
4000 
4001 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
4002 // from a base register.  The consecutive memory locations start at this address, and teh address just above the last
4003 // of those locations can optionally be written back to the base register.
4004 bool
4005 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding)
4006 {
4007 #if 0
4008     if ConditionPassed() then
4009         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4010         address = R[n];
4011 
4012         for i = 0 to 14
4013             if registers<i> == '1' then
4014                 if i == n && wback && i != LowestSetBit(registers) then
4015                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4016                 else
4017                     MemA[address,4] = R[i];
4018                 address = address + 4;
4019 
4020         if registers<15> == '1' then // Only possible for encoding A1
4021             MemA[address,4] = PCStoreValue();
4022         if wback then R[n] = R[n] + 4*BitCount(registers);
4023 #endif
4024 
4025     bool success = false;
4026 
4027     if (ConditionPassed(opcode))
4028     {
4029         uint32_t n;
4030         uint32_t registers = 0;
4031         bool wback;
4032         const uint32_t addr_byte_size = GetAddressByteSize();
4033 
4034         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4035         switch (encoding)
4036         {
4037             case eEncodingT1:
4038                 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4039                 n = Bits32 (opcode, 10, 8);
4040                 registers = Bits32 (opcode, 7, 0);
4041                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
4042                 wback = true;
4043 
4044                 // if BitCount(registers) < 1 then UNPREDICTABLE;
4045                 if (BitCount (registers) < 1)
4046                     return false;
4047 
4048                 break;
4049 
4050             case eEncodingT2:
4051                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4052                 n = Bits32 (opcode, 19, 16);
4053                 registers = Bits32 (opcode, 15, 0);
4054                 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4055                 wback = BitIsSet (opcode, 21);
4056 
4057                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4058                 if ((n == 15) || (BitCount (registers) < 2))
4059                     return false;
4060 
4061                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4062                 if (wback && BitIsSet (registers, n))
4063                     return false;
4064 
4065                 break;
4066 
4067             case eEncodingA1:
4068                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4069                 n = Bits32 (opcode, 19, 16);
4070                 registers = Bits32 (opcode, 15, 0);
4071                 wback = BitIsSet (opcode, 21);
4072 
4073                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4074                 if ((n == 15) || (BitCount (registers) < 1))
4075                     return false;
4076 
4077                 break;
4078 
4079             default:
4080                 return false;
4081         }
4082 
4083         // address = R[n];
4084         int32_t offset = 0;
4085         const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4086         if (!success)
4087             return false;
4088 
4089         EmulateInstruction::Context context;
4090         context.type = EmulateInstruction::eContextRegisterStore;
4091         RegisterInfo base_reg;
4092         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4093 
4094         // for i = 0 to 14
4095         int lowest_set_bit = 14;
4096         for (int i = 0; i < 14; ++i)
4097         {
4098             // if registers<i> == '1' then
4099             if (BitIsSet (registers, i))
4100             {
4101                   if (i < lowest_set_bit)
4102                       lowest_set_bit = i;
4103                   // if i == n && wback && i != LowestSetBit(registers) then
4104                   if ((i == n) && wback && (i != lowest_set_bit))
4105                       // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4106                       WriteBits32UnknownToMemory (address + offset);
4107                   else
4108                   {
4109                      // MemA[address,4] = R[i];
4110                       uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4111                       if (!success)
4112                           return false;
4113 
4114                       RegisterInfo data_reg;
4115                       GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4116                       context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4117                       if (!MemAWrite (context, address + offset, data, addr_byte_size))
4118                           return false;
4119                   }
4120 
4121                   // address = address + 4;
4122                   offset += addr_byte_size;
4123             }
4124         }
4125 
4126         // if registers<15> == '1' then // Only possible for encoding A1
4127         //     MemA[address,4] = PCStoreValue();
4128         if (BitIsSet (registers, 15))
4129         {
4130             RegisterInfo pc_reg;
4131             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4132             context.SetRegisterPlusOffset (pc_reg, 8);
4133             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4134             if (!success)
4135                 return false;
4136 
4137             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4138                 return false;
4139         }
4140 
4141         // if wback then R[n] = R[n] + 4*BitCount(registers);
4142         if (wback)
4143         {
4144             offset = addr_byte_size * BitCount (registers);
4145             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4146             context.SetImmediateSigned (offset);
4147             addr_t data = address + offset;
4148             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4149                 return false;
4150         }
4151     }
4152     return true;
4153 }
4154 
4155 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
4156 // from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
4157 // of those locations can optionally be written back to the base register.
4158 bool
4159 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding)
4160 {
4161 #if 0
4162     if ConditionPassed() then
4163         EncodingSpecificOperations();
4164         address = R[n] - 4*BitCount(registers) + 4;
4165 
4166         for i = 0 to 14
4167             if registers<i> == '1' then
4168                 if i == n && wback && i != LowestSetBit(registers) then
4169                     MemA[address,4] = bits(32) UNKNOWN;
4170                 else
4171                     MemA[address,4] = R[i];
4172                 address = address + 4;
4173 
4174         if registers<15> == '1' then
4175             MemA[address,4] = PCStoreValue();
4176 
4177         if wback then R[n] = R[n] - 4*BitCount(registers);
4178 #endif
4179 
4180     bool success = false;
4181 
4182     if (ConditionPassed(opcode))
4183     {
4184         uint32_t n;
4185         uint32_t registers = 0;
4186         bool wback;
4187         const uint32_t addr_byte_size = GetAddressByteSize();
4188 
4189         // EncodingSpecificOperations();
4190         switch (encoding)
4191         {
4192             case eEncodingA1:
4193                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4194                 n = Bits32 (opcode, 19, 16);
4195                 registers = Bits32 (opcode, 15, 0);
4196                 wback = BitIsSet (opcode, 21);
4197 
4198                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4199                 if ((n == 15) || (BitCount (registers) < 1))
4200                     return false;
4201                 break;
4202             default:
4203                 return false;
4204         }
4205 
4206         // address = R[n] - 4*BitCount(registers) + 4;
4207         int32_t offset = 0;
4208         addr_t Rn = ReadCoreReg (n, &success);
4209         if (!success)
4210             return false;
4211 
4212         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4;
4213 
4214         EmulateInstruction::Context context;
4215         context.type = EmulateInstruction::eContextRegisterStore;
4216         RegisterInfo base_reg;
4217         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4218 
4219         // for i = 0 to 14
4220         int lowest_bit_set = 14;
4221         for (int i = 0; i < 14; ++i)
4222         {
4223             // if registers<i> == '1' then
4224             if (BitIsSet (registers, i))
4225             {
4226                 if (i < lowest_bit_set)
4227                     lowest_bit_set = i;
4228                 //if i == n && wback && i != LowestSetBit(registers) then
4229                 if ((i == n) && wback && (i != lowest_bit_set))
4230                     // MemA[address,4] = bits(32) UNKNOWN;
4231                     WriteBits32UnknownToMemory (address + offset);
4232                 else
4233                 {
4234                     // MemA[address,4] = R[i];
4235                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4236                     if (!success)
4237                         return false;
4238 
4239                     RegisterInfo data_reg;
4240                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4241                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4242                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4243                         return false;
4244                 }
4245 
4246                 // address = address + 4;
4247                 offset += addr_byte_size;
4248             }
4249         }
4250 
4251         // if registers<15> == '1' then
4252         //    MemA[address,4] = PCStoreValue();
4253         if (BitIsSet (registers, 15))
4254         {
4255             RegisterInfo pc_reg;
4256             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4257             context.SetRegisterPlusOffset (pc_reg, 8);
4258             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4259             if (!success)
4260                 return false;
4261 
4262             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4263                 return false;
4264         }
4265 
4266         // if wback then R[n] = R[n] - 4*BitCount(registers);
4267         if (wback)
4268         {
4269             offset = (addr_byte_size * BitCount (registers)) * -1;
4270             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4271             context.SetImmediateSigned (offset);
4272             addr_t data = Rn + offset;
4273             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4274                 return false;
4275         }
4276     }
4277     return true;
4278 }
4279 
4280 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
4281 // from a base register.  The consecutive memory locations end just below this address, and the address of the first of
4282 // those locations can optionally be written back to the base register.
4283 bool
4284 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding)
4285 {
4286 #if 0
4287     if ConditionPassed() then
4288         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4289         address = R[n] - 4*BitCount(registers);
4290 
4291         for i = 0 to 14
4292             if registers<i> == '1' then
4293                 if i == n && wback && i != LowestSetBit(registers) then
4294                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4295                 else
4296                     MemA[address,4] = R[i];
4297                 address = address + 4;
4298 
4299         if registers<15> == '1' then // Only possible for encoding A1
4300             MemA[address,4] = PCStoreValue();
4301 
4302         if wback then R[n] = R[n] - 4*BitCount(registers);
4303 #endif
4304 
4305 
4306     bool success = false;
4307 
4308     if (ConditionPassed(opcode))
4309     {
4310         uint32_t n;
4311         uint32_t registers = 0;
4312         bool wback;
4313         const uint32_t addr_byte_size = GetAddressByteSize();
4314 
4315         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4316         switch (encoding)
4317         {
4318             case eEncodingT1:
4319                 // if W == '1' && Rn == '1101' then SEE PUSH;
4320                 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
4321                 {
4322                     // See PUSH
4323                 }
4324                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4325                 n = Bits32 (opcode, 19, 16);
4326                 registers = Bits32 (opcode, 15, 0);
4327                 registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
4328                 wback = BitIsSet (opcode, 21);
4329                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4330                 if ((n == 15) || BitCount (registers) < 2)
4331                     return false;
4332                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4333                 if (wback && BitIsSet (registers, n))
4334                     return false;
4335                 break;
4336 
4337             case eEncodingA1:
4338                 // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH;
4339                 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
4340                 {
4341                     // See Push
4342                 }
4343                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4344                 n = Bits32 (opcode, 19, 16);
4345                 registers = Bits32 (opcode, 15, 0);
4346                 wback = BitIsSet (opcode, 21);
4347                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4348                 if ((n == 15) || BitCount (registers) < 1)
4349                     return false;
4350                 break;
4351 
4352             default:
4353                 return false;
4354         }
4355 
4356         // address = R[n] - 4*BitCount(registers);
4357 
4358         int32_t offset = 0;
4359         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4360         if (!success)
4361         return false;
4362 
4363         addr_t address = Rn - (addr_byte_size * BitCount (registers));
4364 
4365         EmulateInstruction::Context context;
4366         context.type = EmulateInstruction::eContextRegisterStore;
4367         RegisterInfo base_reg;
4368         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4369 
4370         // for i = 0 to 14
4371         uint32_t lowest_set_bit = 14;
4372         for (int i = 0; i < 14; ++i)
4373         {
4374             // if registers<i> == '1' then
4375             if (BitIsSet (registers, i))
4376             {
4377                 if (i < lowest_set_bit)
4378                     lowest_set_bit = i;
4379                 // if i == n && wback && i != LowestSetBit(registers) then
4380                 if ((i == n) && wback && (i != lowest_set_bit))
4381                     // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4382                     WriteBits32UnknownToMemory (address + offset);
4383                 else
4384                 {
4385                     // MemA[address,4] = R[i];
4386                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4387                     if (!success)
4388                         return false;
4389 
4390                     RegisterInfo data_reg;
4391                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4392                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4393                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4394                         return false;
4395                 }
4396 
4397                 // address = address + 4;
4398                 offset += addr_byte_size;
4399             }
4400         }
4401 
4402         // if registers<15> == '1' then // Only possible for encoding A1
4403         //     MemA[address,4] = PCStoreValue();
4404         if (BitIsSet (registers, 15))
4405         {
4406             RegisterInfo pc_reg;
4407             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4408             context.SetRegisterPlusOffset (pc_reg, 8);
4409             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4410             if (!success)
4411                 return false;
4412 
4413             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4414                 return false;
4415         }
4416 
4417         // if wback then R[n] = R[n] - 4*BitCount(registers);
4418         if (wback)
4419         {
4420             offset = (addr_byte_size * BitCount (registers)) * -1;
4421             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4422             context.SetImmediateSigned (offset);
4423             addr_t data = Rn + offset;
4424             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4425                 return false;
4426         }
4427     }
4428     return true;
4429 }
4430 
4431 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
4432 // from a base register.  The consecutive memory locations start just above this address, and the address of the last
4433 // of those locations can optionally be written back to the base register.
4434 bool
4435 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding)
4436 {
4437 #if 0
4438     if ConditionPassed() then
4439         EncodingSpecificOperations();
4440         address = R[n] + 4;
4441 
4442         for i = 0 to 14
4443             if registers<i> == '1' then
4444                 if i == n && wback && i != LowestSetBit(registers) then
4445                     MemA[address,4] = bits(32) UNKNOWN;
4446                 else
4447                     MemA[address,4] = R[i];
4448                 address = address + 4;
4449 
4450         if registers<15> == '1' then
4451             MemA[address,4] = PCStoreValue();
4452 
4453         if wback then R[n] = R[n] + 4*BitCount(registers);
4454 #endif
4455 
4456     bool success = false;
4457 
4458     if (ConditionPassed(opcode))
4459     {
4460         uint32_t n;
4461         uint32_t registers = 0;
4462         bool wback;
4463         const uint32_t addr_byte_size = GetAddressByteSize();
4464 
4465         // EncodingSpecificOperations();
4466         switch (encoding)
4467         {
4468             case eEncodingA1:
4469                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4470                 n = Bits32 (opcode, 19, 16);
4471                 registers = Bits32 (opcode, 15, 0);
4472                 wback = BitIsSet (opcode, 21);
4473 
4474                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4475                 if ((n == 15) && (BitCount (registers) < 1))
4476                     return false;
4477                 break;
4478             default:
4479                 return false;
4480         }
4481         // address = R[n] + 4;
4482 
4483         int32_t offset = 0;
4484         addr_t Rn = ReadCoreReg (n, &success);
4485         if (!success)
4486             return false;
4487 
4488         addr_t address = Rn + addr_byte_size;
4489 
4490         EmulateInstruction::Context context;
4491         context.type = EmulateInstruction::eContextRegisterStore;
4492         RegisterInfo base_reg;
4493         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4494 
4495         uint32_t lowest_set_bit = 14;
4496         // for i = 0 to 14
4497         for (int i = 0; i < 14; ++i)
4498         {
4499             // if registers<i> == '1' then
4500             if (BitIsSet (registers, i))
4501             {
4502                 if (i < lowest_set_bit)
4503                     lowest_set_bit = i;
4504                 // if i == n && wback && i != LowestSetBit(registers) then
4505                 if ((i == n) && wback && (i != lowest_set_bit))
4506                     // MemA[address,4] = bits(32) UNKNOWN;
4507                     WriteBits32UnknownToMemory (address + offset);
4508                 // else
4509                 else
4510                 {
4511                     // MemA[address,4] = R[i];
4512                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4513                     if (!success)
4514                         return false;
4515 
4516                     RegisterInfo data_reg;
4517                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4518                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size);
4519                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4520                         return false;
4521                 }
4522 
4523                 // address = address + 4;
4524                 offset += addr_byte_size;
4525             }
4526         }
4527 
4528         // if registers<15> == '1' then
4529             // MemA[address,4] = PCStoreValue();
4530         if (BitIsSet (registers, 15))
4531         {
4532             RegisterInfo pc_reg;
4533             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4534             context.SetRegisterPlusOffset (pc_reg, 8);
4535             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4536             if (!success)
4537             return false;
4538 
4539             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4540                 return false;
4541         }
4542 
4543         // if wback then R[n] = R[n] + 4*BitCount(registers);
4544         if (wback)
4545         {
4546             offset = addr_byte_size * BitCount (registers);
4547             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4548             context.SetImmediateSigned (offset);
4549             addr_t data = Rn + offset;
4550             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4551                 return false;
4552         }
4553     }
4554     return true;
4555 }
4556 
4557 // STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word
4558 // from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
4559 bool
4560 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding)
4561 {
4562 #if 0
4563     if ConditionPassed() then
4564         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4565         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4566         address = if index then offset_addr else R[n];
4567         if UnalignedSupport() || address<1:0> == '00' then
4568             MemU[address,4] = R[t];
4569         else // Can only occur before ARMv7
4570             MemU[address,4] = bits(32) UNKNOWN;
4571         if wback then R[n] = offset_addr;
4572 #endif
4573 
4574     bool success = false;
4575 
4576     if (ConditionPassed(opcode))
4577     {
4578         const uint32_t addr_byte_size = GetAddressByteSize();
4579 
4580         uint32_t t;
4581         uint32_t n;
4582         uint32_t imm32;
4583         bool index;
4584         bool add;
4585         bool wback;
4586         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4587         switch (encoding)
4588         {
4589             case eEncodingT1:
4590                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
4591                 t = Bits32 (opcode, 2, 0);
4592                 n = Bits32 (opcode, 5, 3);
4593                 imm32 = Bits32 (opcode, 10, 6) << 2;
4594 
4595                 // index = TRUE; add = TRUE; wback = FALSE;
4596                 index = true;
4597                 add = false;
4598                 wback = false;
4599                 break;
4600 
4601             case eEncodingT2:
4602                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4603                 t = Bits32 (opcode, 10, 8);
4604                 n = 13;
4605                 imm32 = Bits32 (opcode, 7, 0) << 2;
4606 
4607                 // index = TRUE; add = TRUE; wback = FALSE;
4608                 index = true;
4609                 add = true;
4610                 wback = false;
4611                 break;
4612 
4613             case eEncodingT3:
4614                 // if Rn == '1111' then UNDEFINED;
4615                 if (Bits32 (opcode, 19, 16) == 15)
4616                     return false;
4617 
4618                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4619                 t = Bits32 (opcode, 15, 12);
4620                 n = Bits32 (opcode, 19, 16);
4621                 imm32 = Bits32 (opcode, 11, 0);
4622 
4623                 // index = TRUE; add = TRUE; wback = FALSE;
4624                 index = true;
4625                 add = true;
4626                 wback = false;
4627 
4628                 // if t == 15 then UNPREDICTABLE;
4629                 if (t == 15)
4630                     return false;
4631                 break;
4632 
4633             case eEncodingT4:
4634                 // if P == '1' && U == '1' && W == '0' then SEE STRT;
4635                 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH;
4636                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4637                 if ((Bits32 (opcode, 19, 16) == 15)
4638                       || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
4639                     return false;
4640 
4641                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4642                 t = Bits32 (opcode, 15, 12);
4643                 n = Bits32 (opcode, 19, 16);
4644                 imm32 = Bits32 (opcode, 7, 0);
4645 
4646                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4647                 index = BitIsSet (opcode, 10);
4648                 add = BitIsSet (opcode, 9);
4649                 wback = BitIsSet (opcode, 8);
4650 
4651                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
4652                 if ((t == 15) || (wback && (n == t)))
4653                     return false;
4654                 break;
4655 
4656             default:
4657                 return false;
4658         }
4659 
4660         addr_t offset_addr;
4661         addr_t address;
4662 
4663         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4664         uint32_t base_address = ReadCoreReg (n, &success);
4665         if (!success)
4666             return false;
4667 
4668         if (add)
4669             offset_addr = base_address + imm32;
4670         else
4671             offset_addr = base_address - imm32;
4672 
4673         // address = if index then offset_addr else R[n];
4674         if (index)
4675             address = offset_addr;
4676         else
4677             address = base_address;
4678 
4679         EmulateInstruction::Context context;
4680         context.type = eContextRegisterStore;
4681         RegisterInfo base_reg;
4682         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4683 
4684         // if UnalignedSupport() || address<1:0> == '00' then
4685         if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
4686         {
4687             // MemU[address,4] = R[t];
4688             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4689             if (!success)
4690                 return false;
4691 
4692             RegisterInfo data_reg;
4693             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4694             int32_t offset = address - base_address;
4695             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4696             if (!MemUWrite (context, address, data, addr_byte_size))
4697                 return false;
4698         }
4699         else
4700         {
4701             // MemU[address,4] = bits(32) UNKNOWN;
4702             WriteBits32UnknownToMemory (address);
4703         }
4704 
4705         // if wback then R[n] = offset_addr;
4706         if (wback)
4707         {
4708             context.type = eContextRegisterLoad;
4709             context.SetAddress (offset_addr);
4710             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4711                 return false;
4712         }
4713     }
4714     return true;
4715 }
4716 
4717 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a
4718 // word from a register to memory.   The offset register value can optionally be shifted.
4719 bool
4720 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding)
4721 {
4722 #if 0
4723     if ConditionPassed() then
4724         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4725         offset = Shift(R[m], shift_t, shift_n, APSR.C);
4726         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4727         address = if index then offset_addr else R[n];
4728         if t == 15 then // Only possible for encoding A1
4729             data = PCStoreValue();
4730         else
4731             data = R[t];
4732         if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4733             MemU[address,4] = data;
4734         else // Can only occur before ARMv7
4735             MemU[address,4] = bits(32) UNKNOWN;
4736         if wback then R[n] = offset_addr;
4737 #endif
4738 
4739     bool success = false;
4740 
4741     if (ConditionPassed(opcode))
4742     {
4743         const uint32_t addr_byte_size = GetAddressByteSize();
4744 
4745         uint32_t t;
4746         uint32_t n;
4747         uint32_t m;
4748         ARM_ShifterType shift_t;
4749         uint32_t shift_n;
4750         bool index;
4751         bool add;
4752         bool wback;
4753 
4754         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4755         switch (encoding)
4756         {
4757             case eEncodingT1:
4758                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4759                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4760                 t = Bits32 (opcode, 2, 0);
4761                 n = Bits32 (opcode, 5, 3);
4762                 m = Bits32 (opcode, 8, 6);
4763 
4764                 // index = TRUE; add = TRUE; wback = FALSE;
4765                 index = true;
4766                 add = true;
4767                 wback = false;
4768 
4769                 // (shift_t, shift_n) = (SRType_LSL, 0);
4770                 shift_t = SRType_LSL;
4771                 shift_n = 0;
4772                 break;
4773 
4774             case eEncodingT2:
4775                 // if Rn == '1111' then UNDEFINED;
4776                 if (Bits32 (opcode, 19, 16) == 15)
4777                     return false;
4778 
4779                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4780                 t = Bits32 (opcode, 15, 12);
4781                 n = Bits32 (opcode, 19, 16);
4782                 m = Bits32 (opcode, 3, 0);
4783 
4784                 // index = TRUE; add = TRUE; wback = FALSE;
4785                 index = true;
4786                 add = true;
4787                 wback = false;
4788 
4789                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4790                 shift_t = SRType_LSL;
4791                 shift_n = Bits32 (opcode, 5, 4);
4792 
4793                 // if t == 15 || BadReg(m) then UNPREDICTABLE;
4794                 if ((t == 15) || (BadReg (m)))
4795                     return false;
4796                 break;
4797 
4798             case eEncodingA1:
4799             {
4800                 // if P == '0' && W == '1' then SEE STRT;
4801                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4802                 t = Bits32 (opcode, 15, 12);
4803                 n = Bits32 (opcode, 19, 16);
4804                 m = Bits32 (opcode, 3, 0);
4805 
4806                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
4807                 index = BitIsSet (opcode, 24);
4808                 add = BitIsSet (opcode, 23);
4809                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
4810 
4811                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
4812                 uint32_t typ = Bits32 (opcode, 6, 5);
4813                 uint32_t imm5 = Bits32 (opcode, 11, 7);
4814                 shift_n = DecodeImmShift(typ, imm5, shift_t);
4815 
4816                 // if m == 15 then UNPREDICTABLE;
4817                 if (m == 15)
4818                     return false;
4819 
4820                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
4821                 if (wback && ((n == 15) || (n == t)))
4822                     return false;
4823 
4824                 break;
4825             }
4826             default:
4827                 return false;
4828         }
4829 
4830         addr_t offset_addr;
4831         addr_t address;
4832         int32_t offset = 0;
4833 
4834         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4835         if (!success)
4836             return false;
4837 
4838         uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
4839         if (!success)
4840             return false;
4841 
4842         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4843         offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success);
4844         if (!success)
4845             return false;
4846 
4847         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4848         if (add)
4849             offset_addr = base_address + offset;
4850         else
4851             offset_addr = base_address - offset;
4852 
4853         // address = if index then offset_addr else R[n];
4854         if (index)
4855             address = offset_addr;
4856         else
4857             address = base_address;
4858 
4859         uint32_t data;
4860         // if t == 15 then // Only possible for encoding A1
4861         if (t == 15)
4862             // data = PCStoreValue();
4863             data = ReadCoreReg (PC_REG, &success);
4864         else
4865             // data = R[t];
4866             data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4867 
4868         if (!success)
4869             return false;
4870 
4871         EmulateInstruction::Context context;
4872         context.type = eContextRegisterStore;
4873 
4874         // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4875         if (UnalignedSupport ()
4876             || (BitIsClear (address, 1) && BitIsClear (address, 0))
4877             || CurrentInstrSet() == eModeARM)
4878         {
4879             // MemU[address,4] = data;
4880 
4881             RegisterInfo base_reg;
4882             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 +  n, base_reg);
4883 
4884             RegisterInfo data_reg;
4885             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4886 
4887             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4888             if (!MemUWrite (context, address, data, addr_byte_size))
4889                 return false;
4890 
4891         }
4892         else
4893             // MemU[address,4] = bits(32) UNKNOWN;
4894             WriteBits32UnknownToMemory (address);
4895 
4896         // if wback then R[n] = offset_addr;
4897         if (wback)
4898         {
4899             context.type = eContextRegisterLoad;
4900             context.SetAddress (offset_addr);
4901             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4902                 return false;
4903         }
4904 
4905     }
4906     return true;
4907 }
4908 
4909 bool
4910 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding)
4911 {
4912 #if 0
4913     if ConditionPassed() then
4914         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4915         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4916         address = if index then offset_addr else R[n];
4917         MemU[address,1] = R[t]<7:0>;
4918         if wback then R[n] = offset_addr;
4919 #endif
4920 
4921 
4922     bool success = false;
4923 
4924     if (ConditionPassed(opcode))
4925     {
4926         uint32_t t;
4927         uint32_t n;
4928         uint32_t imm32;
4929         bool index;
4930         bool add;
4931         bool wback;
4932         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4933         switch (encoding)
4934         {
4935             case eEncodingT1:
4936                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
4937                 t = Bits32 (opcode, 2, 0);
4938                 n = Bits32 (opcode, 5, 3);
4939                 imm32 = Bits32 (opcode, 10, 6);
4940 
4941                 // index = TRUE; add = TRUE; wback = FALSE;
4942                 index = true;
4943                 add = true;
4944                 wback = false;
4945                 break;
4946 
4947             case eEncodingT2:
4948                 // if Rn == '1111' then UNDEFINED;
4949                 if (Bits32 (opcode, 19, 16) == 15)
4950                     return false;
4951 
4952                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4953                 t = Bits32 (opcode, 15, 12);
4954                 n = Bits32 (opcode, 19, 16);
4955                 imm32 = Bits32 (opcode, 11, 0);
4956 
4957                 // index = TRUE; add = TRUE; wback = FALSE;
4958                 index = true;
4959                 add = true;
4960                 wback = false;
4961 
4962                 // if BadReg(t) then UNPREDICTABLE;
4963                 if (BadReg (t))
4964                     return false;
4965                 break;
4966 
4967             case eEncodingT3:
4968                 // if P == '1' && U == '1' && W == '0' then SEE STRBT;
4969                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4970                 if (Bits32 (opcode, 19, 16) == 15)
4971                     return false;
4972 
4973                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4974                 t = Bits32 (opcode, 15, 12);
4975                 n = Bits32 (opcode, 19, 16);
4976                 imm32 = Bits32 (opcode, 7, 0);
4977 
4978                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4979                 index = BitIsSet (opcode, 10);
4980                 add = BitIsSet (opcode, 9);
4981                 wback = BitIsSet (opcode, 8);
4982 
4983                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
4984                 if ((BadReg (t)) || (wback && (n == t)))
4985                     return false;
4986                 break;
4987 
4988             default:
4989                 return false;
4990         }
4991 
4992         addr_t offset_addr;
4993         addr_t address;
4994         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4995         if (!success)
4996             return false;
4997 
4998         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4999         if (add)
5000             offset_addr = base_address + imm32;
5001         else
5002             offset_addr = base_address - imm32;
5003 
5004         // address = if index then offset_addr else R[n];
5005         if (index)
5006             address = offset_addr;
5007         else
5008             address = base_address;
5009 
5010         // MemU[address,1] = R[t]<7:0>
5011         RegisterInfo base_reg;
5012         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5013 
5014         RegisterInfo data_reg;
5015         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5016 
5017         EmulateInstruction::Context context;
5018         context.type = eContextRegisterStore;
5019         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
5020 
5021         uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5022         if (!success)
5023             return false;
5024 
5025         data = Bits32 (data, 7, 0);
5026 
5027         if (!MemUWrite (context, address, data, 1))
5028             return false;
5029 
5030         // if wback then R[n] = offset_addr;
5031         if (wback)
5032         {
5033             context.type = eContextRegisterLoad;
5034             context.SetAddress (offset_addr);
5035             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5036                 return false;
5037         }
5038 
5039     }
5040 
5041     return true;
5042 }
5043 
5044 // STRH (register) calculates an address from a base register value and an offset register value, and stores a
5045 // halfword from a register to memory.  The offset register alue can be shifted left by 0, 1, 2, or 3 bits.
5046 bool
5047 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding)
5048 {
5049 #if 0
5050     if ConditionPassed() then
5051         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5052         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5053         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5054         address = if index then offset_addr else R[n];
5055         if UnalignedSupport() || address<0> == '0' then
5056             MemU[address,2] = R[t]<15:0>;
5057         else // Can only occur before ARMv7
5058             MemU[address,2] = bits(16) UNKNOWN;
5059         if wback then R[n] = offset_addr;
5060 #endif
5061 
5062     bool success = false;
5063 
5064     if (ConditionPassed(opcode))
5065     {
5066         uint32_t t;
5067         uint32_t n;
5068         uint32_t m;
5069         bool index;
5070         bool add;
5071         bool wback;
5072         ARM_ShifterType shift_t;
5073         uint32_t shift_n;
5074 
5075         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5076         switch (encoding)
5077         {
5078             case eEncodingT1:
5079                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5080                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5081                 t = Bits32 (opcode, 2, 0);
5082                 n = Bits32 (opcode, 5, 3);
5083                 m = Bits32 (opcode, 8, 6);
5084 
5085                 // index = TRUE; add = TRUE; wback = FALSE;
5086                 index = true;
5087                 add = true;
5088                 wback = false;
5089 
5090                 // (shift_t, shift_n) = (SRType_LSL, 0);
5091                 shift_t = SRType_LSL;
5092                 shift_n = 0;
5093 
5094                 break;
5095 
5096             case eEncodingT2:
5097                 // if Rn == '1111' then UNDEFINED;
5098                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5099                 t = Bits32 (opcode, 15, 12);
5100                 n = Bits32 (opcode, 19, 16);
5101                 m = Bits32 (opcode, 3, 0);
5102                 if (n == 15)
5103                     return false;
5104 
5105                 // index = TRUE; add = TRUE; wback = FALSE;
5106                 index = true;
5107                 add = true;
5108                 wback = false;
5109 
5110                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5111                 shift_t = SRType_LSL;
5112                 shift_n = Bits32 (opcode, 5, 4);
5113 
5114                 // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5115                 if (BadReg (t) || BadReg (m))
5116                     return false;
5117 
5118                 break;
5119 
5120             case eEncodingA1:
5121                 // if P == '0' && W == '1' then SEE STRHT;
5122                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5123                 t = Bits32 (opcode, 15, 12);
5124                 n = Bits32 (opcode, 19, 16);
5125                 m = Bits32 (opcode, 3, 0);
5126 
5127                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5128                 index = BitIsSet (opcode, 24);
5129                 add = BitIsSet (opcode, 23);
5130                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5131 
5132                 // (shift_t, shift_n) = (SRType_LSL, 0);
5133                 shift_t = SRType_LSL;
5134                 shift_n = 0;
5135 
5136                 // if t == 15 || m == 15 then UNPREDICTABLE;
5137                 if ((t == 15) || (m == 15))
5138                     return false;
5139 
5140                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5141                 if (wback && ((n == 15) || (n == t)))
5142                     return false;
5143 
5144                 break;
5145 
5146             default:
5147                 return false;
5148         }
5149 
5150         uint32_t Rm = ReadCoreReg (m, &success);
5151         if (!success)
5152             return false;
5153 
5154         uint32_t Rn = ReadCoreReg (n, &success);
5155         if (!success)
5156             return false;
5157 
5158         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5159         uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
5160         if (!success)
5161             return false;
5162 
5163         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5164         addr_t offset_addr;
5165         if (add)
5166             offset_addr = Rn + offset;
5167         else
5168             offset_addr = Rn - offset;
5169 
5170         // address = if index then offset_addr else R[n];
5171         addr_t address;
5172         if (index)
5173             address = offset_addr;
5174         else
5175             address = Rn;
5176 
5177         EmulateInstruction::Context context;
5178         context.type = eContextRegisterStore;
5179         RegisterInfo base_reg;
5180         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5181         RegisterInfo offset_reg;
5182         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5183 
5184         // if UnalignedSupport() || address<0> == '0' then
5185         if (UnalignedSupport() || BitIsClear (address, 0))
5186         {
5187             // MemU[address,2] = R[t]<15:0>;
5188             uint32_t Rt = ReadCoreReg (t, &success);
5189             if (!success)
5190                 return false;
5191 
5192             EmulateInstruction::Context context;
5193             context.type = eContextRegisterStore;
5194             RegisterInfo base_reg;
5195             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5196             RegisterInfo offset_reg;
5197             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5198             RegisterInfo data_reg;
5199             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5200             context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
5201 
5202             if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2))
5203                 return false;
5204         }
5205         else // Can only occur before ARMv7
5206         {
5207             // MemU[address,2] = bits(16) UNKNOWN;
5208         }
5209 
5210         // if wback then R[n] = offset_addr;
5211         if (wback)
5212         {
5213             context.type = eContextAdjustBaseRegister;
5214             context.SetAddress (offset_addr);
5215             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5216                 return false;
5217         }
5218     }
5219 
5220     return true;
5221 }
5222 
5223 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value,
5224 // and writes the result to the destination register.  It can optionally update the condition flags
5225 // based on the result.
5226 bool
5227 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding)
5228 {
5229 #if 0
5230     // ARM pseudo code...
5231     if ConditionPassed() then
5232         EncodingSpecificOperations();
5233         (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5234         if d == 15 then         // Can only occur for ARM encoding
5235             ALUWritePC(result); // setflags is always FALSE here
5236         else
5237             R[d] = result;
5238             if setflags then
5239                 APSR.N = result<31>;
5240                 APSR.Z = IsZeroBit(result);
5241                 APSR.C = carry;
5242                 APSR.V = overflow;
5243 #endif
5244 
5245     bool success = false;
5246 
5247     if (ConditionPassed(opcode))
5248     {
5249         uint32_t Rd, Rn;
5250         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
5251         bool setflags;
5252         switch (encoding)
5253         {
5254         case eEncodingT1:
5255             Rd = Bits32(opcode, 11, 8);
5256             Rn = Bits32(opcode, 19, 16);
5257             setflags = BitIsSet(opcode, 20);
5258             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5259             if (BadReg(Rd) || BadReg(Rn))
5260                 return false;
5261             break;
5262         case eEncodingA1:
5263             Rd = Bits32(opcode, 15, 12);
5264             Rn = Bits32(opcode, 19, 16);
5265             setflags = BitIsSet(opcode, 20);
5266             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5267 
5268             if (Rd == 15 && setflags)
5269                 return EmulateSUBSPcLrEtc (opcode, encoding);
5270             break;
5271         default:
5272             return false;
5273         }
5274 
5275         // Read the first operand.
5276         int32_t val1 = ReadCoreReg(Rn, &success);
5277         if (!success)
5278             return false;
5279 
5280         AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5281 
5282         EmulateInstruction::Context context;
5283         context.type = EmulateInstruction::eContextImmediate;
5284         context.SetNoArgs ();
5285 
5286         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5287             return false;
5288     }
5289     return true;
5290 }
5291 
5292 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted
5293 // register value, and writes the result to the destination register.  It can optionally update the
5294 // condition flags based on the result.
5295 bool
5296 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding)
5297 {
5298 #if 0
5299     // ARM pseudo code...
5300     if ConditionPassed() then
5301         EncodingSpecificOperations();
5302         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5303         (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5304         if d == 15 then         // Can only occur for ARM encoding
5305             ALUWritePC(result); // setflags is always FALSE here
5306         else
5307             R[d] = result;
5308             if setflags then
5309                 APSR.N = result<31>;
5310                 APSR.Z = IsZeroBit(result);
5311                 APSR.C = carry;
5312                 APSR.V = overflow;
5313 #endif
5314 
5315     bool success = false;
5316 
5317     if (ConditionPassed(opcode))
5318     {
5319         uint32_t Rd, Rn, Rm;
5320         ARM_ShifterType shift_t;
5321         uint32_t shift_n; // the shift applied to the value read from Rm
5322         bool setflags;
5323         switch (encoding)
5324         {
5325         case eEncodingT1:
5326             Rd = Rn = Bits32(opcode, 2, 0);
5327             Rm = Bits32(opcode, 5, 3);
5328             setflags = !InITBlock();
5329             shift_t = SRType_LSL;
5330             shift_n = 0;
5331             break;
5332         case eEncodingT2:
5333             Rd = Bits32(opcode, 11, 8);
5334             Rn = Bits32(opcode, 19, 16);
5335             Rm = Bits32(opcode, 3, 0);
5336             setflags = BitIsSet(opcode, 20);
5337             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5338             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5339                 return false;
5340             break;
5341         case eEncodingA1:
5342             Rd = Bits32(opcode, 15, 12);
5343             Rn = Bits32(opcode, 19, 16);
5344             Rm = Bits32(opcode, 3, 0);
5345             setflags = BitIsSet(opcode, 20);
5346             shift_n = DecodeImmShiftARM(opcode, shift_t);
5347 
5348             if (Rd == 15 && setflags)
5349                 return EmulateSUBSPcLrEtc (opcode, encoding);
5350             break;
5351         default:
5352             return false;
5353         }
5354 
5355         // Read the first operand.
5356         int32_t val1 = ReadCoreReg(Rn, &success);
5357         if (!success)
5358             return false;
5359 
5360         // Read the second operand.
5361         int32_t val2 = ReadCoreReg(Rm, &success);
5362         if (!success)
5363             return false;
5364 
5365         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5366         if (!success)
5367             return false;
5368         AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5369 
5370         EmulateInstruction::Context context;
5371         context.type = EmulateInstruction::eContextImmediate;
5372         context.SetNoArgs ();
5373 
5374         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5375             return false;
5376     }
5377     return true;
5378 }
5379 
5380 // This instruction adds an immediate value to the PC value to form a PC-relative address,
5381 // and writes the result to the destination register.
5382 bool
5383 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding)
5384 {
5385 #if 0
5386     // ARM pseudo code...
5387     if ConditionPassed() then
5388         EncodingSpecificOperations();
5389         result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5390         if d == 15 then         // Can only occur for ARM encodings
5391             ALUWritePC(result);
5392         else
5393             R[d] = result;
5394 #endif
5395 
5396     bool success = false;
5397 
5398     if (ConditionPassed(opcode))
5399     {
5400         uint32_t Rd;
5401         uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5402         bool add;
5403         switch (encoding)
5404         {
5405         case eEncodingT1:
5406             Rd = Bits32(opcode, 10, 8);
5407             imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5408             add = true;
5409             break;
5410         case eEncodingT2:
5411         case eEncodingT3:
5412             Rd = Bits32(opcode, 11, 8);
5413             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5414             add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5415             if (BadReg(Rd))
5416                 return false;
5417             break;
5418         case eEncodingA1:
5419         case eEncodingA2:
5420             Rd = Bits32(opcode, 15, 12);
5421             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5422             add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5423             break;
5424         default:
5425             return false;
5426         }
5427 
5428         // Read the PC value.
5429         uint32_t pc = ReadCoreReg(PC_REG, &success);
5430         if (!success)
5431             return false;
5432 
5433         uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5434 
5435         EmulateInstruction::Context context;
5436         context.type = EmulateInstruction::eContextImmediate;
5437         context.SetNoArgs ();
5438 
5439         if (!WriteCoreReg(context, result, Rd))
5440             return false;
5441     }
5442     return true;
5443 }
5444 
5445 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result
5446 // to the destination register.  It can optionally update the condition flags based on the result.
5447 bool
5448 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding)
5449 {
5450 #if 0
5451     // ARM pseudo code...
5452     if ConditionPassed() then
5453         EncodingSpecificOperations();
5454         result = R[n] AND imm32;
5455         if d == 15 then         // Can only occur for ARM encoding
5456             ALUWritePC(result); // setflags is always FALSE here
5457         else
5458             R[d] = result;
5459             if setflags then
5460                 APSR.N = result<31>;
5461                 APSR.Z = IsZeroBit(result);
5462                 APSR.C = carry;
5463                 // APSR.V unchanged
5464 #endif
5465 
5466     bool success = false;
5467 
5468     if (ConditionPassed(opcode))
5469     {
5470         uint32_t Rd, Rn;
5471         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
5472         bool setflags;
5473         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5474         switch (encoding)
5475         {
5476         case eEncodingT1:
5477             Rd = Bits32(opcode, 11, 8);
5478             Rn = Bits32(opcode, 19, 16);
5479             setflags = BitIsSet(opcode, 20);
5480             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5481             // if Rd == '1111' && S == '1' then SEE TST (immediate);
5482             if (Rd == 15 && setflags)
5483                 return EmulateTSTImm(opcode, eEncodingT1);
5484             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
5485                 return false;
5486             break;
5487         case eEncodingA1:
5488             Rd = Bits32(opcode, 15, 12);
5489             Rn = Bits32(opcode, 19, 16);
5490             setflags = BitIsSet(opcode, 20);
5491             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5492 
5493             if (Rd == 15 && setflags)
5494                 return EmulateSUBSPcLrEtc (opcode, encoding);
5495             break;
5496         default:
5497             return false;
5498         }
5499 
5500         // Read the first operand.
5501         uint32_t val1 = ReadCoreReg(Rn, &success);
5502         if (!success)
5503             return false;
5504 
5505         uint32_t result = val1 & imm32;
5506 
5507         EmulateInstruction::Context context;
5508         context.type = EmulateInstruction::eContextImmediate;
5509         context.SetNoArgs ();
5510 
5511         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5512             return false;
5513     }
5514     return true;
5515 }
5516 
5517 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value,
5518 // and writes the result to the destination register.  It can optionally update the condition flags
5519 // based on the result.
5520 bool
5521 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding)
5522 {
5523 #if 0
5524     // ARM pseudo code...
5525     if ConditionPassed() then
5526         EncodingSpecificOperations();
5527         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5528         result = R[n] AND shifted;
5529         if d == 15 then         // Can only occur for ARM encoding
5530             ALUWritePC(result); // setflags is always FALSE here
5531         else
5532             R[d] = result;
5533             if setflags then
5534                 APSR.N = result<31>;
5535                 APSR.Z = IsZeroBit(result);
5536                 APSR.C = carry;
5537                 // APSR.V unchanged
5538 #endif
5539 
5540     bool success = false;
5541 
5542     if (ConditionPassed(opcode))
5543     {
5544         uint32_t Rd, Rn, Rm;
5545         ARM_ShifterType shift_t;
5546         uint32_t shift_n; // the shift applied to the value read from Rm
5547         bool setflags;
5548         uint32_t carry;
5549         switch (encoding)
5550         {
5551         case eEncodingT1:
5552             Rd = Rn = Bits32(opcode, 2, 0);
5553             Rm = Bits32(opcode, 5, 3);
5554             setflags = !InITBlock();
5555             shift_t = SRType_LSL;
5556             shift_n = 0;
5557             break;
5558         case eEncodingT2:
5559             Rd = Bits32(opcode, 11, 8);
5560             Rn = Bits32(opcode, 19, 16);
5561             Rm = Bits32(opcode, 3, 0);
5562             setflags = BitIsSet(opcode, 20);
5563             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5564             // if Rd == '1111' && S == '1' then SEE TST (register);
5565             if (Rd == 15 && setflags)
5566                 return EmulateTSTReg(opcode, eEncodingT2);
5567             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
5568                 return false;
5569             break;
5570         case eEncodingA1:
5571             Rd = Bits32(opcode, 15, 12);
5572             Rn = Bits32(opcode, 19, 16);
5573             Rm = Bits32(opcode, 3, 0);
5574             setflags = BitIsSet(opcode, 20);
5575             shift_n = DecodeImmShiftARM(opcode, shift_t);
5576 
5577             if (Rd == 15 && setflags)
5578                 return EmulateSUBSPcLrEtc (opcode, encoding);
5579             break;
5580         default:
5581             return false;
5582         }
5583 
5584         // Read the first operand.
5585         uint32_t val1 = ReadCoreReg(Rn, &success);
5586         if (!success)
5587             return false;
5588 
5589         // Read the second operand.
5590         uint32_t val2 = ReadCoreReg(Rm, &success);
5591         if (!success)
5592             return false;
5593 
5594         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5595         if (!success)
5596             return false;
5597         uint32_t result = val1 & shifted;
5598 
5599         EmulateInstruction::Context context;
5600         context.type = EmulateInstruction::eContextImmediate;
5601         context.SetNoArgs ();
5602 
5603         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5604             return false;
5605     }
5606     return true;
5607 }
5608 
5609 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an
5610 // immediate value, and writes the result to the destination register.  It can optionally update the
5611 // condition flags based on the result.
5612 bool
5613 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding)
5614 {
5615 #if 0
5616     // ARM pseudo code...
5617     if ConditionPassed() then
5618         EncodingSpecificOperations();
5619         result = R[n] AND NOT(imm32);
5620         if d == 15 then         // Can only occur for ARM encoding
5621             ALUWritePC(result); // setflags is always FALSE here
5622         else
5623             R[d] = result;
5624             if setflags then
5625                 APSR.N = result<31>;
5626                 APSR.Z = IsZeroBit(result);
5627                 APSR.C = carry;
5628                 // APSR.V unchanged
5629 #endif
5630 
5631     bool success = false;
5632 
5633     if (ConditionPassed(opcode))
5634     {
5635         uint32_t Rd, Rn;
5636         uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn
5637         bool setflags;
5638         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5639         switch (encoding)
5640         {
5641         case eEncodingT1:
5642             Rd = Bits32(opcode, 11, 8);
5643             Rn = Bits32(opcode, 19, 16);
5644             setflags = BitIsSet(opcode, 20);
5645             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5646             if (BadReg(Rd) || BadReg(Rn))
5647                 return false;
5648             break;
5649         case eEncodingA1:
5650             Rd = Bits32(opcode, 15, 12);
5651             Rn = Bits32(opcode, 19, 16);
5652             setflags = BitIsSet(opcode, 20);
5653             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5654 
5655             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5656             if (Rd == 15 && setflags)
5657                 return EmulateSUBSPcLrEtc (opcode, encoding);
5658             break;
5659         default:
5660             return false;
5661         }
5662 
5663         // Read the first operand.
5664         uint32_t val1 = ReadCoreReg(Rn, &success);
5665         if (!success)
5666             return false;
5667 
5668         uint32_t result = val1 & ~imm32;
5669 
5670         EmulateInstruction::Context context;
5671         context.type = EmulateInstruction::eContextImmediate;
5672         context.SetNoArgs ();
5673 
5674         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5675             return false;
5676     }
5677     return true;
5678 }
5679 
5680 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an
5681 // optionally-shifted register value, and writes the result to the destination register.
5682 // It can optionally update the condition flags based on the result.
5683 bool
5684 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding)
5685 {
5686 #if 0
5687     // ARM pseudo code...
5688     if ConditionPassed() then
5689         EncodingSpecificOperations();
5690         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5691         result = R[n] AND NOT(shifted);
5692         if d == 15 then         // Can only occur for ARM encoding
5693             ALUWritePC(result); // setflags is always FALSE here
5694         else
5695             R[d] = result;
5696             if setflags then
5697                 APSR.N = result<31>;
5698                 APSR.Z = IsZeroBit(result);
5699                 APSR.C = carry;
5700                 // APSR.V unchanged
5701 #endif
5702 
5703     bool success = false;
5704 
5705     if (ConditionPassed(opcode))
5706     {
5707         uint32_t Rd, Rn, Rm;
5708         ARM_ShifterType shift_t;
5709         uint32_t shift_n; // the shift applied to the value read from Rm
5710         bool setflags;
5711         uint32_t carry;
5712         switch (encoding)
5713         {
5714         case eEncodingT1:
5715             Rd = Rn = Bits32(opcode, 2, 0);
5716             Rm = Bits32(opcode, 5, 3);
5717             setflags = !InITBlock();
5718             shift_t = SRType_LSL;
5719             shift_n = 0;
5720             break;
5721         case eEncodingT2:
5722             Rd = Bits32(opcode, 11, 8);
5723             Rn = Bits32(opcode, 19, 16);
5724             Rm = Bits32(opcode, 3, 0);
5725             setflags = BitIsSet(opcode, 20);
5726             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5727             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5728                 return false;
5729             break;
5730         case eEncodingA1:
5731             Rd = Bits32(opcode, 15, 12);
5732             Rn = Bits32(opcode, 19, 16);
5733             Rm = Bits32(opcode, 3, 0);
5734             setflags = BitIsSet(opcode, 20);
5735             shift_n = DecodeImmShiftARM(opcode, shift_t);
5736 
5737             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5738             if (Rd == 15 && setflags)
5739                 return EmulateSUBSPcLrEtc (opcode, encoding);
5740             break;
5741         default:
5742             return false;
5743         }
5744 
5745         // Read the first operand.
5746         uint32_t val1 = ReadCoreReg(Rn, &success);
5747         if (!success)
5748             return false;
5749 
5750         // Read the second operand.
5751         uint32_t val2 = ReadCoreReg(Rm, &success);
5752         if (!success)
5753             return false;
5754 
5755         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5756         if (!success)
5757             return false;
5758         uint32_t result = val1 & ~shifted;
5759 
5760         EmulateInstruction::Context context;
5761         context.type = EmulateInstruction::eContextImmediate;
5762         context.SetNoArgs ();
5763 
5764         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5765             return false;
5766     }
5767     return true;
5768 }
5769 
5770 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
5771 // from memory, and writes it to a register.  It can use offset, post-indexed, or pre-indexed addressing.
5772 bool
5773 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding)
5774 {
5775 #if 0
5776     if ConditionPassed() then
5777         EncodingSpecificOperations();
5778         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5779         address = if index then offset_addr else R[n];
5780         data = MemU[address,4];
5781         if wback then R[n] = offset_addr;
5782         if t == 15 then
5783             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5784         elsif UnalignedSupport() || address<1:0> = '00' then
5785             R[t] = data;
5786         else // Can only apply before ARMv7
5787             R[t] = ROR(data, 8*UInt(address<1:0>));
5788 #endif
5789 
5790     bool success = false;
5791 
5792     if (ConditionPassed(opcode))
5793     {
5794         const uint32_t addr_byte_size = GetAddressByteSize();
5795 
5796         uint32_t t;
5797         uint32_t n;
5798         uint32_t imm32;
5799         bool index;
5800         bool add;
5801         bool wback;
5802 
5803         switch (encoding)
5804         {
5805             case eEncodingA1:
5806                 // if Rn == '1111' then SEE LDR (literal);
5807                 // if P == '0' && W == '1' then SEE LDRT;
5808                 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP;
5809                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5810                 t = Bits32 (opcode, 15, 12);
5811                 n = Bits32 (opcode, 19, 16);
5812                 imm32 = Bits32 (opcode, 11, 0);
5813 
5814                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5815                 index = BitIsSet (opcode, 24);
5816                 add = BitIsSet (opcode, 23);
5817                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5818 
5819                 // if wback && n == t then UNPREDICTABLE;
5820                 if (wback && (n == t))
5821                     return false;
5822 
5823                 break;
5824 
5825             default:
5826                 return false;
5827         }
5828 
5829         addr_t address;
5830         addr_t offset_addr;
5831         addr_t base_address = ReadCoreReg (n, &success);
5832         if (!success)
5833             return false;
5834 
5835         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5836         if (add)
5837             offset_addr = base_address + imm32;
5838         else
5839             offset_addr = base_address - imm32;
5840 
5841         // address = if index then offset_addr else R[n];
5842         if (index)
5843             address = offset_addr;
5844         else
5845             address = base_address;
5846 
5847         // data = MemU[address,4];
5848 
5849         RegisterInfo base_reg;
5850         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5851 
5852         EmulateInstruction::Context context;
5853         context.type = eContextRegisterLoad;
5854         context.SetRegisterPlusOffset (base_reg, address - base_address);
5855 
5856         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5857         if (!success)
5858             return false;
5859 
5860         // if wback then R[n] = offset_addr;
5861         if (wback)
5862         {
5863             context.type = eContextAdjustBaseRegister;
5864             context.SetAddress (offset_addr);
5865             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5866                 return false;
5867         }
5868 
5869         // if t == 15 then
5870         if (t == 15)
5871         {
5872             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5873             if (BitIsClear (address, 1) && BitIsClear (address, 0))
5874             {
5875                 // LoadWritePC (data);
5876                 context.type = eContextRegisterLoad;
5877                 context.SetRegisterPlusOffset (base_reg, address - base_address);
5878                 LoadWritePC (context, data);
5879             }
5880             else
5881                   return false;
5882         }
5883         // elsif UnalignedSupport() || address<1:0> = '00' then
5884         else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5885         {
5886             // R[t] = data;
5887             context.type = eContextRegisterLoad;
5888             context.SetRegisterPlusOffset (base_reg, address - base_address);
5889             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5890                 return false;
5891         }
5892         // else // Can only apply before ARMv7
5893         else
5894         {
5895             // R[t] = ROR(data, 8*UInt(address<1:0>));
5896             data = ROR (data, Bits32 (address, 1, 0), &success);
5897             if (!success)
5898                 return false;
5899             context.type = eContextRegisterLoad;
5900             context.SetImmediate (data);
5901             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5902                 return false;
5903         }
5904 
5905     }
5906     return true;
5907 }
5908 
5909 // LDR (register) calculates an address from a base register value and an offset register value, loads a word
5910 // from memory, and writes it to a resgister.  The offset register value can optionally be shifted.
5911 bool
5912 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding)
5913 {
5914 #if 0
5915     if ConditionPassed() then
5916         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5917         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5918         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5919         address = if index then offset_addr else R[n];
5920         data = MemU[address,4];
5921         if wback then R[n] = offset_addr;
5922         if t == 15 then
5923             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5924         elsif UnalignedSupport() || address<1:0> = '00' then
5925             R[t] = data;
5926         else // Can only apply before ARMv7
5927             if CurrentInstrSet() == InstrSet_ARM then
5928                 R[t] = ROR(data, 8*UInt(address<1:0>));
5929             else
5930                 R[t] = bits(32) UNKNOWN;
5931 #endif
5932 
5933     bool success = false;
5934 
5935     if (ConditionPassed(opcode))
5936     {
5937         const uint32_t addr_byte_size = GetAddressByteSize();
5938 
5939         uint32_t t;
5940         uint32_t n;
5941         uint32_t m;
5942         bool index;
5943         bool add;
5944         bool wback;
5945         ARM_ShifterType shift_t;
5946         uint32_t shift_n;
5947 
5948         switch (encoding)
5949         {
5950             case eEncodingT1:
5951                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5952                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5953                 t = Bits32 (opcode, 2, 0);
5954                 n = Bits32 (opcode, 5, 3);
5955                 m = Bits32 (opcode, 8, 6);
5956 
5957                 // index = TRUE; add = TRUE; wback = FALSE;
5958                 index = true;
5959                 add = true;
5960                 wback = false;
5961 
5962                 // (shift_t, shift_n) = (SRType_LSL, 0);
5963                 shift_t = SRType_LSL;
5964                 shift_n = 0;
5965 
5966                 break;
5967 
5968             case eEncodingT2:
5969                 // if Rn == '1111' then SEE LDR (literal);
5970                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5971                 t = Bits32 (opcode, 15, 12);
5972                 n = Bits32 (opcode, 19, 16);
5973                 m = Bits32 (opcode, 3, 0);
5974 
5975                 // index = TRUE; add = TRUE; wback = FALSE;
5976                 index = true;
5977                 add = true;
5978                 wback = false;
5979 
5980                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5981                 shift_t = SRType_LSL;
5982                 shift_n = Bits32 (opcode, 5, 4);
5983 
5984                 // if BadReg(m) then UNPREDICTABLE;
5985                 if (BadReg (m))
5986                     return false;
5987 
5988                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
5989                 if ((t == 15) && InITBlock() && !LastInITBlock())
5990                     return false;
5991 
5992                 break;
5993 
5994             case eEncodingA1:
5995             {
5996                 // if P == '0' && W == '1' then SEE LDRT;
5997                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5998                 t = Bits32 (opcode, 15, 12);
5999                 n = Bits32 (opcode, 19, 16);
6000                 m = Bits32 (opcode, 3, 0);
6001 
6002                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6003                 index = BitIsSet (opcode, 24);
6004                 add = BitIsSet (opcode, 23);
6005                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6006 
6007                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6008                 uint32_t type = Bits32 (opcode, 6, 5);
6009                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6010                 shift_n = DecodeImmShift (type, imm5, shift_t);
6011 
6012                 // if m == 15 then UNPREDICTABLE;
6013                 if (m == 15)
6014                     return false;
6015 
6016                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6017                 if (wback && ((n == 15) || (n == t)))
6018                     return false;
6019             }
6020                 break;
6021 
6022 
6023             default:
6024                 return false;
6025         }
6026 
6027         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6028         if (!success)
6029             return false;
6030 
6031         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6032         if (!success)
6033             return false;
6034 
6035         addr_t offset_addr;
6036         addr_t address;
6037 
6038         // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an application level alias for the CPSR".
6039         addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success);
6040         if (!success)
6041             return false;
6042 
6043         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6044         if (add)
6045             offset_addr = Rn + offset;
6046         else
6047             offset_addr = Rn - offset;
6048 
6049         // address = if index then offset_addr else R[n];
6050             if (index)
6051                 address = offset_addr;
6052             else
6053                 address = Rn;
6054 
6055         // data = MemU[address,4];
6056         RegisterInfo base_reg;
6057         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6058 
6059         EmulateInstruction::Context context;
6060         context.type = eContextRegisterLoad;
6061         context.SetRegisterPlusOffset (base_reg, address - Rn);
6062 
6063         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
6064         if (!success)
6065             return false;
6066 
6067         // if wback then R[n] = offset_addr;
6068         if (wback)
6069         {
6070             context.type = eContextAdjustBaseRegister;
6071             context.SetAddress (offset_addr);
6072             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6073                 return false;
6074         }
6075 
6076         // if t == 15 then
6077         if (t == 15)
6078         {
6079             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6080             if (BitIsClear (address, 1) && BitIsClear (address, 0))
6081             {
6082                 context.type = eContextRegisterLoad;
6083                 context.SetRegisterPlusOffset (base_reg, address - Rn);
6084                 LoadWritePC (context, data);
6085             }
6086             else
6087                 return false;
6088         }
6089         // elsif UnalignedSupport() || address<1:0> = '00' then
6090         else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
6091         {
6092             // R[t] = data;
6093             context.type = eContextRegisterLoad;
6094             context.SetRegisterPlusOffset (base_reg, address - Rn);
6095             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6096                 return false;
6097         }
6098         else // Can only apply before ARMv7
6099         {
6100             // if CurrentInstrSet() == InstrSet_ARM then
6101             if (CurrentInstrSet () == eModeARM)
6102             {
6103                 // R[t] = ROR(data, 8*UInt(address<1:0>));
6104                 data = ROR (data, Bits32 (address, 1, 0), &success);
6105                 if (!success)
6106                     return false;
6107                 context.type = eContextRegisterLoad;
6108                 context.SetImmediate (data);
6109                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6110                     return false;
6111             }
6112             else
6113             {
6114                 // R[t] = bits(32) UNKNOWN;
6115                 WriteBits32Unknown (t);
6116             }
6117         }
6118     }
6119     return true;
6120 }
6121 
6122 // LDRB (immediate, Thumb)
6123 bool
6124 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6125 {
6126 #if 0
6127     if ConditionPassed() then
6128         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6129         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6130         address = if index then offset_addr else R[n];
6131         R[t] = ZeroExtend(MemU[address,1], 32);
6132         if wback then R[n] = offset_addr;
6133 #endif
6134 
6135     bool success = false;
6136 
6137     if (ConditionPassed(opcode))
6138     {
6139         uint32_t t;
6140         uint32_t n;
6141         uint32_t imm32;
6142         bool index;
6143         bool add;
6144         bool wback;
6145 
6146         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6147         switch (encoding)
6148         {
6149             case eEncodingT1:
6150                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6151                 t = Bits32 (opcode, 2, 0);
6152                 n = Bits32 (opcode, 5, 3);
6153                 imm32 = Bits32 (opcode, 10, 6);
6154 
6155                 // index = TRUE; add = TRUE; wback = FALSE;
6156                 index = true;
6157                 add = true;
6158                 wback= false;
6159 
6160                 break;
6161 
6162             case eEncodingT2:
6163                 // if Rt == '1111' then SEE PLD;
6164                 // if Rn == '1111' then SEE LDRB (literal);
6165                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6166                 t = Bits32 (opcode, 15, 12);
6167                 n = Bits32 (opcode, 19, 16);
6168                 imm32 = Bits32 (opcode, 11, 0);
6169 
6170                 // index = TRUE; add = TRUE; wback = FALSE;
6171                 index = true;
6172                 add = true;
6173                 wback = false;
6174 
6175                 // if t == 13 then UNPREDICTABLE;
6176                 if (t == 13)
6177                     return false;
6178 
6179                 break;
6180 
6181             case eEncodingT3:
6182                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6183                 // if Rn == '1111' then SEE LDRB (literal);
6184                 // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6185                 // if P == '0' && W == '0' then UNDEFINED;
6186                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6187                     return false;
6188 
6189                   // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6190                 t = Bits32 (opcode, 15, 12);
6191                 n = Bits32 (opcode, 19, 16);
6192                 imm32 = Bits32 (opcode, 7, 0);
6193 
6194                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6195                 index = BitIsSet (opcode, 10);
6196                 add = BitIsSet (opcode, 9);
6197                 wback = BitIsSet (opcode, 8);
6198 
6199                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6200                 if (BadReg (t) || (wback && (n == t)))
6201                     return false;
6202 
6203                 break;
6204 
6205             default:
6206                 return false;
6207         }
6208 
6209         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6210         if (!success)
6211             return false;
6212 
6213         addr_t address;
6214         addr_t offset_addr;
6215 
6216         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6217         if (add)
6218             offset_addr = Rn + imm32;
6219         else
6220             offset_addr = Rn - imm32;
6221 
6222         // address = if index then offset_addr else R[n];
6223         if (index)
6224             address = offset_addr;
6225         else
6226             address = Rn;
6227 
6228         // R[t] = ZeroExtend(MemU[address,1], 32);
6229         RegisterInfo base_reg;
6230         RegisterInfo data_reg;
6231         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6232         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6233 
6234         EmulateInstruction::Context context;
6235         context.type = eContextRegisterLoad;
6236         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
6237 
6238         uint64_t data = MemURead (context, address, 1, 0, &success);
6239         if (!success)
6240             return false;
6241 
6242         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6243             return false;
6244 
6245         // if wback then R[n] = offset_addr;
6246         if (wback)
6247         {
6248             context.type = eContextAdjustBaseRegister;
6249             context.SetAddress (offset_addr);
6250             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6251                 return false;
6252         }
6253     }
6254     return true;
6255 }
6256 
6257 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6258 // zero-extends it to form a 32-bit word and writes it to a register.
6259 bool
6260 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6261 {
6262 #if 0
6263     if ConditionPassed() then
6264         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6265         base = Align(PC,4);
6266         address = if add then (base + imm32) else (base - imm32);
6267         R[t] = ZeroExtend(MemU[address,1], 32);
6268 #endif
6269 
6270     bool success = false;
6271 
6272     if (ConditionPassed(opcode))
6273     {
6274         uint32_t t;
6275         uint32_t imm32;
6276         bool add;
6277         switch (encoding)
6278         {
6279             case eEncodingT1:
6280                 // if Rt == '1111' then SEE PLD;
6281                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6282                 t = Bits32 (opcode, 15, 12);
6283                 imm32 = Bits32 (opcode, 11, 0);
6284                 add = BitIsSet (opcode, 23);
6285 
6286                 // if t == 13 then UNPREDICTABLE;
6287                 if (t == 13)
6288                     return false;
6289 
6290                 break;
6291 
6292             case eEncodingA1:
6293                 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6294                 t = Bits32 (opcode, 15, 12);
6295                 imm32 = Bits32 (opcode, 11, 0);
6296                 add = BitIsSet (opcode, 23);
6297 
6298                 // if t == 15 then UNPREDICTABLE;
6299                 if (t == 15)
6300                     return false;
6301                 break;
6302 
6303             default:
6304                 return false;
6305         }
6306 
6307         // base = Align(PC,4);
6308         uint32_t pc_val = ReadCoreReg (PC_REG, &success);
6309         if (!success)
6310             return false;
6311 
6312         uint32_t base = AlignPC (pc_val);
6313 
6314         addr_t address;
6315         // address = if add then (base + imm32) else (base - imm32);
6316         if (add)
6317             address = base + imm32;
6318         else
6319             address = base - imm32;
6320 
6321         // R[t] = ZeroExtend(MemU[address,1], 32);
6322         EmulateInstruction::Context context;
6323         context.type = eContextRelativeBranchImmediate;
6324         context.SetImmediate (address - base);
6325 
6326         uint64_t data = MemURead (context, address, 1, 0, &success);
6327         if (!success)
6328             return false;
6329 
6330         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6331             return false;
6332     }
6333     return true;
6334 }
6335 
6336 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from
6337 // memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6338 // optionally be shifted.
6339 bool
6340 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding)
6341 {
6342 #if 0
6343     if ConditionPassed() then
6344         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6345         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6346         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6347         address = if index then offset_addr else R[n];
6348         R[t] = ZeroExtend(MemU[address,1],32);
6349         if wback then R[n] = offset_addr;
6350 #endif
6351 
6352     bool success = false;
6353 
6354     if (ConditionPassed(opcode))
6355     {
6356         uint32_t t;
6357         uint32_t n;
6358         uint32_t m;
6359         bool index;
6360         bool add;
6361         bool wback;
6362         ARM_ShifterType shift_t;
6363         uint32_t shift_n;
6364 
6365         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6366         switch (encoding)
6367         {
6368             case eEncodingT1:
6369                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6370                 t = Bits32 (opcode, 2, 0);
6371                 n = Bits32 (opcode, 5, 3);
6372                 m = Bits32 (opcode, 8, 6);
6373 
6374                 // index = TRUE; add = TRUE; wback = FALSE;
6375                 index = true;
6376                 add = true;
6377                 wback = false;
6378 
6379                 // (shift_t, shift_n) = (SRType_LSL, 0);
6380                 shift_t = SRType_LSL;
6381                 shift_n = 0;
6382                 break;
6383 
6384             case eEncodingT2:
6385                 // if Rt == '1111' then SEE PLD;
6386                 // if Rn == '1111' then SEE LDRB (literal);
6387                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6388                 t = Bits32 (opcode, 15, 12);
6389                 n = Bits32 (opcode, 19, 16);
6390                 m = Bits32 (opcode, 3, 0);
6391 
6392                 // index = TRUE; add = TRUE; wback = FALSE;
6393                 index = true;
6394                 add = true;
6395                 wback = false;
6396 
6397                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6398                 shift_t = SRType_LSL;
6399                 shift_n = Bits32 (opcode, 5, 4);
6400 
6401                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6402                 if ((t == 13) || BadReg (m))
6403                     return false;
6404                 break;
6405 
6406             case eEncodingA1:
6407             {
6408                 // if P == '0' && W == '1' then SEE LDRBT;
6409                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6410                 t = Bits32 (opcode, 15, 12);
6411                 n = Bits32 (opcode, 19, 16);
6412                 m = Bits32 (opcode, 3, 0);
6413 
6414                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6415                 index = BitIsSet (opcode, 24);
6416                 add = BitIsSet (opcode, 23);
6417                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6418 
6419                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6420                 uint32_t type = Bits32 (opcode, 6, 5);
6421                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6422                 shift_n = DecodeImmShift (type, imm5, shift_t);
6423 
6424                 // if t == 15 || m == 15 then UNPREDICTABLE;
6425                 if ((t == 15) || (m == 15))
6426                     return false;
6427 
6428                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6429                 if (wback && ((n == 15) || (n == t)))
6430                     return false;
6431             }
6432                 break;
6433 
6434             default:
6435                 return false;
6436         }
6437 
6438         addr_t offset_addr;
6439         addr_t address;
6440 
6441         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6442         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6443         if (!success)
6444             return false;
6445 
6446         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6447         if (!success)
6448             return false;
6449 
6450         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6451         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6452         if (!success)
6453             return false;
6454 
6455         if (add)
6456             offset_addr = Rn + offset;
6457         else
6458             offset_addr = Rn - offset;
6459 
6460         // address = if index then offset_addr else R[n];
6461         if (index)
6462             address = offset_addr;
6463         else
6464             address = Rn;
6465 
6466         // R[t] = ZeroExtend(MemU[address,1],32);
6467         RegisterInfo base_reg;
6468         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6469 
6470         EmulateInstruction::Context context;
6471         context.type = eContextRegisterLoad;
6472         context.SetRegisterPlusOffset (base_reg, address - Rn);
6473 
6474         uint64_t data = MemURead (context, address, 1, 0, &success);
6475         if (!success)
6476             return false;
6477 
6478         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6479             return false;
6480 
6481         // if wback then R[n] = offset_addr;
6482         if (wback)
6483         {
6484             context.type = eContextAdjustBaseRegister;
6485             context.SetAddress (offset_addr);
6486             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6487                 return false;
6488         }
6489     }
6490     return true;
6491 }
6492 
6493 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a
6494 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register.  It can use offset,
6495 // post-indexed, or pre-indexed addressing.
6496 bool
6497 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding)
6498 {
6499 #if 0
6500     if ConditionPassed() then
6501         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6502         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6503         address = if index then offset_addr else R[n];
6504         data = MemU[address,2];
6505         if wback then R[n] = offset_addr;
6506         if UnalignedSupport() || address<0> = '0' then
6507             R[t] = ZeroExtend(data, 32);
6508         else // Can only apply before ARMv7
6509             R[t] = bits(32) UNKNOWN;
6510 #endif
6511 
6512 
6513     bool success = false;
6514 
6515     if (ConditionPassed(opcode))
6516     {
6517         uint32_t t;
6518         uint32_t n;
6519         uint32_t imm32;
6520         bool index;
6521         bool add;
6522         bool wback;
6523 
6524         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6525         switch (encoding)
6526         {
6527             case eEncodingT1:
6528                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
6529                 t = Bits32 (opcode, 2, 0);
6530                 n = Bits32 (opcode, 5, 3);
6531                 imm32 = Bits32 (opcode, 10, 6) << 1;
6532 
6533                 // index = TRUE; add = TRUE; wback = FALSE;
6534                 index = true;
6535                 add = true;
6536                 wback = false;
6537 
6538                 break;
6539 
6540             case eEncodingT2:
6541                 // if Rt == '1111' then SEE "Unallocated memory hints";
6542                 // if Rn == '1111' then SEE LDRH (literal);
6543                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6544                 t = Bits32 (opcode, 15, 12);
6545                 n = Bits32 (opcode, 19, 16);
6546                 imm32 = Bits32 (opcode, 11, 0);
6547 
6548                 // index = TRUE; add = TRUE; wback = FALSE;
6549                 index = true;
6550                 add = true;
6551                 wback = false;
6552 
6553                 // if t == 13 then UNPREDICTABLE;
6554                 if (t == 13)
6555                     return false;
6556                 break;
6557 
6558             case eEncodingT3:
6559                 // if Rn == '1111' then SEE LDRH (literal);
6560                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
6561                 // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
6562                 // if P == '0' && W == '0' then UNDEFINED;
6563                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6564                     return false;
6565 
6566                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6567                 t = Bits32 (opcode, 15, 12);
6568                 n = Bits32 (opcode, 19, 16);
6569                 imm32 = Bits32 (opcode, 7, 0);
6570 
6571                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6572                 index = BitIsSet (opcode, 10);
6573                 add = BitIsSet (opcode, 9);
6574                 wback = BitIsSet (opcode, 8);
6575 
6576                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6577                 if (BadReg (t) || (wback && (n == t)))
6578                     return false;
6579                 break;
6580 
6581             default:
6582                 return false;
6583         }
6584 
6585         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6586         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6587         if (!success)
6588             return false;
6589 
6590         addr_t offset_addr;
6591         addr_t address;
6592 
6593         if (add)
6594             offset_addr = Rn + imm32;
6595         else
6596             offset_addr = Rn - imm32;
6597 
6598         // address = if index then offset_addr else R[n];
6599         if (index)
6600             address = offset_addr;
6601         else
6602             address = Rn;
6603 
6604         // data = MemU[address,2];
6605         RegisterInfo base_reg;
6606         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6607 
6608         EmulateInstruction::Context context;
6609         context.type = eContextRegisterLoad;
6610         context.SetRegisterPlusOffset (base_reg, address - Rn);
6611 
6612         uint64_t data = MemURead (context, address, 2, 0, &success);
6613         if (!success)
6614             return false;
6615 
6616         // if wback then R[n] = offset_addr;
6617         if (wback)
6618         {
6619             context.type = eContextAdjustBaseRegister;
6620             context.SetAddress (offset_addr);
6621             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6622                 return false;
6623         }
6624 
6625         // if UnalignedSupport() || address<0> = '0' then
6626         if (UnalignedSupport () || BitIsClear (address, 0))
6627         {
6628             // R[t] = ZeroExtend(data, 32);
6629             context.type = eContextRegisterLoad;
6630             context.SetRegisterPlusOffset (base_reg, address - Rn);
6631             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6632                 return false;
6633         }
6634         else // Can only apply before ARMv7
6635         {
6636             // R[t] = bits(32) UNKNOWN;
6637             WriteBits32Unknown (t);
6638         }
6639     }
6640     return true;
6641 }
6642 
6643 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory,
6644 // zero-extends it to form a 32-bit word, and writes it to a register.
6645 bool
6646 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding)
6647 {
6648 #if 0
6649     if ConditionPassed() then
6650         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6651         base = Align(PC,4);
6652         address = if add then (base + imm32) else (base - imm32);
6653         data = MemU[address,2];
6654         if UnalignedSupport() || address<0> = '0' then
6655             R[t] = ZeroExtend(data, 32);
6656         else // Can only apply before ARMv7
6657             R[t] = bits(32) UNKNOWN;
6658 #endif
6659 
6660     bool success = false;
6661 
6662     if (ConditionPassed(opcode))
6663     {
6664         uint32_t t;
6665         uint32_t imm32;
6666         bool add;
6667 
6668         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6669         switch (encoding)
6670         {
6671             case eEncodingT1:
6672                 // if Rt == '1111' then SEE "Unallocated memory hints";
6673                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6674                 t = Bits32 (opcode, 15, 12);
6675                 imm32 = Bits32 (opcode, 11, 0);
6676                 add = BitIsSet (opcode, 23);
6677 
6678                 // if t == 13 then UNPREDICTABLE;
6679                 if (t == 13)
6680                     return false;
6681 
6682                 break;
6683 
6684             case eEncodingA1:
6685             {
6686                 uint32_t imm4H = Bits32 (opcode, 11, 8);
6687                 uint32_t imm4L = Bits32 (opcode, 3, 0);
6688 
6689                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6690                 t = Bits32 (opcode, 15, 12);
6691                 imm32 = (imm4H << 4) | imm4L;
6692                 add = BitIsSet (opcode, 23);
6693 
6694                 // if t == 15 then UNPREDICTABLE;
6695                 if (t == 15)
6696                     return false;
6697                 break;
6698             }
6699 
6700             default:
6701                 return false;
6702         }
6703 
6704         // base = Align(PC,4);
6705         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6706         if (!success)
6707             return false;
6708 
6709         addr_t base = AlignPC (pc_value);
6710         addr_t address;
6711 
6712         // address = if add then (base + imm32) else (base - imm32);
6713         if (add)
6714             address = base + imm32;
6715         else
6716             address = base - imm32;
6717 
6718         // data = MemU[address,2];
6719         RegisterInfo base_reg;
6720         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
6721 
6722         EmulateInstruction::Context context;
6723         context.type = eContextRegisterLoad;
6724         context.SetRegisterPlusOffset (base_reg, address - base);
6725 
6726         uint64_t data = MemURead (context, address, 2, 0, &success);
6727         if (!success)
6728             return false;
6729 
6730 
6731         // if UnalignedSupport() || address<0> = '0' then
6732         if (UnalignedSupport () || BitIsClear (address, 0))
6733         {
6734             // R[t] = ZeroExtend(data, 32);
6735             context.type = eContextRegisterLoad;
6736             context.SetRegisterPlusOffset (base_reg, address - base);
6737             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6738                 return false;
6739 
6740         }
6741         else // Can only apply before ARMv7
6742         {
6743             // R[t] = bits(32) UNKNOWN;
6744             WriteBits32Unknown (t);
6745         }
6746     }
6747     return true;
6748 }
6749 
6750 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword
6751 // from memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6752 // be shifted left by 0, 1, 2, or 3 bits.
6753 bool
6754 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding)
6755 {
6756 #if 0
6757     if ConditionPassed() then
6758         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6759         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6760         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6761         address = if index then offset_addr else R[n];
6762         data = MemU[address,2];
6763         if wback then R[n] = offset_addr;
6764         if UnalignedSupport() || address<0> = '0' then
6765             R[t] = ZeroExtend(data, 32);
6766         else // Can only apply before ARMv7
6767             R[t] = bits(32) UNKNOWN;
6768 #endif
6769 
6770     bool success = false;
6771 
6772     if (ConditionPassed(opcode))
6773     {
6774         uint32_t t;
6775         uint32_t n;
6776         uint32_t m;
6777         bool index;
6778         bool add;
6779         bool wback;
6780         ARM_ShifterType shift_t;
6781         uint32_t shift_n;
6782 
6783         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6784         switch (encoding)
6785         {
6786             case eEncodingT1:
6787                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6788                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6789                 t = Bits32 (opcode, 2, 0);
6790                 n = Bits32 (opcode, 5, 3);
6791                 m = Bits32 (opcode, 8, 6);
6792 
6793                 // index = TRUE; add = TRUE; wback = FALSE;
6794                 index = true;
6795                 add = true;
6796                 wback = false;
6797 
6798                 // (shift_t, shift_n) = (SRType_LSL, 0);
6799                 shift_t = SRType_LSL;
6800                 shift_n = 0;
6801 
6802                 break;
6803 
6804             case eEncodingT2:
6805                 // if Rn == '1111' then SEE LDRH (literal);
6806                 // if Rt == '1111' then SEE "Unallocated memory hints";
6807                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6808                 t = Bits32 (opcode, 15, 12);
6809                 n = Bits32 (opcode, 19, 16);
6810                 m = Bits32 (opcode, 3, 0);
6811 
6812                 // index = TRUE; add = TRUE; wback = FALSE;
6813                 index = true;
6814                 add = true;
6815                 wback = false;
6816 
6817                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6818                 shift_t = SRType_LSL;
6819                 shift_n = Bits32 (opcode, 5, 4);
6820 
6821                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6822                 if ((t == 13) || BadReg (m))
6823                     return false;
6824                 break;
6825 
6826             case eEncodingA1:
6827                 // if P == '0' && W == '1' then SEE LDRHT;
6828                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6829                 t = Bits32 (opcode, 15, 12);
6830                 n = Bits32 (opcode, 19, 16);
6831                 m = Bits32 (opcode, 3, 0);
6832 
6833                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6834                 index = BitIsSet (opcode, 24);
6835                 add = BitIsSet (opcode, 23);
6836                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6837 
6838                 // (shift_t, shift_n) = (SRType_LSL, 0);
6839                 shift_t = SRType_LSL;
6840                 shift_n = 0;
6841 
6842                 // if t == 15 || m == 15 then UNPREDICTABLE;
6843                 if ((t == 15) || (m == 15))
6844                     return false;
6845 
6846                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6847                 if (wback && ((n == 15) || (n == t)))
6848                     return false;
6849 
6850                 break;
6851 
6852             default:
6853                 return false;
6854         }
6855 
6856         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6857 
6858         uint64_t Rm  = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6859         if (!success)
6860             return false;
6861 
6862         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6863         if (!success)
6864             return false;
6865 
6866         addr_t offset_addr;
6867         addr_t address;
6868 
6869         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6870         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6871         if (!success)
6872             return false;
6873 
6874         if (add)
6875             offset_addr = Rn + offset;
6876         else
6877             offset_addr = Rn - offset;
6878 
6879         // address = if index then offset_addr else R[n];
6880         if (index)
6881             address = offset_addr;
6882         else
6883             address = Rn;
6884 
6885         // data = MemU[address,2];
6886         RegisterInfo base_reg;
6887         RegisterInfo offset_reg;
6888         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6889         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
6890 
6891         EmulateInstruction::Context context;
6892         context.type = eContextRegisterLoad;
6893         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6894         uint64_t data = MemURead (context, address, 2, 0, &success);
6895         if (!success)
6896             return false;
6897 
6898         // if wback then R[n] = offset_addr;
6899         if (wback)
6900         {
6901             context.type = eContextAdjustBaseRegister;
6902             context.SetAddress (offset_addr);
6903             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6904                 return false;
6905         }
6906 
6907         // if UnalignedSupport() || address<0> = '0' then
6908         if (UnalignedSupport() || BitIsClear (address, 0))
6909         {
6910             // R[t] = ZeroExtend(data, 32);
6911             context.type = eContextRegisterLoad;
6912             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6913             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6914                 return false;
6915         }
6916         else // Can only apply before ARMv7
6917         {
6918             // R[t] = bits(32) UNKNOWN;
6919             WriteBits32Unknown (t);
6920         }
6921     }
6922     return true;
6923 }
6924 
6925 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from
6926 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed,
6927 // or pre-indexed addressing.
6928 bool
6929 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6930 {
6931 #if 0
6932     if ConditionPassed() then
6933         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6934         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6935         address = if index then offset_addr else R[n];
6936         R[t] = SignExtend(MemU[address,1], 32);
6937         if wback then R[n] = offset_addr;
6938 #endif
6939 
6940     bool success = false;
6941 
6942     if (ConditionPassed(opcode))
6943     {
6944         uint32_t t;
6945         uint32_t n;
6946         uint32_t imm32;
6947         bool index;
6948         bool add;
6949         bool wback;
6950 
6951         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6952         switch (encoding)
6953         {
6954             case eEncodingT1:
6955                 // if Rt == '1111' then SEE PLI;
6956                 // if Rn == '1111' then SEE LDRSB (literal);
6957                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6958                 t = Bits32 (opcode, 15, 12);
6959                 n = Bits32 (opcode, 19, 16);
6960                 imm32 = Bits32 (opcode, 11, 0);
6961 
6962                 // index = TRUE; add = TRUE; wback = FALSE;
6963                 index = true;
6964                 add = true;
6965                 wback = false;
6966 
6967                 // if t == 13 then UNPREDICTABLE;
6968                 if (t == 13)
6969                     return false;
6970 
6971                 break;
6972 
6973             case eEncodingT2:
6974                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
6975                 // if Rn == '1111' then SEE LDRSB (literal);
6976                 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
6977                 // if P == '0' && W == '0' then UNDEFINED;
6978                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6979                     return false;
6980 
6981                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6982                 t = Bits32 (opcode, 15, 12);
6983                 n = Bits32 (opcode, 19, 16);
6984                 imm32 = Bits32 (opcode, 7, 0);
6985 
6986                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6987                 index = BitIsSet (opcode, 10);
6988                 add = BitIsSet (opcode, 9);
6989                 wback = BitIsSet (opcode, 8);
6990 
6991                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6992                   if (((t == 13) || ((t == 15)
6993                                      && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8))))
6994                       || (wback && (n == t)))
6995                     return false;
6996 
6997                 break;
6998 
6999             case eEncodingA1:
7000             {
7001                 // if Rn == '1111' then SEE LDRSB (literal);
7002                 // if P == '0' && W == '1' then SEE LDRSBT;
7003                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7004                 t = Bits32 (opcode, 15, 12);
7005                 n = Bits32 (opcode, 19, 16);
7006 
7007                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7008                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7009                 imm32 = (imm4H << 4) | imm4L;
7010 
7011                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7012                 index = BitIsSet (opcode, 24);
7013                 add = BitIsSet (opcode, 23);
7014                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
7015 
7016                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7017                 if ((t == 15) || (wback && (n == t)))
7018                     return false;
7019 
7020                 break;
7021             }
7022 
7023             default:
7024                 return false;
7025         }
7026 
7027         uint64_t Rn = ReadCoreReg (n, &success);
7028         if (!success)
7029             return false;
7030 
7031         addr_t offset_addr;
7032         addr_t address;
7033 
7034         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7035         if (add)
7036             offset_addr = Rn + imm32;
7037         else
7038             offset_addr = Rn - imm32;
7039 
7040         // address = if index then offset_addr else R[n];
7041         if (index)
7042             address = offset_addr;
7043         else
7044             address = Rn;
7045 
7046         // R[t] = SignExtend(MemU[address,1], 32);
7047         RegisterInfo base_reg;
7048         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7049 
7050         EmulateInstruction::Context context;
7051         context.type = eContextRegisterLoad;
7052         context.SetRegisterPlusOffset (base_reg, address - Rn);
7053 
7054         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7055         if (!success)
7056             return false;
7057 
7058         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7059         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7060             return false;
7061 
7062         // if wback then R[n] = offset_addr;
7063         if (wback)
7064         {
7065             context.type = eContextAdjustBaseRegister;
7066             context.SetAddress (offset_addr);
7067             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7068                 return false;
7069         }
7070     }
7071 
7072     return true;
7073 }
7074 
7075 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
7076 // sign-extends it to form a 32-bit word, and writes tit to a register.
7077 bool
7078 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding)
7079 {
7080 #if 0
7081     if ConditionPassed() then
7082         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7083         base = Align(PC,4);
7084         address = if add then (base + imm32) else (base - imm32);
7085         R[t] = SignExtend(MemU[address,1], 32);
7086 #endif
7087 
7088     bool success = false;
7089 
7090     if (ConditionPassed(opcode))
7091     {
7092         uint32_t t;
7093         uint32_t imm32;
7094         bool add;
7095 
7096         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7097         switch (encoding)
7098         {
7099             case eEncodingT1:
7100                 // if Rt == '1111' then SEE PLI;
7101                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7102                 t = Bits32 (opcode, 15, 12);
7103                 imm32 = Bits32 (opcode, 11, 0);
7104                 add = BitIsSet (opcode, 23);
7105 
7106                 // if t == 13 then UNPREDICTABLE;
7107                 if (t == 13)
7108                     return false;
7109 
7110                 break;
7111 
7112             case eEncodingA1:
7113             {
7114                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7115                 t = Bits32 (opcode, 15, 12);
7116                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7117                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7118                 imm32 = (imm4H << 4) | imm4L;
7119                 add = BitIsSet (opcode, 23);
7120 
7121                 // if t == 15 then UNPREDICTABLE;
7122                 if (t == 15)
7123                     return false;
7124 
7125                 break;
7126             }
7127 
7128             default:
7129                 return false;
7130         }
7131 
7132         // base = Align(PC,4);
7133         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7134         if (!success)
7135             return false;
7136         uint64_t base = AlignPC (pc_value);
7137 
7138         // address = if add then (base + imm32) else (base - imm32);
7139         addr_t address;
7140         if (add)
7141             address = base + imm32;
7142         else
7143             address = base - imm32;
7144 
7145         // R[t] = SignExtend(MemU[address,1], 32);
7146         RegisterInfo base_reg;
7147         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7148 
7149         EmulateInstruction::Context context;
7150         context.type = eContextRegisterLoad;
7151         context.SetRegisterPlusOffset (base_reg, address - base);
7152 
7153         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7154         if (!success)
7155             return false;
7156 
7157         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7158         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7159             return false;
7160     }
7161     return true;
7162 }
7163 
7164 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from
7165 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7166 // shifted left by 0, 1, 2, or 3 bits.
7167 bool
7168 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding)
7169 {
7170 #if 0
7171     if ConditionPassed() then
7172         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7173         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7174         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7175         address = if index then offset_addr else R[n];
7176         R[t] = SignExtend(MemU[address,1], 32);
7177         if wback then R[n] = offset_addr;
7178 #endif
7179 
7180     bool success = false;
7181 
7182     if (ConditionPassed(opcode))
7183     {
7184         uint32_t t;
7185         uint32_t n;
7186         uint32_t m;
7187         bool index;
7188         bool add;
7189         bool wback;
7190         ARM_ShifterType shift_t;
7191         uint32_t shift_n;
7192 
7193         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7194         switch (encoding)
7195         {
7196             case eEncodingT1:
7197                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7198                 t = Bits32 (opcode, 2, 0);
7199                 n = Bits32 (opcode, 5, 3);
7200                 m = Bits32 (opcode, 8, 6);
7201 
7202                 // index = TRUE; add = TRUE; wback = FALSE;
7203                 index = true;
7204                 add = true;
7205                 wback = false;
7206 
7207                 // (shift_t, shift_n) = (SRType_LSL, 0);
7208                 shift_t = SRType_LSL;
7209                 shift_n = 0;
7210 
7211                 break;
7212 
7213             case eEncodingT2:
7214                 // if Rt == '1111' then SEE PLI;
7215                 // if Rn == '1111' then SEE LDRSB (literal);
7216                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7217                 t = Bits32 (opcode, 15, 12);
7218                 n = Bits32 (opcode, 19, 16);
7219                 m = Bits32 (opcode, 3, 0);
7220 
7221                 // index = TRUE; add = TRUE; wback = FALSE;
7222                 index = true;
7223                 add = true;
7224                 wback = false;
7225 
7226                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7227                 shift_t = SRType_LSL;
7228                 shift_n = Bits32 (opcode, 5, 4);
7229 
7230                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7231                 if ((t == 13) || BadReg (m))
7232                     return false;
7233                 break;
7234 
7235             case eEncodingA1:
7236                 // if P == '0' && W == '1' then SEE LDRSBT;
7237                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7238                 t = Bits32 (opcode, 15, 12);
7239                 n = Bits32 (opcode, 19, 16);
7240                 m = Bits32 (opcode, 3, 0);
7241 
7242                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7243                 index = BitIsSet (opcode, 24);
7244                 add = BitIsSet (opcode, 23);
7245                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7246 
7247                 // (shift_t, shift_n) = (SRType_LSL, 0);
7248                 shift_t = SRType_LSL;
7249                 shift_n = 0;
7250 
7251                 // if t == 15 || m == 15 then UNPREDICTABLE;
7252                 if ((t == 15) || (m == 15))
7253                     return false;
7254 
7255                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7256                 if (wback && ((n == 15) || (n == t)))
7257                     return false;
7258                 break;
7259 
7260             default:
7261                 return false;
7262         }
7263 
7264         uint64_t Rm =  ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7265         if (!success)
7266             return false;
7267 
7268         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7269         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7270         if (!success)
7271             return false;
7272 
7273         addr_t offset_addr;
7274         addr_t address;
7275 
7276         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7277         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7278         if (!success)
7279             return false;
7280 
7281         if (add)
7282             offset_addr = Rn + offset;
7283         else
7284             offset_addr = Rn - offset;
7285 
7286         // address = if index then offset_addr else R[n];
7287         if (index)
7288             address = offset_addr;
7289         else
7290             address = Rn;
7291 
7292         // R[t] = SignExtend(MemU[address,1], 32);
7293         RegisterInfo base_reg;
7294         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7295         RegisterInfo offset_reg;
7296         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7297 
7298         EmulateInstruction::Context context;
7299         context.type = eContextRegisterLoad;
7300         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7301 
7302         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7303         if (!success)
7304             return false;
7305 
7306         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7307         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7308             return false;
7309 
7310         // if wback then R[n] = offset_addr;
7311         if (wback)
7312         {
7313             context.type = eContextAdjustBaseRegister;
7314             context.SetAddress (offset_addr);
7315             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7316                 return false;
7317         }
7318     }
7319     return true;
7320 }
7321 
7322 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from
7323 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed, or
7324 // pre-indexed addressing.
7325 bool
7326 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding)
7327 {
7328 #if 0
7329     if ConditionPassed() then
7330         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7331         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7332         address = if index then offset_addr else R[n];
7333         data = MemU[address,2];
7334         if wback then R[n] = offset_addr;
7335         if UnalignedSupport() || address<0> = '0' then
7336             R[t] = SignExtend(data, 32);
7337         else // Can only apply before ARMv7
7338             R[t] = bits(32) UNKNOWN;
7339 #endif
7340 
7341     bool success = false;
7342 
7343     if (ConditionPassed(opcode))
7344     {
7345         uint32_t t;
7346         uint32_t n;
7347         uint32_t imm32;
7348         bool index;
7349         bool add;
7350         bool wback;
7351 
7352         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7353         switch (encoding)
7354         {
7355             case eEncodingT1:
7356                 // if Rn == '1111' then SEE LDRSH (literal);
7357                 // if Rt == '1111' then SEE "Unallocated memory hints";
7358                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7359                 t = Bits32 (opcode, 15, 12);
7360                 n = Bits32 (opcode, 19, 16);
7361                 imm32 = Bits32 (opcode, 11, 0);
7362 
7363                 // index = TRUE; add = TRUE; wback = FALSE;
7364                 index = true;
7365                 add = true;
7366                 wback = false;
7367 
7368                 // if t == 13 then UNPREDICTABLE;
7369                 if (t == 13)
7370                     return false;
7371 
7372                 break;
7373 
7374             case eEncodingT2:
7375                 // if Rn == '1111' then SEE LDRSH (literal);
7376                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
7377                 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7378                 // if P == '0' && W == '0' then UNDEFINED;
7379                   if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7380                   return false;
7381 
7382                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7383                 t = Bits32 (opcode, 15, 12);
7384                 n = Bits32 (opcode, 19, 16);
7385                 imm32 = Bits32 (opcode, 7, 0);
7386 
7387                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7388                 index = BitIsSet (opcode, 10);
7389                 add = BitIsSet (opcode, 9);
7390                 wback = BitIsSet (opcode, 8);
7391 
7392                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7393                 if (BadReg (t) || (wback && (n == t)))
7394                     return false;
7395 
7396                 break;
7397 
7398             case eEncodingA1:
7399             {
7400                 // if Rn == '1111' then SEE LDRSH (literal);
7401                 // if P == '0' && W == '1' then SEE LDRSHT;
7402                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7403                 t = Bits32 (opcode, 15, 12);
7404                 n = Bits32 (opcode, 19, 16);
7405                 uint32_t imm4H = Bits32 (opcode, 11,8);
7406                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7407                 imm32 = (imm4H << 4) | imm4L;
7408 
7409                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7410                 index = BitIsSet (opcode, 24);
7411                 add = BitIsSet (opcode, 23);
7412                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7413 
7414                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7415                 if ((t == 15) || (wback && (n == t)))
7416                     return false;
7417 
7418                 break;
7419             }
7420 
7421             default:
7422                 return false;
7423         }
7424 
7425         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7426         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7427         if (!success)
7428             return false;
7429 
7430         addr_t offset_addr;
7431         if (add)
7432             offset_addr = Rn + imm32;
7433         else
7434             offset_addr = Rn - imm32;
7435 
7436         // address = if index then offset_addr else R[n];
7437         addr_t address;
7438         if (index)
7439             address = offset_addr;
7440         else
7441             address = Rn;
7442 
7443         // data = MemU[address,2];
7444         RegisterInfo base_reg;
7445         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7446 
7447         EmulateInstruction::Context context;
7448         context.type = eContextRegisterLoad;
7449         context.SetRegisterPlusOffset (base_reg, address - Rn);
7450 
7451         uint64_t data = MemURead (context, address, 2, 0, &success);
7452         if (!success)
7453             return false;
7454 
7455         // if wback then R[n] = offset_addr;
7456         if (wback)
7457         {
7458             context.type = eContextAdjustBaseRegister;
7459             context.SetAddress (offset_addr);
7460             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7461                 return false;
7462         }
7463 
7464         // if UnalignedSupport() || address<0> = '0' then
7465         if (UnalignedSupport() || BitIsClear (address, 0))
7466         {
7467             // R[t] = SignExtend(data, 32);
7468             int64_t signed_data = llvm::SignExtend64<16>(data);
7469             context.type = eContextRegisterLoad;
7470             context.SetRegisterPlusOffset (base_reg, address - Rn);
7471             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7472                 return false;
7473         }
7474         else // Can only apply before ARMv7
7475         {
7476             // R[t] = bits(32) UNKNOWN;
7477             WriteBits32Unknown (t);
7478         }
7479     }
7480     return true;
7481 }
7482 
7483 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory,
7484 // sign-extends it to from a 32-bit word, and writes it to a register.
7485 bool
7486 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding)
7487 {
7488 #if 0
7489     if ConditionPassed() then
7490         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7491         base = Align(PC,4);
7492         address = if add then (base + imm32) else (base - imm32);
7493         data = MemU[address,2];
7494         if UnalignedSupport() || address<0> = '0' then
7495             R[t] = SignExtend(data, 32);
7496         else // Can only apply before ARMv7
7497             R[t] = bits(32) UNKNOWN;
7498 #endif
7499 
7500     bool success = false;
7501 
7502     if (ConditionPassed(opcode))
7503     {
7504         uint32_t t;
7505         uint32_t imm32;
7506         bool add;
7507 
7508         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7509         switch (encoding)
7510         {
7511             case eEncodingT1:
7512                 // if Rt == '1111' then SEE "Unallocated memory hints";
7513                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7514                 t = Bits32  (opcode, 15, 12);
7515                 imm32 = Bits32 (opcode, 11, 0);
7516                 add = BitIsSet (opcode, 23);
7517 
7518                 // if t == 13 then UNPREDICTABLE;
7519                 if (t == 13)
7520                     return false;
7521 
7522                 break;
7523 
7524             case eEncodingA1:
7525             {
7526                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7527                 t = Bits32 (opcode, 15, 12);
7528                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7529                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7530                 imm32 = (imm4H << 4) | imm4L;
7531                 add = BitIsSet (opcode, 23);
7532 
7533                 // if t == 15 then UNPREDICTABLE;
7534                 if (t == 15)
7535                     return false;
7536 
7537                 break;
7538             }
7539             default:
7540                 return false;
7541         }
7542 
7543         // base = Align(PC,4);
7544         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7545         if (!success)
7546             return false;
7547 
7548         uint64_t base = AlignPC (pc_value);
7549 
7550         addr_t address;
7551         // address = if add then (base + imm32) else (base - imm32);
7552         if (add)
7553             address = base + imm32;
7554         else
7555             address = base - imm32;
7556 
7557         // data = MemU[address,2];
7558         RegisterInfo base_reg;
7559         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7560 
7561         EmulateInstruction::Context context;
7562         context.type = eContextRegisterLoad;
7563         context.SetRegisterPlusOffset (base_reg, imm32);
7564 
7565         uint64_t data = MemURead (context, address, 2, 0, &success);
7566         if (!success)
7567             return false;
7568 
7569         // if UnalignedSupport() || address<0> = '0' then
7570         if (UnalignedSupport() || BitIsClear (address, 0))
7571         {
7572             // R[t] = SignExtend(data, 32);
7573             int64_t signed_data = llvm::SignExtend64<16>(data);
7574             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7575                 return false;
7576         }
7577         else // Can only apply before ARMv7
7578         {
7579             // R[t] = bits(32) UNKNOWN;
7580             WriteBits32Unknown (t);
7581         }
7582     }
7583     return true;
7584 }
7585 
7586 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword
7587 // from memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7588 // shifted left by 0, 1, 2, or 3 bits.
7589 bool
7590 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding)
7591 {
7592 #if 0
7593     if ConditionPassed() then
7594         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7595         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7596         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7597         address = if index then offset_addr else R[n];
7598         data = MemU[address,2];
7599         if wback then R[n] = offset_addr;
7600         if UnalignedSupport() || address<0> = '0' then
7601             R[t] = SignExtend(data, 32);
7602         else // Can only apply before ARMv7
7603             R[t] = bits(32) UNKNOWN;
7604 #endif
7605 
7606     bool success = false;
7607 
7608     if (ConditionPassed(opcode))
7609     {
7610         uint32_t t;
7611         uint32_t n;
7612         uint32_t m;
7613         bool index;
7614         bool add;
7615         bool wback;
7616         ARM_ShifterType shift_t;
7617         uint32_t shift_n;
7618 
7619         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7620         switch (encoding)
7621         {
7622             case eEncodingT1:
7623                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
7624                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7625                 t = Bits32 (opcode, 2, 0);
7626                 n = Bits32 (opcode, 5, 3);
7627                 m = Bits32 (opcode, 8, 6);
7628 
7629                 // index = TRUE; add = TRUE; wback = FALSE;
7630                 index = true;
7631                 add = true;
7632                 wback = false;
7633 
7634                 // (shift_t, shift_n) = (SRType_LSL, 0);
7635                 shift_t = SRType_LSL;
7636                 shift_n = 0;
7637 
7638                 break;
7639 
7640             case eEncodingT2:
7641                 // if Rn == '1111' then SEE LDRSH (literal);
7642                 // if Rt == '1111' then SEE "Unallocated memory hints";
7643                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7644                 t = Bits32 (opcode, 15, 12);
7645                 n = Bits32 (opcode, 19, 16);
7646                 m = Bits32 (opcode, 3, 0);
7647 
7648                 // index = TRUE; add = TRUE; wback = FALSE;
7649                 index = true;
7650                 add = true;
7651                 wback = false;
7652 
7653                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7654                 shift_t = SRType_LSL;
7655                 shift_n = Bits32 (opcode, 5, 4);
7656 
7657                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7658                 if ((t == 13) || BadReg (m))
7659                     return false;
7660 
7661                 break;
7662 
7663             case eEncodingA1:
7664                 // if P == '0' && W == '1' then SEE LDRSHT;
7665                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7666                 t = Bits32 (opcode, 15, 12);
7667                 n = Bits32 (opcode, 19, 16);
7668                 m = Bits32 (opcode, 3, 0);
7669 
7670                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7671                 index = BitIsSet (opcode, 24);
7672                 add = BitIsSet (opcode, 23);
7673                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7674 
7675                 // (shift_t, shift_n) = (SRType_LSL, 0);
7676                 shift_t = SRType_LSL;
7677                 shift_n = 0;
7678 
7679                 // if t == 15 || m == 15 then UNPREDICTABLE;
7680                 if ((t == 15) || (m == 15))
7681                     return false;
7682 
7683                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7684                 if (wback && ((n == 15) || (n == t)))
7685                     return false;
7686 
7687                 break;
7688 
7689             default:
7690                 return false;
7691         }
7692 
7693         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7694         if (!success)
7695             return false;
7696 
7697         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7698         if (!success)
7699             return false;
7700 
7701         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7702         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7703         if (!success)
7704             return false;
7705 
7706         addr_t offset_addr;
7707         addr_t address;
7708 
7709         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7710         if (add)
7711             offset_addr = Rn + offset;
7712         else
7713             offset_addr = Rn - offset;
7714 
7715         // address = if index then offset_addr else R[n];
7716         if (index)
7717             address = offset_addr;
7718         else
7719             address = Rn;
7720 
7721         // data = MemU[address,2];
7722         RegisterInfo base_reg;
7723         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7724 
7725         RegisterInfo offset_reg;
7726         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7727 
7728         EmulateInstruction::Context context;
7729         context.type = eContextRegisterLoad;
7730         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7731 
7732         uint64_t data = MemURead (context, address, 2, 0, &success);
7733         if (!success)
7734             return false;
7735 
7736         // if wback then R[n] = offset_addr;
7737         if (wback)
7738         {
7739             context.type = eContextAdjustBaseRegister;
7740             context.SetAddress (offset_addr);
7741             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7742                 return false;
7743         }
7744 
7745         // if UnalignedSupport() || address<0> = '0' then
7746         if (UnalignedSupport() || BitIsClear (address, 0))
7747         {
7748             // R[t] = SignExtend(data, 32);
7749             context.type = eContextRegisterLoad;
7750             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7751 
7752             int64_t signed_data = llvm::SignExtend64<16>(data);
7753             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7754                 return false;
7755         }
7756         else // Can only apply before ARMv7
7757         {
7758             // R[t] = bits(32) UNKNOWN;
7759             WriteBits32Unknown (t);
7760         }
7761     }
7762     return true;
7763 }
7764 
7765 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7766 // register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7767 bool
7768 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding)
7769 {
7770 #if 0
7771     if ConditionPassed() then
7772         EncodingSpecificOperations();
7773         rotated = ROR(R[m], rotation);
7774         R[d] = SignExtend(rotated<7:0>, 32);
7775 #endif
7776 
7777     bool success = false;
7778 
7779     if (ConditionPassed(opcode))
7780     {
7781         uint32_t d;
7782         uint32_t m;
7783         uint32_t rotation;
7784 
7785         // EncodingSpecificOperations();
7786         switch (encoding)
7787         {
7788             case eEncodingT1:
7789                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7790                 d = Bits32 (opcode, 2, 0);
7791                 m = Bits32 (opcode, 5, 3);
7792                 rotation = 0;
7793 
7794                 break;
7795 
7796             case eEncodingT2:
7797                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7798                 d = Bits32 (opcode, 11, 8);
7799                 m = Bits32 (opcode, 3, 0);
7800                 rotation = Bits32 (opcode, 5, 4) << 3;
7801 
7802                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7803                 if (BadReg (d) || BadReg (m))
7804                     return false;
7805 
7806                 break;
7807 
7808             case eEncodingA1:
7809                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7810                 d = Bits32 (opcode, 15, 12);
7811                 m = Bits32 (opcode, 3, 0);
7812                 rotation = Bits32 (opcode, 11, 10) << 3;
7813 
7814                 // if d == 15 || m == 15 then UNPREDICTABLE;
7815                 if ((d == 15) || (m == 15))
7816                     return false;
7817 
7818                 break;
7819 
7820             default:
7821                 return false;
7822         }
7823 
7824         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7825         if (!success)
7826             return false;
7827 
7828         // rotated = ROR(R[m], rotation);
7829         uint64_t rotated = ROR (Rm, rotation, &success);
7830         if (!success)
7831             return false;
7832 
7833         // R[d] = SignExtend(rotated<7:0>, 32);
7834         int64_t data = llvm::SignExtend64<8>(rotated);
7835 
7836         RegisterInfo source_reg;
7837         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7838 
7839         EmulateInstruction::Context context;
7840         context.type = eContextRegisterLoad;
7841         context.SetRegister (source_reg);
7842 
7843         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7844             return false;
7845     }
7846     return true;
7847 }
7848 
7849 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7850 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7851 bool
7852 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding)
7853 {
7854 #if 0
7855     if ConditionPassed() then
7856         EncodingSpecificOperations();
7857         rotated = ROR(R[m], rotation);
7858         R[d] = SignExtend(rotated<15:0>, 32);
7859 #endif
7860 
7861     bool success = false;
7862 
7863     if (ConditionPassed(opcode))
7864     {
7865         uint32_t d;
7866         uint32_t m;
7867         uint32_t rotation;
7868 
7869         // EncodingSpecificOperations();
7870         switch (encoding)
7871         {
7872             case eEncodingT1:
7873                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7874                 d = Bits32 (opcode, 2, 0);
7875                 m = Bits32 (opcode, 5, 3);
7876                 rotation = 0;
7877 
7878                 break;
7879 
7880             case eEncodingT2:
7881                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7882                 d = Bits32 (opcode, 11, 8);
7883                 m = Bits32 (opcode, 3, 0);
7884                 rotation = Bits32 (opcode, 5, 4) << 3;
7885 
7886                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7887                 if (BadReg (d) || BadReg (m))
7888                     return false;
7889 
7890                 break;
7891 
7892             case eEncodingA1:
7893                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7894                 d = Bits32 (opcode, 15, 12);
7895                 m = Bits32 (opcode, 3, 0);
7896                 rotation = Bits32 (opcode, 11, 10) << 3;
7897 
7898                 // if d == 15 || m == 15 then UNPREDICTABLE;
7899                 if ((d == 15) || (m == 15))
7900                     return false;
7901 
7902                 break;
7903 
7904             default:
7905                 return false;
7906         }
7907 
7908         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7909         if (!success)
7910             return false;
7911 
7912         // rotated = ROR(R[m], rotation);
7913         uint64_t rotated = ROR (Rm, rotation, &success);
7914         if (!success)
7915             return false;
7916 
7917         // R[d] = SignExtend(rotated<15:0>, 32);
7918         RegisterInfo source_reg;
7919         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7920 
7921         EmulateInstruction::Context context;
7922         context.type = eContextRegisterLoad;
7923         context.SetRegister (source_reg);
7924 
7925         int64_t data = llvm::SignExtend64<16> (rotated);
7926         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7927             return false;
7928     }
7929 
7930     return true;
7931 }
7932 
7933 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination
7934 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7935 bool
7936 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding)
7937 {
7938 #if 0
7939     if ConditionPassed() then
7940         EncodingSpecificOperations();
7941         rotated = ROR(R[m], rotation);
7942         R[d] = ZeroExtend(rotated<7:0>, 32);
7943 #endif
7944 
7945     bool success = false;
7946 
7947     if (ConditionPassed(opcode))
7948     {
7949         uint32_t d;
7950         uint32_t m;
7951         uint32_t rotation;
7952 
7953         // EncodingSpecificOperations();
7954         switch (encoding)
7955         {
7956             case eEncodingT1:
7957                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7958                 d = Bits32 (opcode, 2, 0);
7959                 m = Bits32 (opcode, 5, 3);
7960                 rotation = 0;
7961 
7962                 break;
7963 
7964             case eEncodingT2:
7965                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7966                 d = Bits32 (opcode, 11, 8);
7967                 m = Bits32 (opcode, 3, 0);
7968                   rotation = Bits32 (opcode, 5, 4) << 3;
7969 
7970                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7971                 if (BadReg (d) || BadReg (m))
7972                   return false;
7973 
7974                 break;
7975 
7976             case eEncodingA1:
7977                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7978                 d = Bits32 (opcode, 15, 12);
7979                 m = Bits32 (opcode, 3, 0);
7980                 rotation = Bits32 (opcode, 11, 10) << 3;
7981 
7982                 // if d == 15 || m == 15 then UNPREDICTABLE;
7983                 if ((d == 15) || (m == 15))
7984                     return false;
7985 
7986                 break;
7987 
7988             default:
7989                 return false;
7990         }
7991 
7992         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7993         if (!success)
7994             return false;
7995 
7996         // rotated = ROR(R[m], rotation);
7997         uint64_t rotated = ROR (Rm, rotation, &success);
7998         if (!success)
7999             return false;
8000 
8001         // R[d] = ZeroExtend(rotated<7:0>, 32);
8002         RegisterInfo source_reg;
8003         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8004 
8005         EmulateInstruction::Context context;
8006         context.type = eContextRegisterLoad;
8007         context.SetRegister (source_reg);
8008 
8009         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0)))
8010             return false;
8011     }
8012     return true;
8013 }
8014 
8015 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination
8016 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
8017 bool
8018 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding)
8019 {
8020 #if 0
8021     if ConditionPassed() then
8022         EncodingSpecificOperations();
8023         rotated = ROR(R[m], rotation);
8024         R[d] = ZeroExtend(rotated<15:0>, 32);
8025 #endif
8026 
8027     bool success = false;
8028 
8029     if (ConditionPassed(opcode))
8030     {
8031         uint32_t d;
8032         uint32_t m;
8033         uint32_t rotation;
8034 
8035         switch (encoding)
8036         {
8037             case eEncodingT1:
8038                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8039                 d = Bits32 (opcode, 2, 0);
8040                 m = Bits32 (opcode, 5, 3);
8041                 rotation = 0;
8042 
8043                 break;
8044 
8045             case eEncodingT2:
8046                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8047                 d = Bits32 (opcode, 11, 8);
8048                 m = Bits32 (opcode, 3, 0);
8049                 rotation = Bits32 (opcode, 5, 4) << 3;
8050 
8051                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8052                 if (BadReg (d) || BadReg (m))
8053                   return false;
8054 
8055                 break;
8056 
8057             case eEncodingA1:
8058                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8059                 d = Bits32 (opcode, 15, 12);
8060                 m = Bits32 (opcode, 3, 0);
8061                 rotation = Bits32 (opcode, 11, 10) << 3;
8062 
8063                 // if d == 15 || m == 15 then UNPREDICTABLE;
8064                 if ((d == 15) || (m == 15))
8065                     return false;
8066 
8067                 break;
8068 
8069             default:
8070                 return false;
8071         }
8072 
8073         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8074         if (!success)
8075             return false;
8076 
8077         // rotated = ROR(R[m], rotation);
8078         uint64_t rotated = ROR (Rm, rotation, &success);
8079         if (!success)
8080             return false;
8081 
8082         // R[d] = ZeroExtend(rotated<15:0>, 32);
8083         RegisterInfo source_reg;
8084         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8085 
8086         EmulateInstruction::Context context;
8087         context.type = eContextRegisterLoad;
8088         context.SetRegister (source_reg);
8089 
8090         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0)))
8091             return false;
8092     }
8093     return true;
8094 }
8095 
8096 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following
8097 // word respectively.
8098 bool
8099 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding)
8100 {
8101 #if 0
8102     if ConditionPassed() then
8103         EncodingSpecificOperations();
8104         if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8105             UNPREDICTABLE;
8106         else
8107             address = if increment then R[n] else R[n]-8;
8108             if wordhigher then address = address+4;
8109             CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8110             BranchWritePC(MemA[address,4]);
8111             if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8112 #endif
8113 
8114     bool success = false;
8115 
8116     if (ConditionPassed(opcode))
8117     {
8118         uint32_t n;
8119         bool wback;
8120         bool increment;
8121         bool wordhigher;
8122 
8123         // EncodingSpecificOperations();
8124         switch (encoding)
8125         {
8126             case eEncodingT1:
8127                 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE;
8128                 n = Bits32 (opcode, 19, 16);
8129                 wback = BitIsSet (opcode, 21);
8130                 increment = false;
8131                 wordhigher = false;
8132 
8133                 // if n == 15 then UNPREDICTABLE;
8134                 if (n == 15)
8135                     return false;
8136 
8137                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8138                 if (InITBlock() && !LastInITBlock())
8139                     return false;
8140 
8141                 break;
8142 
8143             case eEncodingT2:
8144                 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8145                 n = Bits32 (opcode, 19, 16);
8146                 wback = BitIsSet (opcode, 21);
8147                 increment = true;
8148                 wordhigher = false;
8149 
8150                 // if n == 15 then UNPREDICTABLE;
8151                 if (n == 15)
8152                     return false;
8153 
8154                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8155                 if (InITBlock() && !LastInITBlock())
8156                     return false;
8157 
8158                 break;
8159 
8160             case eEncodingA1:
8161                 // n = UInt(Rn);
8162                 n = Bits32 (opcode, 19, 16);
8163 
8164                 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8165                 wback = BitIsSet (opcode, 21);
8166                 increment = BitIsSet (opcode, 23);
8167                 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23));
8168 
8169                 // if n == 15 then UNPREDICTABLE;
8170                 if (n == 15)
8171                     return false;
8172 
8173                 break;
8174 
8175             default:
8176                 return false;
8177         }
8178 
8179         // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8180         if (!CurrentModeIsPrivileged ())
8181             // UNPREDICTABLE;
8182             return false;
8183         else
8184         {
8185             uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8186             if (!success)
8187                 return false;
8188 
8189             addr_t address;
8190             // address = if increment then R[n] else R[n]-8;
8191             if (increment)
8192                 address = Rn;
8193             else
8194                 address = Rn - 8;
8195 
8196             // if wordhigher then address = address+4;
8197             if (wordhigher)
8198                 address = address + 4;
8199 
8200             // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8201             RegisterInfo base_reg;
8202             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8203 
8204             EmulateInstruction::Context context;
8205             context.type = eContextReturnFromException;
8206             context.SetRegisterPlusOffset (base_reg, address - Rn);
8207 
8208             uint64_t data = MemARead (context, address + 4, 4, 0, &success);
8209             if (!success)
8210                 return false;
8211 
8212             CPSRWriteByInstr (data, 15, true);
8213 
8214             // BranchWritePC(MemA[address,4]);
8215             uint64_t data2 = MemARead (context, address, 4, 0, &success);
8216             if (!success)
8217                 return false;
8218 
8219             BranchWritePC (context, data2);
8220 
8221             // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8222             if (wback)
8223             {
8224                 context.type = eContextAdjustBaseRegister;
8225                 if (increment)
8226                 {
8227                     context.SetOffset (8);
8228                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8))
8229                         return false;
8230                 }
8231                 else
8232                 {
8233                     context.SetOffset (-8);
8234                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8))
8235                         return false;
8236                 }
8237             } // if wback
8238         }
8239     } // if ConditionPassed()
8240     return true;
8241 }
8242 
8243 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
8244 // and writes the result to the destination register.  It can optionally update the condition flags based on
8245 // the result.
8246 bool
8247 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding)
8248 {
8249 #if 0
8250     // ARM pseudo code...
8251     if ConditionPassed() then
8252         EncodingSpecificOperations();
8253         result = R[n] EOR imm32;
8254         if d == 15 then         // Can only occur for ARM encoding
8255             ALUWritePC(result); // setflags is always FALSE here
8256         else
8257             R[d] = result;
8258             if setflags then
8259                 APSR.N = result<31>;
8260                 APSR.Z = IsZeroBit(result);
8261                 APSR.C = carry;
8262                 // APSR.V unchanged
8263 #endif
8264 
8265     bool success = false;
8266 
8267     if (ConditionPassed(opcode))
8268     {
8269         uint32_t Rd, Rn;
8270         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8271         bool setflags;
8272         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8273         switch (encoding)
8274         {
8275         case eEncodingT1:
8276             Rd = Bits32(opcode, 11, 8);
8277             Rn = Bits32(opcode, 19, 16);
8278             setflags = BitIsSet(opcode, 20);
8279             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8280             // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8281             if (Rd == 15 && setflags)
8282                 return EmulateTEQImm (opcode, eEncodingT1);
8283             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8284                 return false;
8285             break;
8286         case eEncodingA1:
8287             Rd = Bits32(opcode, 15, 12);
8288             Rn = Bits32(opcode, 19, 16);
8289             setflags = BitIsSet(opcode, 20);
8290             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8291 
8292             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8293             if (Rd == 15 && setflags)
8294                 return EmulateSUBSPcLrEtc (opcode, encoding);
8295             break;
8296         default:
8297             return false;
8298         }
8299 
8300         // Read the first operand.
8301         uint32_t val1 = ReadCoreReg(Rn, &success);
8302         if (!success)
8303             return false;
8304 
8305         uint32_t result = val1 ^ imm32;
8306 
8307         EmulateInstruction::Context context;
8308         context.type = EmulateInstruction::eContextImmediate;
8309         context.SetNoArgs ();
8310 
8311         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8312             return false;
8313     }
8314     return true;
8315 }
8316 
8317 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an
8318 // optionally-shifted register value, and writes the result to the destination register.
8319 // It can optionally update the condition flags based on the result.
8320 bool
8321 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding)
8322 {
8323 #if 0
8324     // ARM pseudo code...
8325     if ConditionPassed() then
8326         EncodingSpecificOperations();
8327         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8328         result = R[n] EOR shifted;
8329         if d == 15 then         // Can only occur for ARM encoding
8330             ALUWritePC(result); // setflags is always FALSE here
8331         else
8332             R[d] = result;
8333             if setflags then
8334                 APSR.N = result<31>;
8335                 APSR.Z = IsZeroBit(result);
8336                 APSR.C = carry;
8337                 // APSR.V unchanged
8338 #endif
8339 
8340     bool success = false;
8341 
8342     if (ConditionPassed(opcode))
8343     {
8344         uint32_t Rd, Rn, Rm;
8345         ARM_ShifterType shift_t;
8346         uint32_t shift_n; // the shift applied to the value read from Rm
8347         bool setflags;
8348         uint32_t carry;
8349         switch (encoding)
8350         {
8351         case eEncodingT1:
8352             Rd = Rn = Bits32(opcode, 2, 0);
8353             Rm = Bits32(opcode, 5, 3);
8354             setflags = !InITBlock();
8355             shift_t = SRType_LSL;
8356             shift_n = 0;
8357             break;
8358         case eEncodingT2:
8359             Rd = Bits32(opcode, 11, 8);
8360             Rn = Bits32(opcode, 19, 16);
8361             Rm = Bits32(opcode, 3, 0);
8362             setflags = BitIsSet(opcode, 20);
8363             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8364             // if Rd == '1111' && S == '1' then SEE TEQ (register);
8365             if (Rd == 15 && setflags)
8366                 return EmulateTEQReg (opcode, eEncodingT1);
8367             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8368                 return false;
8369             break;
8370         case eEncodingA1:
8371             Rd = Bits32(opcode, 15, 12);
8372             Rn = Bits32(opcode, 19, 16);
8373             Rm = Bits32(opcode, 3, 0);
8374             setflags = BitIsSet(opcode, 20);
8375             shift_n = DecodeImmShiftARM(opcode, shift_t);
8376 
8377             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8378             if (Rd == 15 && setflags)
8379                 return EmulateSUBSPcLrEtc (opcode, encoding);
8380             break;
8381         default:
8382             return false;
8383         }
8384 
8385         // Read the first operand.
8386         uint32_t val1 = ReadCoreReg(Rn, &success);
8387         if (!success)
8388             return false;
8389 
8390         // Read the second operand.
8391         uint32_t val2 = ReadCoreReg(Rm, &success);
8392         if (!success)
8393             return false;
8394 
8395         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8396         if (!success)
8397             return false;
8398         uint32_t result = val1 ^ shifted;
8399 
8400         EmulateInstruction::Context context;
8401         context.type = EmulateInstruction::eContextImmediate;
8402         context.SetNoArgs ();
8403 
8404         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8405             return false;
8406     }
8407     return true;
8408 }
8409 
8410 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and
8411 // writes the result to the destination register.  It can optionally update the condition flags based
8412 // on the result.
8413 bool
8414 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding)
8415 {
8416 #if 0
8417     // ARM pseudo code...
8418     if ConditionPassed() then
8419         EncodingSpecificOperations();
8420         result = R[n] OR imm32;
8421         if d == 15 then         // Can only occur for ARM encoding
8422             ALUWritePC(result); // setflags is always FALSE here
8423         else
8424             R[d] = result;
8425             if setflags then
8426                 APSR.N = result<31>;
8427                 APSR.Z = IsZeroBit(result);
8428                 APSR.C = carry;
8429                 // APSR.V unchanged
8430 #endif
8431 
8432     bool success = false;
8433 
8434     if (ConditionPassed(opcode))
8435     {
8436         uint32_t Rd, Rn;
8437         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8438         bool setflags;
8439         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8440         switch (encoding)
8441         {
8442         case eEncodingT1:
8443             Rd = Bits32(opcode, 11, 8);
8444             Rn = Bits32(opcode, 19, 16);
8445             setflags = BitIsSet(opcode, 20);
8446             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8447             // if Rn == '1111' then SEE MOV (immediate);
8448             if (Rn == 15)
8449                 return EmulateMOVRdImm (opcode, eEncodingT2);
8450             if (BadReg(Rd) || Rn == 13)
8451                 return false;
8452             break;
8453         case eEncodingA1:
8454             Rd = Bits32(opcode, 15, 12);
8455             Rn = Bits32(opcode, 19, 16);
8456             setflags = BitIsSet(opcode, 20);
8457             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8458 
8459             if (Rd == 15 && setflags)
8460                 return EmulateSUBSPcLrEtc (opcode, encoding);
8461             break;
8462         default:
8463             return false;
8464         }
8465 
8466         // Read the first operand.
8467         uint32_t val1 = ReadCoreReg(Rn, &success);
8468         if (!success)
8469             return false;
8470 
8471         uint32_t result = val1 | imm32;
8472 
8473         EmulateInstruction::Context context;
8474         context.type = EmulateInstruction::eContextImmediate;
8475         context.SetNoArgs ();
8476 
8477         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8478             return false;
8479     }
8480     return true;
8481 }
8482 
8483 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register
8484 // value, and writes the result to the destination register.  It can optionally update the condition flags based
8485 // on the result.
8486 bool
8487 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding)
8488 {
8489 #if 0
8490     // ARM pseudo code...
8491     if ConditionPassed() then
8492         EncodingSpecificOperations();
8493         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8494         result = R[n] OR shifted;
8495         if d == 15 then         // Can only occur for ARM encoding
8496             ALUWritePC(result); // setflags is always FALSE here
8497         else
8498             R[d] = result;
8499             if setflags then
8500                 APSR.N = result<31>;
8501                 APSR.Z = IsZeroBit(result);
8502                 APSR.C = carry;
8503                 // APSR.V unchanged
8504 #endif
8505 
8506     bool success = false;
8507 
8508     if (ConditionPassed(opcode))
8509     {
8510         uint32_t Rd, Rn, Rm;
8511         ARM_ShifterType shift_t;
8512         uint32_t shift_n; // the shift applied to the value read from Rm
8513         bool setflags;
8514         uint32_t carry;
8515         switch (encoding)
8516         {
8517         case eEncodingT1:
8518             Rd = Rn = Bits32(opcode, 2, 0);
8519             Rm = Bits32(opcode, 5, 3);
8520             setflags = !InITBlock();
8521             shift_t = SRType_LSL;
8522             shift_n = 0;
8523             break;
8524         case eEncodingT2:
8525             Rd = Bits32(opcode, 11, 8);
8526             Rn = Bits32(opcode, 19, 16);
8527             Rm = Bits32(opcode, 3, 0);
8528             setflags = BitIsSet(opcode, 20);
8529             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8530             // if Rn == '1111' then SEE MOV (register);
8531             if (Rn == 15)
8532                 return EmulateMOVRdRm (opcode, eEncodingT3);
8533             if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
8534                 return false;
8535             break;
8536         case eEncodingA1:
8537             Rd = Bits32(opcode, 15, 12);
8538             Rn = Bits32(opcode, 19, 16);
8539             Rm = Bits32(opcode, 3, 0);
8540             setflags = BitIsSet(opcode, 20);
8541             shift_n = DecodeImmShiftARM(opcode, shift_t);
8542 
8543             if (Rd == 15 && setflags)
8544                 return EmulateSUBSPcLrEtc (opcode, encoding);
8545             break;
8546         default:
8547             return false;
8548         }
8549 
8550         // Read the first operand.
8551         uint32_t val1 = ReadCoreReg(Rn, &success);
8552         if (!success)
8553             return false;
8554 
8555         // Read the second operand.
8556         uint32_t val2 = ReadCoreReg(Rm, &success);
8557         if (!success)
8558             return false;
8559 
8560         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8561         if (!success)
8562             return false;
8563         uint32_t result = val1 | shifted;
8564 
8565         EmulateInstruction::Context context;
8566         context.type = EmulateInstruction::eContextImmediate;
8567         context.SetNoArgs ();
8568 
8569         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8570             return false;
8571     }
8572     return true;
8573 }
8574 
8575 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to
8576 // the destination register. It can optionally update the condition flags based on the result.
8577 bool
8578 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding)
8579 {
8580 #if 0
8581     // ARM pseudo code...
8582     if ConditionPassed() then
8583         EncodingSpecificOperations();
8584         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
8585         if d == 15 then         // Can only occur for ARM encoding
8586             ALUWritePC(result); // setflags is always FALSE here
8587         else
8588             R[d] = result;
8589             if setflags then
8590                 APSR.N = result<31>;
8591                 APSR.Z = IsZeroBit(result);
8592                 APSR.C = carry;
8593                 APSR.V = overflow;
8594 #endif
8595 
8596     bool success = false;
8597 
8598     uint32_t Rd; // the destination register
8599     uint32_t Rn; // the first operand
8600     bool setflags;
8601     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8602     switch (encoding) {
8603     case eEncodingT1:
8604         Rd = Bits32(opcode, 2, 0);
8605         Rn = Bits32(opcode, 5, 3);
8606         setflags = !InITBlock();
8607         imm32 = 0;
8608         break;
8609     case eEncodingT2:
8610         Rd = Bits32(opcode, 11, 8);
8611         Rn = Bits32(opcode, 19, 16);
8612         setflags = BitIsSet(opcode, 20);
8613         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8614         if (BadReg(Rd) || BadReg(Rn))
8615             return false;
8616         break;
8617     case eEncodingA1:
8618         Rd = Bits32(opcode, 15, 12);
8619         Rn = Bits32(opcode, 19, 16);
8620         setflags = BitIsSet(opcode, 20);
8621         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8622 
8623         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8624         if (Rd == 15 && setflags)
8625             return EmulateSUBSPcLrEtc (opcode, encoding);
8626         break;
8627     default:
8628         return false;
8629     }
8630     // Read the register value from the operand register Rn.
8631     uint32_t reg_val = ReadCoreReg(Rn, &success);
8632     if (!success)
8633         return false;
8634 
8635     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
8636 
8637     EmulateInstruction::Context context;
8638     context.type = EmulateInstruction::eContextImmediate;
8639     context.SetNoArgs ();
8640 
8641     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8642         return false;
8643 
8644     return true;
8645 }
8646 
8647 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the
8648 // result to the destination register. It can optionally update the condition flags based on the result.
8649 bool
8650 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding)
8651 {
8652 #if 0
8653     // ARM pseudo code...
8654     if ConditionPassed() then
8655         EncodingSpecificOperations();
8656         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8657         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
8658         if d == 15 then         // Can only occur for ARM encoding
8659             ALUWritePC(result); // setflags is always FALSE here
8660         else
8661             R[d] = result;
8662             if setflags then
8663                 APSR.N = result<31>;
8664                 APSR.Z = IsZeroBit(result);
8665                 APSR.C = carry;
8666                 APSR.V = overflow;
8667 #endif
8668 
8669     bool success = false;
8670 
8671     uint32_t Rd; // the destination register
8672     uint32_t Rn; // the first operand
8673     uint32_t Rm; // the second operand
8674     bool setflags;
8675     ARM_ShifterType shift_t;
8676     uint32_t shift_n; // the shift applied to the value read from Rm
8677     switch (encoding) {
8678     case eEncodingT1:
8679         Rd = Bits32(opcode, 11, 8);
8680         Rn = Bits32(opcode, 19, 16);
8681         Rm = Bits32(opcode, 3, 0);
8682         setflags = BitIsSet(opcode, 20);
8683         shift_n = DecodeImmShiftThumb(opcode, shift_t);
8684         // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
8685         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8686             return false;
8687         break;
8688     case eEncodingA1:
8689         Rd = Bits32(opcode, 15, 12);
8690         Rn = Bits32(opcode, 19, 16);
8691         Rm = Bits32(opcode, 3, 0);
8692         setflags = BitIsSet(opcode, 20);
8693         shift_n = DecodeImmShiftARM(opcode, shift_t);
8694 
8695         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8696         if (Rd == 15 && setflags)
8697             return EmulateSUBSPcLrEtc (opcode, encoding);
8698         break;
8699     default:
8700         return false;
8701     }
8702     // Read the register value from register Rn.
8703     uint32_t val1 = ReadCoreReg(Rn, &success);
8704     if (!success)
8705         return false;
8706 
8707     // Read the register value from register Rm.
8708     uint32_t val2 = ReadCoreReg(Rm, &success);
8709     if (!success)
8710         return false;
8711 
8712     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8713     if (!success)
8714         return false;
8715     AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
8716 
8717     EmulateInstruction::Context context;
8718     context.type = EmulateInstruction::eContextImmediate;
8719     context.SetNoArgs();
8720     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8721         return false;
8722 
8723     return true;
8724 }
8725 
8726 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from
8727 // an immediate value, and writes the result to the destination register. It can optionally update the condition
8728 // flags based on the result.
8729 bool
8730 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding)
8731 {
8732 #if 0
8733     // ARM pseudo code...
8734     if ConditionPassed() then
8735         EncodingSpecificOperations();
8736         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
8737         if d == 15 then
8738             ALUWritePC(result); // setflags is always FALSE here
8739         else
8740             R[d] = result;
8741             if setflags then
8742                 APSR.N = result<31>;
8743                 APSR.Z = IsZeroBit(result);
8744                 APSR.C = carry;
8745                 APSR.V = overflow;
8746 #endif
8747 
8748     bool success = false;
8749 
8750     uint32_t Rd; // the destination register
8751     uint32_t Rn; // the first operand
8752     bool setflags;
8753     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8754     switch (encoding) {
8755     case eEncodingA1:
8756         Rd = Bits32(opcode, 15, 12);
8757         Rn = Bits32(opcode, 19, 16);
8758         setflags = BitIsSet(opcode, 20);
8759         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8760 
8761         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8762         if (Rd == 15 && setflags)
8763             return EmulateSUBSPcLrEtc  (opcode, encoding);
8764         break;
8765     default:
8766         return false;
8767     }
8768     // Read the register value from the operand register Rn.
8769     uint32_t reg_val = ReadCoreReg(Rn, &success);
8770     if (!success)
8771         return false;
8772 
8773     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
8774 
8775     EmulateInstruction::Context context;
8776     context.type = EmulateInstruction::eContextImmediate;
8777     context.SetNoArgs ();
8778 
8779     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8780         return false;
8781 
8782     return true;
8783 }
8784 
8785 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an
8786 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the
8787 // condition flags based on the result.
8788 bool
8789 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding)
8790 {
8791 #if 0
8792     // ARM pseudo code...
8793     if ConditionPassed() then
8794         EncodingSpecificOperations();
8795         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8796         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
8797         if d == 15 then
8798             ALUWritePC(result); // setflags is always FALSE here
8799         else
8800             R[d] = result;
8801             if setflags then
8802                 APSR.N = result<31>;
8803                 APSR.Z = IsZeroBit(result);
8804                 APSR.C = carry;
8805                 APSR.V = overflow;
8806 #endif
8807 
8808     bool success = false;
8809 
8810     uint32_t Rd; // the destination register
8811     uint32_t Rn; // the first operand
8812     uint32_t Rm; // the second operand
8813     bool setflags;
8814     ARM_ShifterType shift_t;
8815     uint32_t shift_n; // the shift applied to the value read from Rm
8816     switch (encoding) {
8817     case eEncodingA1:
8818         Rd = Bits32(opcode, 15, 12);
8819         Rn = Bits32(opcode, 19, 16);
8820         Rm = Bits32(opcode, 3, 0);
8821         setflags = BitIsSet(opcode, 20);
8822         shift_n = DecodeImmShiftARM(opcode, shift_t);
8823 
8824         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8825         if (Rd == 15 && setflags)
8826             return EmulateSUBSPcLrEtc (opcode, encoding);
8827         break;
8828     default:
8829         return false;
8830     }
8831     // Read the register value from register Rn.
8832     uint32_t val1 = ReadCoreReg(Rn, &success);
8833     if (!success)
8834         return false;
8835 
8836     // Read the register value from register Rm.
8837     uint32_t val2 = ReadCoreReg(Rm, &success);
8838     if (!success)
8839         return false;
8840 
8841     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8842     if (!success)
8843         return false;
8844     AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
8845 
8846     EmulateInstruction::Context context;
8847     context.type = EmulateInstruction::eContextImmediate;
8848     context.SetNoArgs();
8849     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8850         return false;
8851 
8852     return true;
8853 }
8854 
8855 // Subtract with Carry (immediate) subtracts an immediate value and the value of
8856 // NOT (Carry flag) from a register value, and writes the result to the destination register.
8857 // It can optionally update the condition flags based on the result.
8858 bool
8859 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding)
8860 {
8861 #if 0
8862     // ARM pseudo code...
8863     if ConditionPassed() then
8864         EncodingSpecificOperations();
8865         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
8866         if d == 15 then         // Can only occur for ARM encoding
8867             ALUWritePC(result); // setflags is always FALSE here
8868         else
8869             R[d] = result;
8870             if setflags then
8871                 APSR.N = result<31>;
8872                 APSR.Z = IsZeroBit(result);
8873                 APSR.C = carry;
8874                 APSR.V = overflow;
8875 #endif
8876 
8877     bool success = false;
8878 
8879     uint32_t Rd; // the destination register
8880     uint32_t Rn; // the first operand
8881     bool setflags;
8882     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8883     switch (encoding) {
8884     case eEncodingT1:
8885         Rd = Bits32(opcode, 11, 8);
8886         Rn = Bits32(opcode, 19, 16);
8887         setflags = BitIsSet(opcode, 20);
8888         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8889         if (BadReg(Rd) || BadReg(Rn))
8890             return false;
8891         break;
8892     case eEncodingA1:
8893         Rd = Bits32(opcode, 15, 12);
8894         Rn = Bits32(opcode, 19, 16);
8895         setflags = BitIsSet(opcode, 20);
8896         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8897 
8898         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8899         if (Rd == 15 && setflags)
8900             return EmulateSUBSPcLrEtc (opcode, encoding);
8901         break;
8902     default:
8903         return false;
8904     }
8905     // Read the register value from the operand register Rn.
8906     uint32_t reg_val = ReadCoreReg(Rn, &success);
8907     if (!success)
8908         return false;
8909 
8910     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
8911 
8912     EmulateInstruction::Context context;
8913     context.type = EmulateInstruction::eContextImmediate;
8914     context.SetNoArgs ();
8915 
8916     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8917         return false;
8918 
8919     return true;
8920 }
8921 
8922 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of
8923 // NOT (Carry flag) from a register value, and writes the result to the destination register.
8924 // It can optionally update the condition flags based on the result.
8925 bool
8926 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding)
8927 {
8928 #if 0
8929     // ARM pseudo code...
8930     if ConditionPassed() then
8931         EncodingSpecificOperations();
8932         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8933         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
8934         if d == 15 then         // Can only occur for ARM encoding
8935             ALUWritePC(result); // setflags is always FALSE here
8936         else
8937             R[d] = result;
8938             if setflags then
8939                 APSR.N = result<31>;
8940                 APSR.Z = IsZeroBit(result);
8941                 APSR.C = carry;
8942                 APSR.V = overflow;
8943 #endif
8944 
8945     bool success = false;
8946 
8947     uint32_t Rd; // the destination register
8948     uint32_t Rn; // the first operand
8949     uint32_t Rm; // the second operand
8950     bool setflags;
8951     ARM_ShifterType shift_t;
8952     uint32_t shift_n; // the shift applied to the value read from Rm
8953     switch (encoding) {
8954     case eEncodingT1:
8955         Rd = Rn = Bits32(opcode, 2, 0);
8956         Rm = Bits32(opcode, 5, 3);
8957         setflags = !InITBlock();
8958         shift_t = SRType_LSL;
8959         shift_n = 0;
8960         break;
8961     case eEncodingT2:
8962         Rd = Bits32(opcode, 11, 8);
8963         Rn = Bits32(opcode, 19, 16);
8964         Rm = Bits32(opcode, 3, 0);
8965         setflags = BitIsSet(opcode, 20);
8966         shift_n = DecodeImmShiftThumb(opcode, shift_t);
8967         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8968             return false;
8969         break;
8970     case eEncodingA1:
8971         Rd = Bits32(opcode, 15, 12);
8972         Rn = Bits32(opcode, 19, 16);
8973         Rm = Bits32(opcode, 3, 0);
8974         setflags = BitIsSet(opcode, 20);
8975         shift_n = DecodeImmShiftARM(opcode, shift_t);
8976 
8977         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8978         if (Rd == 15 && setflags)
8979             return EmulateSUBSPcLrEtc (opcode, encoding);
8980         break;
8981     default:
8982         return false;
8983     }
8984     // Read the register value from register Rn.
8985     uint32_t val1 = ReadCoreReg(Rn, &success);
8986     if (!success)
8987         return false;
8988 
8989     // Read the register value from register Rm.
8990     uint32_t val2 = ReadCoreReg(Rm, &success);
8991     if (!success)
8992         return false;
8993 
8994     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8995     if (!success)
8996         return false;
8997     AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
8998 
8999     EmulateInstruction::Context context;
9000     context.type = EmulateInstruction::eContextImmediate;
9001     context.SetNoArgs();
9002     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9003         return false;
9004 
9005     return true;
9006 }
9007 
9008 // This instruction subtracts an immediate value from a register value, and writes the result
9009 // to the destination register.  It can optionally update the condition flags based on the result.
9010 bool
9011 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding)
9012 {
9013 #if 0
9014     // ARM pseudo code...
9015     if ConditionPassed() then
9016         EncodingSpecificOperations();
9017         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9018         R[d] = result;
9019         if setflags then
9020             APSR.N = result<31>;
9021             APSR.Z = IsZeroBit(result);
9022             APSR.C = carry;
9023             APSR.V = overflow;
9024 #endif
9025 
9026     bool success = false;
9027 
9028     uint32_t Rd; // the destination register
9029     uint32_t Rn; // the first operand
9030     bool setflags;
9031     uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9032     switch (encoding) {
9033     case eEncodingT1:
9034         Rd = Bits32(opcode, 2, 0);
9035         Rn = Bits32(opcode, 5, 3);
9036         setflags = !InITBlock();
9037         imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9038         break;
9039     case eEncodingT2:
9040         Rd = Rn = Bits32(opcode, 10, 8);
9041         setflags = !InITBlock();
9042         imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9043         break;
9044     case eEncodingT3:
9045         Rd = Bits32(opcode, 11, 8);
9046         Rn = Bits32(opcode, 19, 16);
9047         setflags = BitIsSet(opcode, 20);
9048         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9049 
9050         // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9051         if (Rd == 15 && setflags)
9052             return EmulateCMPImm (opcode, eEncodingT2);
9053 
9054         // if Rn == '1101' then SEE SUB (SP minus immediate);
9055         if (Rn == 13)
9056             return EmulateSUBSPImm (opcode, eEncodingT2);
9057 
9058         // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9059         if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9060             return false;
9061         break;
9062     case eEncodingT4:
9063         Rd = Bits32(opcode, 11, 8);
9064         Rn = Bits32(opcode, 19, 16);
9065         setflags = BitIsSet(opcode, 20);
9066         imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9067 
9068         // if Rn == '1111' then SEE ADR;
9069         if (Rn == 15)
9070             return EmulateADR (opcode, eEncodingT2);
9071 
9072         // if Rn == '1101' then SEE SUB (SP minus immediate);
9073         if (Rn == 13)
9074             return EmulateSUBSPImm (opcode, eEncodingT3);
9075 
9076         if (BadReg(Rd))
9077             return false;
9078         break;
9079     default:
9080         return false;
9081     }
9082     // Read the register value from the operand register Rn.
9083     uint32_t reg_val = ReadCoreReg(Rn, &success);
9084     if (!success)
9085         return false;
9086 
9087     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9088 
9089     EmulateInstruction::Context context;
9090     context.type = EmulateInstruction::eContextImmediate;
9091     context.SetNoArgs ();
9092 
9093     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9094         return false;
9095 
9096     return true;
9097 }
9098 
9099 // This instruction subtracts an immediate value from a register value, and writes the result
9100 // to the destination register.  It can optionally update the condition flags based on the result.
9101 bool
9102 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9103 {
9104 #if 0
9105     // ARM pseudo code...
9106     if ConditionPassed() then
9107         EncodingSpecificOperations();
9108         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9109         if d == 15 then
9110             ALUWritePC(result); // setflags is always FALSE here
9111         else
9112             R[d] = result;
9113             if setflags then
9114                 APSR.N = result<31>;
9115                 APSR.Z = IsZeroBit(result);
9116                 APSR.C = carry;
9117                 APSR.V = overflow;
9118 #endif
9119 
9120     bool success = false;
9121 
9122     uint32_t Rd; // the destination register
9123     uint32_t Rn; // the first operand
9124     bool setflags;
9125     uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9126     switch (encoding) {
9127     case eEncodingA1:
9128         Rd = Bits32(opcode, 15, 12);
9129         Rn = Bits32(opcode, 19, 16);
9130         setflags = BitIsSet(opcode, 20);
9131         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9132 
9133         // if Rn == '1111' && S == '0' then SEE ADR;
9134         if (Rn == 15 && !setflags)
9135             return EmulateADR (opcode, eEncodingA2);
9136 
9137         // if Rn == '1101' then SEE SUB (SP minus immediate);
9138         if (Rn == 13)
9139             return EmulateSUBSPImm (opcode, eEncodingA1);
9140 
9141         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9142         if (Rd == 15 && setflags)
9143             return EmulateSUBSPcLrEtc (opcode, encoding);
9144         break;
9145     default:
9146         return false;
9147     }
9148     // Read the register value from the operand register Rn.
9149     uint32_t reg_val = ReadCoreReg(Rn, &success);
9150     if (!success)
9151         return false;
9152 
9153     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9154 
9155     EmulateInstruction::Context context;
9156     context.type = EmulateInstruction::eContextImmediate;
9157     context.SetNoArgs ();
9158 
9159     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9160         return false;
9161 
9162     return true;
9163 }
9164 
9165 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an
9166 // immediate value.  It updates the condition flags based on the result, and discards the result.
9167 bool
9168 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding)
9169 {
9170 #if 0
9171     // ARM pseudo code...
9172     if ConditionPassed() then
9173         EncodingSpecificOperations();
9174         result = R[n] EOR imm32;
9175         APSR.N = result<31>;
9176         APSR.Z = IsZeroBit(result);
9177         APSR.C = carry;
9178         // APSR.V unchanged
9179 #endif
9180 
9181     bool success = false;
9182 
9183     if (ConditionPassed(opcode))
9184     {
9185         uint32_t Rn;
9186         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9187         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9188         switch (encoding)
9189         {
9190         case eEncodingT1:
9191             Rn = Bits32(opcode, 19, 16);
9192             imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9193             if (BadReg(Rn))
9194                 return false;
9195             break;
9196         case eEncodingA1:
9197             Rn = Bits32(opcode, 19, 16);
9198             imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9199             break;
9200         default:
9201             return false;
9202         }
9203 
9204         // Read the first operand.
9205         uint32_t val1 = ReadCoreReg(Rn, &success);
9206         if (!success)
9207             return false;
9208 
9209         uint32_t result = val1 ^ imm32;
9210 
9211         EmulateInstruction::Context context;
9212         context.type = EmulateInstruction::eContextImmediate;
9213         context.SetNoArgs ();
9214 
9215         if (!WriteFlags(context, result, carry))
9216             return false;
9217     }
9218     return true;
9219 }
9220 
9221 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an
9222 // optionally-shifted register value.  It updates the condition flags based on the result, and discards
9223 // the result.
9224 bool
9225 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding)
9226 {
9227 #if 0
9228     // ARM pseudo code...
9229     if ConditionPassed() then
9230         EncodingSpecificOperations();
9231         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9232         result = R[n] EOR shifted;
9233         APSR.N = result<31>;
9234         APSR.Z = IsZeroBit(result);
9235         APSR.C = carry;
9236         // APSR.V unchanged
9237 #endif
9238 
9239     bool success = false;
9240 
9241     if (ConditionPassed(opcode))
9242     {
9243         uint32_t Rn, Rm;
9244         ARM_ShifterType shift_t;
9245         uint32_t shift_n; // the shift applied to the value read from Rm
9246         uint32_t carry;
9247         switch (encoding)
9248         {
9249         case eEncodingT1:
9250             Rn = Bits32(opcode, 19, 16);
9251             Rm = Bits32(opcode, 3, 0);
9252             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9253             if (BadReg(Rn) || BadReg(Rm))
9254                 return false;
9255             break;
9256         case eEncodingA1:
9257             Rn = Bits32(opcode, 19, 16);
9258             Rm = Bits32(opcode, 3, 0);
9259             shift_n = DecodeImmShiftARM(opcode, shift_t);
9260             break;
9261         default:
9262             return false;
9263         }
9264 
9265         // Read the first operand.
9266         uint32_t val1 = ReadCoreReg(Rn, &success);
9267         if (!success)
9268             return false;
9269 
9270         // Read the second operand.
9271         uint32_t val2 = ReadCoreReg(Rm, &success);
9272         if (!success)
9273             return false;
9274 
9275         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9276         if (!success)
9277             return false;
9278         uint32_t result = val1 ^ shifted;
9279 
9280         EmulateInstruction::Context context;
9281         context.type = EmulateInstruction::eContextImmediate;
9282         context.SetNoArgs ();
9283 
9284         if (!WriteFlags(context, result, carry))
9285             return false;
9286     }
9287     return true;
9288 }
9289 
9290 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value.
9291 // It updates the condition flags based on the result, and discards the result.
9292 bool
9293 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding)
9294 {
9295 #if 0
9296     // ARM pseudo code...
9297     if ConditionPassed() then
9298         EncodingSpecificOperations();
9299         result = R[n] AND imm32;
9300         APSR.N = result<31>;
9301         APSR.Z = IsZeroBit(result);
9302         APSR.C = carry;
9303         // APSR.V unchanged
9304 #endif
9305 
9306     bool success = false;
9307 
9308     if (ConditionPassed(opcode))
9309     {
9310         uint32_t Rn;
9311         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9312         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9313         switch (encoding)
9314         {
9315         case eEncodingT1:
9316             Rn = Bits32(opcode, 19, 16);
9317             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9318             if (BadReg(Rn))
9319                 return false;
9320             break;
9321         case eEncodingA1:
9322             Rn = Bits32(opcode, 19, 16);
9323             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9324             break;
9325         default:
9326             return false;
9327         }
9328 
9329         // Read the first operand.
9330         uint32_t val1 = ReadCoreReg(Rn, &success);
9331         if (!success)
9332             return false;
9333 
9334         uint32_t result = val1 & imm32;
9335 
9336         EmulateInstruction::Context context;
9337         context.type = EmulateInstruction::eContextImmediate;
9338         context.SetNoArgs ();
9339 
9340         if (!WriteFlags(context, result, carry))
9341             return false;
9342     }
9343     return true;
9344 }
9345 
9346 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value.
9347 // It updates the condition flags based on the result, and discards the result.
9348 bool
9349 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding)
9350 {
9351 #if 0
9352     // ARM pseudo code...
9353     if ConditionPassed() then
9354         EncodingSpecificOperations();
9355         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9356         result = R[n] AND shifted;
9357         APSR.N = result<31>;
9358         APSR.Z = IsZeroBit(result);
9359         APSR.C = carry;
9360         // APSR.V unchanged
9361 #endif
9362 
9363     bool success = false;
9364 
9365     if (ConditionPassed(opcode))
9366     {
9367         uint32_t Rn, Rm;
9368         ARM_ShifterType shift_t;
9369         uint32_t shift_n; // the shift applied to the value read from Rm
9370         uint32_t carry;
9371         switch (encoding)
9372         {
9373         case eEncodingT1:
9374             Rn = Bits32(opcode, 2, 0);
9375             Rm = Bits32(opcode, 5, 3);
9376             shift_t = SRType_LSL;
9377             shift_n = 0;
9378             break;
9379         case eEncodingT2:
9380             Rn = Bits32(opcode, 19, 16);
9381             Rm = Bits32(opcode, 3, 0);
9382             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9383             if (BadReg(Rn) || BadReg(Rm))
9384                 return false;
9385             break;
9386         case eEncodingA1:
9387             Rn = Bits32(opcode, 19, 16);
9388             Rm = Bits32(opcode, 3, 0);
9389             shift_n = DecodeImmShiftARM(opcode, shift_t);
9390             break;
9391         default:
9392             return false;
9393         }
9394 
9395         // Read the first operand.
9396         uint32_t val1 = ReadCoreReg(Rn, &success);
9397         if (!success)
9398             return false;
9399 
9400         // Read the second operand.
9401         uint32_t val2 = ReadCoreReg(Rm, &success);
9402         if (!success)
9403             return false;
9404 
9405         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9406         if (!success)
9407             return false;
9408         uint32_t result = val1 & shifted;
9409 
9410         EmulateInstruction::Context context;
9411         context.type = EmulateInstruction::eContextImmediate;
9412         context.SetNoArgs ();
9413 
9414         if (!WriteFlags(context, result, carry))
9415             return false;
9416     }
9417     return true;
9418 }
9419 
9420 // A8.6.216 SUB (SP minus register)
9421 bool
9422 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding)
9423 {
9424 #if 0
9425     if ConditionPassed() then
9426         EncodingSpecificOperations();
9427         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9428         (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9429         if d == 15 then // Can only occur for ARM encoding
9430             ALUWritePC(result); // setflags is always FALSE here
9431         else
9432             R[d] = result;
9433             if setflags then
9434                 APSR.N = result<31>;
9435                 APSR.Z = IsZeroBit(result);
9436                 APSR.C = carry;
9437                 APSR.V = overflow;
9438 #endif
9439 
9440     bool success = false;
9441 
9442     if (ConditionPassed(opcode))
9443     {
9444         uint32_t d;
9445         uint32_t m;
9446         bool setflags;
9447         ARM_ShifterType shift_t;
9448         uint32_t shift_n;
9449 
9450         switch (encoding)
9451         {
9452             case eEncodingT1:
9453                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9454                 d = Bits32 (opcode, 11, 8);
9455                 m = Bits32 (opcode, 3, 0);
9456                 setflags = BitIsSet (opcode, 20);
9457 
9458                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9459                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9460 
9461                 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE;
9462                 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
9463                     return false;
9464 
9465                 // if d == 15 || BadReg(m) then UNPREDICTABLE;
9466                 if ((d == 15) || BadReg (m))
9467                     return false;
9468                 break;
9469 
9470             case eEncodingA1:
9471                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9472                 d = Bits32 (opcode, 15, 12);
9473                 m = Bits32 (opcode, 3, 0);
9474                 setflags = BitIsSet (opcode, 20);
9475 
9476                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9477                 if (d == 15 && setflags)
9478                     EmulateSUBSPcLrEtc (opcode, encoding);
9479 
9480                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9481                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9482                 break;
9483 
9484             default:
9485                 return false;
9486         }
9487 
9488         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9489         uint32_t Rm = ReadCoreReg (m, &success);
9490         if (!success)
9491             return false;
9492 
9493         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9494         if (!success)
9495             return false;
9496 
9497         // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9498         uint32_t sp_val = ReadCoreReg (SP_REG, &success);
9499         if (!success)
9500             return false;
9501 
9502         AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1);
9503 
9504         EmulateInstruction::Context context;
9505         context.type = eContextArithmetic;
9506         RegisterInfo sp_reg;
9507         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
9508         RegisterInfo dwarf_reg;
9509         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
9510         context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
9511 
9512         if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9513             return false;
9514     }
9515     return true;
9516 }
9517 
9518 
9519 // A8.6.7 ADD (register-shifted register)
9520 bool
9521 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding)
9522 {
9523 #if 0
9524     if ConditionPassed() then
9525         EncodingSpecificOperations();
9526         shift_n = UInt(R[s]<7:0>);
9527         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9528         (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9529         R[d] = result;
9530         if setflags then
9531             APSR.N = result<31>;
9532             APSR.Z = IsZeroBit(result);
9533             APSR.C = carry;
9534             APSR.V = overflow;
9535 #endif
9536 
9537     bool success = false;
9538 
9539     if (ConditionPassed(opcode))
9540     {
9541         uint32_t d;
9542         uint32_t n;
9543         uint32_t m;
9544         uint32_t s;
9545         bool setflags;
9546         ARM_ShifterType shift_t;
9547 
9548         switch (encoding)
9549         {
9550             case eEncodingA1:
9551                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
9552                 d = Bits32 (opcode, 15, 12);
9553                 n = Bits32 (opcode, 19, 16);
9554                 m = Bits32 (opcode, 3, 0);
9555                 s = Bits32 (opcode, 11, 8);
9556 
9557                 // setflags = (S == �1�); shift_t = DecodeRegShift(type);
9558                 setflags = BitIsSet (opcode, 20);
9559                 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5));
9560 
9561                 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
9562                 if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
9563                     return false;
9564                 break;
9565 
9566             default:
9567                 return false;
9568         }
9569 
9570         // shift_n = UInt(R[s]<7:0>);
9571         uint32_t Rs = ReadCoreReg (s, &success);
9572         if (!success)
9573             return false;
9574 
9575         uint32_t shift_n = Bits32 (Rs, 7, 0);
9576 
9577         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9578         uint32_t Rm = ReadCoreReg (m, &success);
9579         if (!success)
9580             return false;
9581 
9582         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9583         if (!success)
9584             return false;
9585 
9586         // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9587         uint32_t Rn = ReadCoreReg (n, &success);
9588         if (!success)
9589             return false;
9590 
9591         AddWithCarryResult res = AddWithCarry (Rn, shifted, 0);
9592 
9593         // R[d] = result;
9594         EmulateInstruction::Context context;
9595         context.type = eContextArithmetic;
9596         RegisterInfo reg_n;
9597         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9598         RegisterInfo reg_m;
9599         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9600 
9601         context.SetRegisterRegisterOperands (reg_n, reg_m);
9602 
9603         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result))
9604             return false;
9605 
9606         // if setflags then
9607             // APSR.N = result<31>;
9608             // APSR.Z = IsZeroBit(result);
9609             // APSR.C = carry;
9610             // APSR.V = overflow;
9611         if (setflags)
9612             return WriteFlags (context, res.result, res.carry_out, res.overflow);
9613     }
9614     return true;
9615 }
9616 
9617 // A8.6.213 SUB (register)
9618 bool
9619 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding)
9620 {
9621 #if 0
9622     if ConditionPassed() then
9623         EncodingSpecificOperations();
9624         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9625         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9626         if d == 15 then // Can only occur for ARM encoding
9627             ALUWritePC(result); // setflags is always FALSE here
9628         else
9629             R[d] = result;
9630             if setflags then
9631                 APSR.N = result<31>;
9632                 APSR.Z = IsZeroBit(result);
9633                 APSR.C = carry;
9634                 APSR.V = overflow;
9635 #endif
9636 
9637     bool success = false;
9638 
9639     if (ConditionPassed(opcode))
9640     {
9641         uint32_t d;
9642         uint32_t n;
9643         uint32_t m;
9644         bool setflags;
9645         ARM_ShifterType shift_t;
9646         uint32_t shift_n;
9647 
9648         switch (encoding)
9649         {
9650             case eEncodingT1:
9651                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
9652                 d = Bits32 (opcode, 2, 0);
9653                 n = Bits32 (opcode, 5, 3);
9654                 m = Bits32 (opcode, 8, 6);
9655                 setflags = !InITBlock();
9656 
9657                 // (shift_t, shift_n) = (SRType_LSL, 0);
9658                 shift_t = SRType_LSL;
9659                 shift_n = 0;
9660 
9661                 break;
9662 
9663             case eEncodingT2:
9664                 // if Rd == �1111� && S == �1� then SEE CMP (register);
9665                 // if Rn == �1101� then SEE SUB (SP minus register);
9666                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9667                 d = Bits32 (opcode, 11, 8);
9668                 n = Bits32 (opcode, 19, 16);
9669                 m = Bits32 (opcode, 3, 0);
9670                 setflags = BitIsSet (opcode, 20);
9671 
9672                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9673                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9674 
9675                 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE;
9676                 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m))
9677                     return false;
9678 
9679                 break;
9680 
9681             case eEncodingA1:
9682                 // if Rn == �1101� then SEE SUB (SP minus register);
9683                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9684                 d = Bits32 (opcode, 15, 12);
9685                 n = Bits32 (opcode, 19, 16);
9686                 m = Bits32 (opcode, 3, 0);
9687                 setflags = BitIsSet (opcode, 20);
9688 
9689                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9690                 if ((d == 15) && setflags)
9691                     EmulateSUBSPcLrEtc (opcode, encoding);
9692 
9693                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9694                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9695 
9696                 break;
9697 
9698             default:
9699                 return false;
9700         }
9701 
9702         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9703         uint32_t Rm = ReadCoreReg (m, &success);
9704         if (!success)
9705             return false;
9706 
9707         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9708         if (!success)
9709             return false;
9710 
9711         // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9712         uint32_t Rn = ReadCoreReg (n, &success);
9713         if (!success)
9714             return false;
9715 
9716         AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1);
9717 
9718         // if d == 15 then // Can only occur for ARM encoding
9719             // ALUWritePC(result); // setflags is always FALSE here
9720         // else
9721             // R[d] = result;
9722             // if setflags then
9723                 // APSR.N = result<31>;
9724                 // APSR.Z = IsZeroBit(result);
9725                 // APSR.C = carry;
9726                 // APSR.V = overflow;
9727 
9728         EmulateInstruction::Context context;
9729         context.type = eContextArithmetic;
9730         RegisterInfo reg_n;
9731         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9732         RegisterInfo reg_m;
9733         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9734         context.SetRegisterRegisterOperands (reg_n, reg_m);
9735 
9736         if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9737             return false;
9738     }
9739     return true;
9740 }
9741 
9742 // A8.6.202 STREX
9743 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a
9744 // word from a register to memory if the executing processor has exclusive access to the memory addressed.
9745 bool
9746 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding)
9747 {
9748 #if 0
9749     if ConditionPassed() then
9750         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9751         address = R[n] + imm32;
9752         if ExclusiveMonitorsPass(address,4) then
9753             MemA[address,4] = R[t];
9754             R[d] = 0;
9755         else
9756             R[d] = 1;
9757 #endif
9758 
9759     bool success = false;
9760 
9761     if (ConditionPassed(opcode))
9762     {
9763         uint32_t d;
9764         uint32_t t;
9765         uint32_t n;
9766         uint32_t imm32;
9767         const uint32_t addr_byte_size = GetAddressByteSize();
9768 
9769         switch (encoding)
9770         {
9771             case eEncodingT1:
9772                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
9773                 d = Bits32 (opcode, 11, 8);
9774                 t = Bits32 (opcode, 15, 12);
9775                 n = Bits32 (opcode, 19, 16);
9776                 imm32 = Bits32 (opcode, 7, 0) << 2;
9777 
9778                 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
9779                 if (BadReg (d) || BadReg (t) || (n == 15))
9780                   return false;
9781 
9782                 // if d == n || d == t then UNPREDICTABLE;
9783                 if ((d == n) || (d == t))
9784                   return false;
9785 
9786                 break;
9787 
9788             case eEncodingA1:
9789                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset
9790                 d = Bits32 (opcode, 15, 12);
9791                 t = Bits32 (opcode, 3, 0);
9792                 n = Bits32 (opcode, 19, 16);
9793                 imm32 = 0;
9794 
9795                 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
9796                 if ((d == 15) || (t == 15) || (n == 15))
9797                     return false;
9798 
9799                 // if d == n || d == t then UNPREDICTABLE;
9800                 if ((d == n) || (d == t))
9801                     return false;
9802 
9803                 break;
9804 
9805             default:
9806                 return false;
9807         }
9808 
9809         // address = R[n] + imm32;
9810         uint32_t Rn = ReadCoreReg (n, &success);
9811         if (!success)
9812             return false;
9813 
9814         addr_t address = Rn + imm32;
9815 
9816         RegisterInfo base_reg;
9817         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9818         RegisterInfo data_reg;
9819         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9820         EmulateInstruction::Context context;
9821         context.type = eContextRegisterStore;
9822         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32);
9823 
9824         // if ExclusiveMonitorsPass(address,4) then
9825         // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this
9826         //                                                         always return true.
9827         if (true)
9828         {
9829             // MemA[address,4] = R[t];
9830             uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
9831             if (!success)
9832                 return false;
9833 
9834             if (!MemAWrite (context, address, Rt, addr_byte_size))
9835                 return false;
9836 
9837             // R[d] = 0;
9838             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0))
9839                 return false;
9840         }
9841         else
9842         {
9843             // R[d] = 1;
9844             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
9845                 return false;
9846         }
9847     }
9848     return true;
9849 }
9850 
9851 // A8.6.197 STRB (immediate, ARM)
9852 bool
9853 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9854 {
9855 #if 0
9856     if ConditionPassed() then
9857         EncodingSpecificOperations();
9858         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9859         address = if index then offset_addr else R[n];
9860         MemU[address,1] = R[t]<7:0>;
9861         if wback then R[n] = offset_addr;
9862 #endif
9863 
9864     bool success = false;
9865 
9866     if (ConditionPassed(opcode))
9867     {
9868         uint32_t t;
9869         uint32_t n;
9870         uint32_t imm32;
9871         bool index;
9872         bool add;
9873         bool wback;
9874 
9875         switch (encoding)
9876         {
9877             case eEncodingA1:
9878                 // if P == �0� && W == �1� then SEE STRBT;
9879                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9880                 t = Bits32 (opcode, 15, 12);
9881                 n = Bits32 (opcode, 19, 16);
9882                 imm32 = Bits32 (opcode, 11, 0);
9883 
9884                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9885                 index = BitIsSet (opcode, 24);
9886                 add = BitIsSet (opcode, 23);
9887                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9888 
9889                 // if t == 15 then UNPREDICTABLE;
9890                 if (t == 15)
9891                     return false;
9892 
9893                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9894                 if (wback && ((n == 15) || (n == t)))
9895                     return false;
9896 
9897                 break;
9898 
9899             default:
9900                 return false;
9901         }
9902 
9903         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9904         uint32_t Rn = ReadCoreReg (n, &success);
9905         if (!success)
9906             return false;
9907 
9908         addr_t offset_addr;
9909         if (add)
9910             offset_addr = Rn + imm32;
9911         else
9912             offset_addr = Rn - imm32;
9913 
9914         // address = if index then offset_addr else R[n];
9915         addr_t address;
9916         if (index)
9917             address = offset_addr;
9918         else
9919             address = Rn;
9920 
9921         // MemU[address,1] = R[t]<7:0>;
9922         uint32_t Rt = ReadCoreReg (t, &success);
9923         if (!success)
9924             return false;
9925 
9926         RegisterInfo base_reg;
9927         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9928         RegisterInfo data_reg;
9929         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9930         EmulateInstruction::Context context;
9931         context.type = eContextRegisterStore;
9932         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
9933 
9934         if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1))
9935             return false;
9936 
9937         // if wback then R[n] = offset_addr;
9938         if (wback)
9939         {
9940             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
9941                 return false;
9942         }
9943     }
9944     return true;
9945 }
9946 
9947 // A8.6.194 STR (immediate, ARM)
9948 bool
9949 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding)
9950 {
9951 #if 0
9952     if ConditionPassed() then
9953         EncodingSpecificOperations();
9954         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9955         address = if index then offset_addr else R[n];
9956         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
9957         if wback then R[n] = offset_addr;
9958 #endif
9959 
9960     bool success = false;
9961 
9962     if (ConditionPassed(opcode))
9963     {
9964         uint32_t t;
9965         uint32_t n;
9966         uint32_t imm32;
9967         bool index;
9968         bool add;
9969         bool wback;
9970 
9971         const uint32_t addr_byte_size = GetAddressByteSize();
9972 
9973         switch (encoding)
9974         {
9975             case eEncodingA1:
9976                 // if P == �0� && W == �1� then SEE STRT;
9977                 // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH;
9978                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9979                 t = Bits32 (opcode, 15, 12);
9980                 n = Bits32 (opcode, 19, 16);
9981                 imm32 = Bits32 (opcode, 11, 0);
9982 
9983                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9984                 index = BitIsSet (opcode, 24);
9985                 add = BitIsSet (opcode, 23);
9986                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9987 
9988                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9989                 if (wback && ((n == 15) || (n == t)))
9990                     return false;
9991 
9992                 break;
9993 
9994             default:
9995                 return false;
9996         }
9997 
9998         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9999         uint32_t Rn = ReadCoreReg (n, &success);
10000         if (!success)
10001             return false;
10002 
10003         addr_t offset_addr;
10004         if (add)
10005             offset_addr = Rn + imm32;
10006         else
10007             offset_addr = Rn - imm32;
10008 
10009         // address = if index then offset_addr else R[n];
10010         addr_t address;
10011         if (index)
10012             address = offset_addr;
10013         else
10014             address = Rn;
10015 
10016         RegisterInfo base_reg;
10017         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10018         RegisterInfo data_reg;
10019         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10020         EmulateInstruction::Context context;
10021         context.type = eContextRegisterStore;
10022         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10023 
10024         // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10025         uint32_t Rt = ReadCoreReg (t, &success);
10026         if (!success)
10027             return false;
10028 
10029         if (t == 15)
10030         {
10031             uint32_t pc_value = ReadCoreReg (PC_REG, &success);
10032             if (!success)
10033                 return false;
10034 
10035             if (!MemUWrite (context, address, pc_value, addr_byte_size))
10036                 return false;
10037         }
10038         else
10039         {
10040             if (!MemUWrite (context, address, Rt, addr_byte_size))
10041                   return false;
10042         }
10043 
10044         // if wback then R[n] = offset_addr;
10045         if (wback)
10046         {
10047             context.type = eContextAdjustBaseRegister;
10048             context.SetImmediate (offset_addr);
10049 
10050             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10051                 return false;
10052         }
10053     }
10054     return true;
10055 }
10056 
10057 // A8.6.66 LDRD (immediate)
10058 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two
10059 // words from memory, and writes them to two registers.  It can use offset, post-indexed, or pre-indexed addressing.
10060 bool
10061 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding)
10062 {
10063 #if 0
10064     if ConditionPassed() then
10065         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10066         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10067         address = if index then offset_addr else R[n];
10068         R[t] = MemA[address,4];
10069         R[t2] = MemA[address+4,4];
10070         if wback then R[n] = offset_addr;
10071 #endif
10072 
10073     bool success = false;
10074 
10075     if (ConditionPassed(opcode))
10076     {
10077         uint32_t t;
10078         uint32_t t2;
10079         uint32_t n;
10080         uint32_t imm32;
10081         bool index;
10082         bool add;
10083         bool wback;
10084 
10085         switch (encoding)
10086         {
10087             case eEncodingT1:
10088                 //if P == �0� && W == �0� then SEE �Related encodings�;
10089                 //if Rn == �1111� then SEE LDRD (literal);
10090                 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10091                 t = Bits32 (opcode, 15, 12);
10092                 t2 = Bits32 (opcode, 11, 8);
10093                 n = Bits32 (opcode, 19, 16);
10094                 imm32 = Bits32 (opcode, 7, 0) << 2;
10095 
10096                 //index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10097                 index = BitIsSet (opcode, 24);
10098                 add = BitIsSet (opcode, 23);
10099                 wback = BitIsSet (opcode, 21);
10100 
10101                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10102                 if (wback && ((n == t) || (n == t2)))
10103                     return false;
10104 
10105                 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10106                 if (BadReg (t) || BadReg (t2) || (t == t2))
10107                     return false;
10108 
10109                 break;
10110 
10111             case eEncodingA1:
10112                 //if Rn == �1111� then SEE LDRD (literal);
10113                 //if Rt<0> == �1� then UNPREDICTABLE;
10114                 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10115                 t = Bits32 (opcode, 15, 12);
10116                 if (BitIsSet (t, 0))
10117                     return false;
10118                 t2 = t + 1;
10119                 n = Bits32 (opcode, 19, 16);
10120                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10121 
10122                 //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10123                 index = BitIsSet (opcode, 24);
10124                 add = BitIsSet (opcode, 23);
10125                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10126 
10127                 //if P == �0� && W == �1� then UNPREDICTABLE;
10128                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10129                     return false;
10130 
10131                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10132                 if (wback && ((n == t) || (n == t2)))
10133                     return false;
10134 
10135                 //if t2 == 15 then UNPREDICTABLE;
10136                 if (t2 == 15)
10137                     return false;
10138 
10139                 break;
10140 
10141             default:
10142                 return false;
10143         }
10144 
10145         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10146         uint32_t Rn = ReadCoreReg (n, &success);
10147         if (!success)
10148             return false;
10149 
10150         addr_t offset_addr;
10151         if (add)
10152                   offset_addr = Rn + imm32;
10153         else
10154             offset_addr = Rn - imm32;
10155 
10156         //address = if index then offset_addr else R[n];
10157         addr_t address;
10158         if (index)
10159             address = offset_addr;
10160         else
10161             address = Rn;
10162 
10163         //R[t] = MemA[address,4];
10164         RegisterInfo base_reg;
10165         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10166 
10167         EmulateInstruction::Context context;
10168         context.type = eContextRegisterLoad;
10169         context.SetRegisterPlusOffset (base_reg, address - Rn);
10170 
10171         const uint32_t addr_byte_size = GetAddressByteSize();
10172         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10173         if (!success)
10174             return false;
10175 
10176         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10177             return false;
10178 
10179         //R[t2] = MemA[address+4,4];
10180 
10181         context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10182         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10183         if (!success)
10184             return false;
10185 
10186         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10187             return false;
10188 
10189         //if wback then R[n] = offset_addr;
10190         if (wback)
10191         {
10192             context.type = eContextAdjustBaseRegister;
10193             context.SetAddress (offset_addr);
10194 
10195             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10196                 return false;
10197         }
10198     }
10199     return true;
10200 }
10201 
10202 // A8.6.68 LDRD (register)
10203 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two
10204 // words from memory, and writes them to two registers.  It can use offset, post-indexed or pre-indexed addressing.
10205 bool
10206 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding)
10207 {
10208 #if 0
10209     if ConditionPassed() then
10210         EncodingSpecificOperations();
10211         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10212         address = if index then offset_addr else R[n];
10213         R[t] = MemA[address,4];
10214         R[t2] = MemA[address+4,4];
10215         if wback then R[n] = offset_addr;
10216 #endif
10217 
10218     bool success = false;
10219 
10220     if (ConditionPassed(opcode))
10221     {
10222         uint32_t t;
10223         uint32_t t2;
10224         uint32_t n;
10225         uint32_t m;
10226         bool index;
10227         bool add;
10228         bool wback;
10229 
10230         switch (encoding)
10231         {
10232             case eEncodingA1:
10233                 // if Rt<0> == �1� then UNPREDICTABLE;
10234                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10235                 t = Bits32 (opcode, 15, 12);
10236                 if (BitIsSet (t, 0))
10237                     return false;
10238                 t2 = t + 1;
10239                 n = Bits32 (opcode, 19, 16);
10240                 m = Bits32 (opcode, 3, 0);
10241 
10242                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10243                 index = BitIsSet (opcode, 24);
10244                 add = BitIsSet (opcode, 23);
10245                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10246 
10247                 // if P == �0� && W == �1� then UNPREDICTABLE;
10248                   if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10249                   return false;
10250 
10251                 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10252                   if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10253                   return false;
10254 
10255                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10256                   if (wback && ((n == 15) || (n == t) || (n == t2)))
10257                   return false;
10258 
10259                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10260                 if ((ArchVersion() < 6) && wback && (m == n))
10261                   return false;
10262                 break;
10263 
10264             default:
10265                 return false;
10266         }
10267 
10268         uint32_t Rn = ReadCoreReg (n, &success);
10269         if (!success)
10270             return false;
10271         RegisterInfo base_reg;
10272         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10273 
10274         uint32_t Rm = ReadCoreReg (m, &success);
10275         if (!success)
10276             return false;
10277         RegisterInfo offset_reg;
10278         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10279 
10280         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10281         addr_t offset_addr;
10282         if (add)
10283             offset_addr = Rn + Rm;
10284         else
10285             offset_addr = Rn - Rm;
10286 
10287         // address = if index then offset_addr else R[n];
10288         addr_t address;
10289         if (index)
10290             address = offset_addr;
10291         else
10292             address = Rn;
10293 
10294         EmulateInstruction::Context context;
10295         context.type = eContextRegisterLoad;
10296         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
10297 
10298         // R[t] = MemA[address,4];
10299         const uint32_t addr_byte_size = GetAddressByteSize();
10300         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10301         if (!success)
10302             return false;
10303 
10304         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10305             return false;
10306 
10307         // R[t2] = MemA[address+4,4];
10308 
10309         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10310         if (!success)
10311             return false;
10312 
10313         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10314             return false;
10315 
10316         // if wback then R[n] = offset_addr;
10317         if (wback)
10318         {
10319             context.type = eContextAdjustBaseRegister;
10320             context.SetAddress (offset_addr);
10321 
10322             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10323                 return false;
10324         }
10325     }
10326     return true;
10327 }
10328 
10329 // A8.6.200 STRD (immediate)
10330 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and
10331 // stores two words from two registers to memory.  It can use offset, post-indexed, or pre-indexed addressing.
10332 bool
10333 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding)
10334 {
10335 #if 0
10336     if ConditionPassed() then
10337         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10338         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10339         address = if index then offset_addr else R[n];
10340         MemA[address,4] = R[t];
10341         MemA[address+4,4] = R[t2];
10342         if wback then R[n] = offset_addr;
10343 #endif
10344 
10345     bool success = false;
10346 
10347     if (ConditionPassed(opcode))
10348     {
10349         uint32_t t;
10350         uint32_t t2;
10351         uint32_t n;
10352         uint32_t imm32;
10353         bool index;
10354         bool add;
10355         bool wback;
10356 
10357         switch (encoding)
10358         {
10359             case eEncodingT1:
10360                 // if P == �0� && W == �0� then SEE �Related encodings�;
10361                 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10362                 t = Bits32 (opcode, 15, 12);
10363                 t2 = Bits32 (opcode, 11, 8);
10364                 n = Bits32 (opcode, 19, 16);
10365                 imm32 = Bits32 (opcode, 7, 0) << 2;
10366 
10367                 // index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10368                 index = BitIsSet (opcode, 24);
10369                 add = BitIsSet (opcode, 23);
10370                 wback = BitIsSet (opcode, 21);
10371 
10372                 // if wback && (n == t || n == t2) then UNPREDICTABLE;
10373                 if (wback && ((n == t) || (n == t2)))
10374                     return false;
10375 
10376                 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10377                 if ((n == 15) || BadReg (t) || BadReg (t2))
10378                     return false;
10379 
10380                 break;
10381 
10382             case eEncodingA1:
10383                 // if Rt<0> == �1� then UNPREDICTABLE;
10384                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10385                 t = Bits32 (opcode, 15, 12);
10386                 if (BitIsSet (t, 0))
10387                     return false;
10388 
10389                 t2 = t + 1;
10390                 n = Bits32 (opcode, 19, 16);
10391                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10392 
10393                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10394                 index = BitIsSet (opcode, 24);
10395                 add = BitIsSet (opcode, 23);
10396                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10397 
10398                 // if P == �0� && W == �1� then UNPREDICTABLE;
10399                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10400                     return false;
10401 
10402                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10403                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10404                     return false;
10405 
10406                 // if t2 == 15 then UNPREDICTABLE;
10407                 if (t2 == 15)
10408                     return false;
10409 
10410                 break;
10411 
10412             default:
10413                 return false;
10414         }
10415 
10416         RegisterInfo base_reg;
10417         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10418 
10419         uint32_t Rn = ReadCoreReg (n, &success);
10420         if (!success)
10421             return false;
10422 
10423         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10424         addr_t offset_addr;
10425         if (add)
10426             offset_addr = Rn + imm32;
10427         else
10428             offset_addr = Rn - imm32;
10429 
10430         //address = if index then offset_addr else R[n];
10431         addr_t address;
10432         if (index)
10433             address = offset_addr;
10434         else
10435             address = Rn;
10436 
10437         //MemA[address,4] = R[t];
10438         RegisterInfo data_reg;
10439         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10440 
10441         uint32_t data = ReadCoreReg (t, &success);
10442         if (!success)
10443             return false;
10444 
10445         EmulateInstruction::Context context;
10446         context.type = eContextRegisterStore;
10447         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10448 
10449         const uint32_t addr_byte_size = GetAddressByteSize();
10450 
10451         if (!MemAWrite (context, address, data, addr_byte_size))
10452             return false;
10453 
10454         //MemA[address+4,4] = R[t2];
10455         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10456         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10457 
10458         data = ReadCoreReg (t2, &success);
10459         if (!success)
10460             return false;
10461 
10462         if (!MemAWrite (context, address + 4, data, addr_byte_size))
10463             return false;
10464 
10465         //if wback then R[n] = offset_addr;
10466         if (wback)
10467         {
10468             context.type = eContextAdjustBaseRegister;
10469             context.SetAddress (offset_addr);
10470 
10471             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10472                 return false;
10473         }
10474     }
10475     return true;
10476 }
10477 
10478 
10479 // A8.6.201 STRD (register)
10480 bool
10481 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding)
10482 {
10483 #if 0
10484     if ConditionPassed() then
10485         EncodingSpecificOperations();
10486         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10487         address = if index then offset_addr else R[n];
10488         MemA[address,4] = R[t];
10489         MemA[address+4,4] = R[t2];
10490         if wback then R[n] = offset_addr;
10491 #endif
10492 
10493     bool success = false;
10494 
10495     if (ConditionPassed(opcode))
10496     {
10497         uint32_t t;
10498         uint32_t t2;
10499         uint32_t n;
10500         uint32_t m;
10501         bool index;
10502         bool add;
10503         bool wback;
10504 
10505         switch (encoding)
10506         {
10507             case eEncodingA1:
10508                 // if Rt<0> == �1� then UNPREDICTABLE;
10509                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10510                 t = Bits32 (opcode, 15, 12);
10511                 if (BitIsSet (t, 0))
10512                    return false;
10513 
10514                 t2 = t+1;
10515                 n = Bits32 (opcode, 19, 16);
10516                 m = Bits32 (opcode, 3, 0);
10517 
10518                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10519                 index = BitIsSet (opcode, 24);
10520                 add = BitIsSet (opcode, 23);
10521                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10522 
10523                 // if P == �0� && W == �1� then UNPREDICTABLE;
10524                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10525                    return false;
10526 
10527                 // if t2 == 15 || m == 15 then UNPREDICTABLE;
10528                 if ((t2 == 15) || (m == 15))
10529                    return false;
10530 
10531                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10532                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10533                    return false;
10534 
10535                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10536                 if ((ArchVersion() < 6) && wback && (m == n))
10537                    return false;
10538 
10539                 break;
10540 
10541             default:
10542                 return false;
10543         }
10544 
10545         RegisterInfo base_reg;
10546         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10547         RegisterInfo offset_reg;
10548         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10549         RegisterInfo data_reg;
10550 
10551         uint32_t Rn = ReadCoreReg (n, &success);
10552         if (!success)
10553             return false;
10554 
10555         uint32_t Rm = ReadCoreReg (m, &success);
10556         if (!success)
10557             return false;
10558 
10559         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10560         addr_t offset_addr;
10561         if (add)
10562             offset_addr = Rn + Rm;
10563         else
10564             offset_addr = Rn - Rm;
10565 
10566         // address = if index then offset_addr else R[n];
10567         addr_t address;
10568         if (index)
10569             address = offset_addr;
10570         else
10571             address = Rn;
10572                           // MemA[address,4] = R[t];
10573         uint32_t Rt = ReadCoreReg (t, &success);
10574         if (!success)
10575             return false;
10576 
10577         EmulateInstruction::Context context;
10578         context.type = eContextRegisterStore;
10579         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10580         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10581 
10582         const uint32_t addr_byte_size = GetAddressByteSize();
10583 
10584         if (!MemAWrite (context, address, Rt, addr_byte_size))
10585             return false;
10586 
10587         // MemA[address+4,4] = R[t2];
10588         uint32_t Rt2 = ReadCoreReg (t2, &success);
10589         if (!success)
10590             return false;
10591 
10592         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10593 
10594         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10595 
10596         if (!MemAWrite (context, address + 4, Rt2, addr_byte_size))
10597             return false;
10598 
10599         // if wback then R[n] = offset_addr;
10600         if (wback)
10601         {
10602             context.type = eContextAdjustBaseRegister;
10603             context.SetAddress (offset_addr);
10604 
10605             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10606                 return false;
10607 
10608         }
10609     }
10610     return true;
10611 }
10612 
10613 // A8.6.319 VLDM
10614 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from
10615 // an ARM core register.
10616 bool
10617 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding)
10618 {
10619 #if 0
10620     if ConditionPassed() then
10621         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10622         address = if add then R[n] else R[n]-imm32;
10623         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10624         for r = 0 to regs-1
10625             if single_regs then
10626                 S[d+r] = MemA[address,4]; address = address+4;
10627             else
10628                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10629                 // Combine the word-aligned words in the correct order for current endianness.
10630                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10631 #endif
10632 
10633     bool success = false;
10634 
10635     if (ConditionPassed(opcode))
10636     {
10637         bool single_regs;
10638         bool add;
10639         bool wback;
10640         uint32_t d;
10641         uint32_t n;
10642         uint32_t imm32;
10643         uint32_t regs;
10644 
10645         switch (encoding)
10646         {
10647             case eEncodingT1:
10648             case eEncodingA1:
10649                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10650                 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10651                 // if P == �1� && W == �0� then SEE VLDR;
10652                 // if P == U && W == �1� then UNDEFINED;
10653                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10654                     return false;
10655 
10656                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10657                 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10658                 single_regs = false;
10659                 add = BitIsSet (opcode, 23);
10660                 wback = BitIsSet (opcode, 21);
10661 
10662                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10663                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10664                 n = Bits32 (opcode, 19, 16);
10665                 imm32 = Bits32 (opcode, 7, 0) << 2;
10666 
10667                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�.
10668                 regs = Bits32 (opcode, 7, 0) / 2;
10669 
10670                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10671                 if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
10672                     return false;
10673 
10674                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10675                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10676                     return false;
10677 
10678                 break;
10679 
10680             case eEncodingT2:
10681             case eEncodingA2:
10682                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10683                 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10684                 // if P == �1� && W == �0� then SEE VLDR;
10685                 // if P == U && W == �1� then UNDEFINED;
10686                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10687                     return false;
10688 
10689                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10690                 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10691                 single_regs = true;
10692                 add = BitIsSet (opcode, 23);
10693                 wback = BitIsSet (opcode, 21);
10694                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10695                 n = Bits32 (opcode, 19, 16);
10696 
10697                 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10698                 imm32 = Bits32 (opcode, 7, 0) << 2;
10699                 regs = Bits32 (opcode, 7, 0);
10700 
10701                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10702                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10703                     return false;
10704 
10705                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10706                 if ((regs == 0) || ((d + regs) > 32))
10707                     return false;
10708                 break;
10709 
10710             default:
10711                 return false;
10712         }
10713 
10714         RegisterInfo base_reg;
10715         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10716 
10717         uint32_t Rn = ReadCoreReg (n, &success);
10718         if (!success)
10719             return false;
10720 
10721         // address = if add then R[n] else R[n]-imm32;
10722         addr_t address;
10723         if (add)
10724             address = Rn;
10725         else
10726             address = Rn - imm32;
10727 
10728         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10729         EmulateInstruction::Context context;
10730 
10731         if (wback)
10732         {
10733             uint32_t value;
10734             if (add)
10735                 value = Rn + imm32;
10736             else
10737                 value = Rn - imm32;
10738 
10739             context.type = eContextAdjustBaseRegister;
10740             context.SetImmediateSigned (value - Rn);
10741             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10742                 return false;
10743 
10744         }
10745 
10746         const uint32_t addr_byte_size = GetAddressByteSize();
10747         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10748 
10749         context.type = eContextRegisterLoad;
10750 
10751         // for r = 0 to regs-1
10752         for (uint32_t r = 0; r < regs; ++r)
10753         {
10754             if (single_regs)
10755             {
10756                 // S[d+r] = MemA[address,4]; address = address+4;
10757                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10758 
10759                 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10760                 if (!success)
10761                     return false;
10762 
10763                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10764                     return false;
10765 
10766                 address = address + 4;
10767             }
10768             else
10769             {
10770                 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10771                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10772                 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10773                 if (!success)
10774                     return false;
10775 
10776                 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10777                 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10778                 if (!success)
10779                     return false;
10780 
10781                 address = address + 8;
10782                 // // Combine the word-aligned words in the correct order for current endianness.
10783                 // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10784                 uint64_t data;
10785                 if (GetByteOrder() == eByteOrderBig)
10786                 {
10787                     data = word1;
10788                     data = (data << 32) | word2;
10789                 }
10790                 else
10791                 {
10792                     data = word2;
10793                     data = (data << 32) | word1;
10794                 }
10795 
10796                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10797                     return false;
10798             }
10799         }
10800     }
10801     return true;
10802 }
10803 
10804 // A8.6.399 VSTM
10805 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an
10806 // ARM core register.
10807 bool
10808 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding)
10809 {
10810 #if 0
10811     if ConditionPassed() then
10812         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10813         address = if add then R[n] else R[n]-imm32;
10814         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10815         for r = 0 to regs-1
10816             if single_regs then
10817                 MemA[address,4] = S[d+r]; address = address+4;
10818             else
10819                 // Store as two word-aligned words in the correct order for current endianness.
10820                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10821                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10822                 address = address+8;
10823 #endif
10824 
10825     bool success = false;
10826 
10827     if (ConditionPassed (opcode))
10828     {
10829         bool single_regs;
10830         bool add;
10831         bool wback;
10832         uint32_t d;
10833         uint32_t n;
10834         uint32_t imm32;
10835         uint32_t regs;
10836 
10837         switch (encoding)
10838         {
10839             case eEncodingT1:
10840             case eEncodingA1:
10841                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10842                 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10843                 // if P == �1� && W == �0� then SEE VSTR;
10844                 // if P == U && W == �1� then UNDEFINED;
10845                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10846                     return false;
10847 
10848                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10849                 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10850                 single_regs = false;
10851                 add = BitIsSet (opcode, 23);
10852                 wback = BitIsSet (opcode, 21);
10853 
10854                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10855                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10856                 n = Bits32 (opcode, 19, 16);
10857                 imm32 = Bits32 (opcode, 7, 0) << 2;
10858 
10859                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�.
10860                 regs = Bits32 (opcode, 7, 0) / 2;
10861 
10862                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10863                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10864                     return false;
10865 
10866                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10867                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10868                     return false;
10869 
10870                 break;
10871 
10872             case eEncodingT2:
10873             case eEncodingA2:
10874                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10875                 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10876                 // if P == �1� && W == �0� then SEE VSTR;
10877                 // if P == U && W == �1� then UNDEFINED;
10878                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10879                     return false;
10880 
10881                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10882                 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10883                 single_regs = true;
10884                 add = BitIsSet (opcode, 23);
10885                 wback = BitIsSet (opcode, 21);
10886                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10887                 n = Bits32 (opcode, 19, 16);
10888 
10889                 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10890                 imm32 = Bits32 (opcode, 7, 0) << 2;
10891                 regs = Bits32 (opcode, 7, 0);
10892 
10893                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10894                 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM)))
10895                     return false;
10896 
10897                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10898                 if ((regs == 0) || ((d + regs) > 32))
10899                     return false;
10900 
10901                 break;
10902 
10903             default:
10904                 return false;
10905         }
10906 
10907         RegisterInfo base_reg;
10908         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10909 
10910         uint32_t Rn = ReadCoreReg (n, &success);
10911         if (!success)
10912             return false;
10913 
10914         // address = if add then R[n] else R[n]-imm32;
10915         addr_t address;
10916         if (add)
10917             address = Rn;
10918         else
10919             address = Rn - imm32;
10920 
10921         EmulateInstruction::Context context;
10922         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10923         if (wback)
10924         {
10925             uint32_t value;
10926             if (add)
10927                 value = Rn + imm32;
10928             else
10929                 value = Rn - imm32;
10930 
10931             context.type = eContextAdjustBaseRegister;
10932             context.SetRegisterPlusOffset (base_reg, value - Rn);
10933 
10934             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10935                 return false;
10936         }
10937 
10938         const uint32_t addr_byte_size = GetAddressByteSize();
10939         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10940 
10941         context.type = eContextRegisterStore;
10942         // for r = 0 to regs-1
10943         for (int r = 0; r < regs; ++r)
10944         {
10945 
10946             if (single_regs)
10947             {
10948                 // MemA[address,4] = S[d+r]; address = address+4;
10949                 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10950                 if (!success)
10951                     return false;
10952 
10953                 RegisterInfo data_reg;
10954                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
10955                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10956                 if (!MemAWrite (context, address, data, addr_byte_size))
10957                     return false;
10958 
10959                 address = address + 4;
10960             }
10961             else
10962             {
10963                 // // Store as two word-aligned words in the correct order for current endianness.
10964                 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10965                 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10966                 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10967                 if (!success)
10968                     return false;
10969 
10970                 RegisterInfo data_reg;
10971                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
10972 
10973                 if (GetByteOrder() == eByteOrderBig)
10974                 {
10975                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10976                     if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
10977                         return false;
10978 
10979                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10980                     if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size))
10981                         return false;
10982                 }
10983                 else
10984                 {
10985                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10986                     if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
10987                         return false;
10988 
10989                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10990                     if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
10991                         return false;
10992                 }
10993                 // address = address+8;
10994                 address = address + 8;
10995             }
10996         }
10997     }
10998     return true;
10999 }
11000 
11001 // A8.6.320
11002 // This instruciton loads a single extension register fronm memory, using an address from an ARM core register, with
11003 // an optional offset.
11004 bool
11005 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
11006 {
11007 #if 0
11008     if ConditionPassed() then
11009         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11010         base = if n == 15 then Align(PC,4) else R[n];
11011         address = if add then (base + imm32) else (base - imm32);
11012         if single_reg then
11013             S[d] = MemA[address,4];
11014         else
11015             word1 = MemA[address,4]; word2 = MemA[address+4,4];
11016             // Combine the word-aligned words in the correct order for current endianness.
11017             D[d] = if BigEndian() then word1:word2 else word2:word1;
11018 #endif
11019 
11020     bool success = false;
11021 
11022     if (ConditionPassed (opcode))
11023     {
11024         bool single_reg;
11025         bool add;
11026         uint32_t imm32;
11027         uint32_t d;
11028         uint32_t n;
11029 
11030         switch (encoding)
11031         {
11032             case eEncodingT1:
11033             case eEncodingA1:
11034                 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11035                 single_reg = false;
11036                 add = BitIsSet (opcode, 23);
11037                 imm32 = Bits32 (opcode, 7, 0) << 2;
11038 
11039                 // d = UInt(D:Vd); n = UInt(Rn);
11040                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11041                 n = Bits32 (opcode, 19, 16);
11042 
11043                 break;
11044 
11045             case eEncodingT2:
11046             case eEncodingA2:
11047                 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11048                 single_reg = true;
11049                 add = BitIsSet (opcode, 23);
11050                 imm32 = Bits32 (opcode, 7, 0) << 2;
11051 
11052                 // d = UInt(Vd:D); n = UInt(Rn);
11053                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11054                 n = Bits32 (opcode, 19, 16);
11055 
11056                 break;
11057 
11058             default:
11059                 return false;
11060         }
11061         RegisterInfo base_reg;
11062         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11063 
11064         uint32_t Rn = ReadCoreReg (n, &success);
11065         if (!success)
11066             return false;
11067 
11068         // base = if n == 15 then Align(PC,4) else R[n];
11069         uint32_t base;
11070         if (n == 15)
11071             base = AlignPC (Rn);
11072         else
11073             base = Rn;
11074 
11075         // address = if add then (base + imm32) else (base - imm32);
11076         addr_t address;
11077         if (add)
11078             address = base + imm32;
11079         else
11080             address = base - imm32;
11081 
11082         const uint32_t addr_byte_size = GetAddressByteSize();
11083         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11084 
11085         EmulateInstruction::Context context;
11086         context.type = eContextRegisterLoad;
11087         context.SetRegisterPlusOffset (base_reg, address - base);
11088 
11089         if (single_reg)
11090         {
11091             // S[d] = MemA[address,4];
11092             uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
11093             if (!success)
11094                 return false;
11095 
11096             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data))
11097                 return false;
11098         }
11099         else
11100         {
11101             // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11102             uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
11103             if (!success)
11104                 return false;
11105 
11106             context.SetRegisterPlusOffset (base_reg, (address + 4) - base);
11107             uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
11108             if (!success)
11109                 return false;
11110             // // Combine the word-aligned words in the correct order for current endianness.
11111             // D[d] = if BigEndian() then word1:word2 else word2:word1;
11112             uint64_t data64;
11113             if (GetByteOrder() == eByteOrderBig)
11114             {
11115                 data64 = word1;
11116                 data64 = (data64 << 32) | word2;
11117             }
11118             else
11119             {
11120                 data64 = word2;
11121                 data64 = (data64 << 32) | word1;
11122             }
11123 
11124             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64))
11125                 return false;
11126         }
11127     }
11128     return true;
11129 }
11130 
11131 // A8.6.400 VSTR
11132 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an
11133 // optional offset.
11134 bool
11135 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
11136 {
11137 #if 0
11138     if ConditionPassed() then
11139         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11140         address = if add then (R[n] + imm32) else (R[n] - imm32);
11141         if single_reg then
11142             MemA[address,4] = S[d];
11143         else
11144             // Store as two word-aligned words in the correct order for current endianness.
11145             MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11146             MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11147 #endif
11148 
11149     bool success = false;
11150 
11151     if (ConditionPassed (opcode))
11152     {
11153         bool single_reg;
11154         bool add;
11155         uint32_t imm32;
11156         uint32_t d;
11157         uint32_t n;
11158 
11159         switch (encoding)
11160         {
11161             case eEncodingT1:
11162             case eEncodingA1:
11163                 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11164                 single_reg = false;
11165                 add = BitIsSet (opcode, 23);
11166                 imm32 = Bits32 (opcode, 7, 0) << 2;
11167 
11168                 // d = UInt(D:Vd); n = UInt(Rn);
11169                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11170                 n = Bits32 (opcode, 19, 16);
11171 
11172                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11173                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11174                     return false;
11175 
11176                 break;
11177 
11178             case eEncodingT2:
11179             case eEncodingA2:
11180                 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11181                 single_reg = true;
11182                 add = BitIsSet (opcode, 23);
11183                 imm32 = Bits32 (opcode, 7, 0) << 2;
11184 
11185                 // d = UInt(Vd:D); n = UInt(Rn);
11186                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11187                 n = Bits32 (opcode, 19, 16);
11188 
11189                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11190                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11191                     return false;
11192 
11193                 break;
11194 
11195             default:
11196                 return false;
11197         }
11198 
11199         RegisterInfo base_reg;
11200         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11201 
11202         uint32_t Rn = ReadCoreReg (n, &success);
11203         if (!success)
11204             return false;
11205 
11206         // address = if add then (R[n] + imm32) else (R[n] - imm32);
11207         addr_t address;
11208         if (add)
11209             address = Rn + imm32;
11210         else
11211             address = Rn - imm32;
11212 
11213         const uint32_t addr_byte_size = GetAddressByteSize();
11214         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11215 
11216         RegisterInfo data_reg;
11217         GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg);
11218         EmulateInstruction::Context context;
11219         context.type = eContextRegisterStore;
11220         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11221 
11222         if (single_reg)
11223         {
11224             // MemA[address,4] = S[d];
11225             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11226             if (!success)
11227                 return false;
11228 
11229             if (!MemAWrite (context, address, data, addr_byte_size))
11230                 return false;
11231         }
11232         else
11233         {
11234             // // Store as two word-aligned words in the correct order for current endianness.
11235             // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11236             // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11237             uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11238             if (!success)
11239                 return false;
11240 
11241             if (GetByteOrder() == eByteOrderBig)
11242             {
11243                 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11244                     return false;
11245 
11246                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11247                 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size))
11248                     return false;
11249             }
11250             else
11251             {
11252                 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11253                     return false;
11254 
11255                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11256                 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11257                     return false;
11258             }
11259         }
11260     }
11261     return true;
11262 }
11263 
11264 // A8.6.307 VLDI1 (multiple single elements)
11265 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving.  Every
11266 // element of each register is loaded.
11267 bool
11268 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding)
11269 {
11270 #if 0
11271     if ConditionPassed() then
11272         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11273         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11274         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11275         for r = 0 to regs-1
11276             for e = 0 to elements-1
11277                 Elem[D[d+r],e,esize] = MemU[address,ebytes];
11278                 address = address + ebytes;
11279 #endif
11280 
11281     bool success = false;
11282 
11283     if (ConditionPassed (opcode))
11284     {
11285         uint32_t regs;
11286         uint32_t alignment;
11287         uint32_t ebytes;
11288         uint32_t esize;
11289         uint32_t elements;
11290         uint32_t d;
11291         uint32_t n;
11292         uint32_t m;
11293         bool wback;
11294         bool register_index;
11295 
11296         switch (encoding)
11297         {
11298             case eEncodingT1:
11299             case eEncodingA1:
11300             {
11301                 // case type of
11302                     // when �0111�
11303                         // regs = 1; if align<1> == �1� then UNDEFINED;
11304                     // when �1010�
11305                         // regs = 2; if align == �11� then UNDEFINED;
11306                     // when �0110�
11307                         // regs = 3; if align<1> == �1� then UNDEFINED;
11308                     // when �0010�
11309                         // regs = 4;
11310                     // otherwise
11311                         // SEE �Related encodings�;
11312                 uint32_t type = Bits32 (opcode, 11, 8);
11313                 uint32_t align = Bits32 (opcode, 5, 4);
11314                 if (type == 7) // '0111'
11315                 {
11316                     regs = 1;
11317                     if (BitIsSet (align, 1))
11318                         return false;
11319                 }
11320                 else if (type == 10) // '1010'
11321                 {
11322                     regs = 2;
11323                     if (align == 3)
11324                         return false;
11325 
11326                 }
11327                 else if (type == 6) // '0110'
11328                 {
11329                     regs = 3;
11330                     if (BitIsSet (align, 1))
11331                         return false;
11332                 }
11333                 else if (type == 2) // '0010'
11334                 {
11335                     regs = 4;
11336                 }
11337                 else
11338                     return false;
11339 
11340                 // alignment = if align == �00� then 1 else 4 << UInt(align);
11341                 if (align == 0)
11342                     alignment = 1;
11343                 else
11344                     alignment = 4 << align;
11345 
11346                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11347                 ebytes = 1 << Bits32 (opcode, 7, 6);
11348                 esize = 8 * ebytes;
11349                 elements = 8 / ebytes;
11350 
11351                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11352                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11353                 n = Bits32 (opcode, 19, 15);
11354                 m = Bits32 (opcode, 3, 0);
11355 
11356                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11357                 wback = (m != 15);
11358                 register_index = ((m != 15) && (m != 13));
11359 
11360                 // if d+regs > 32 then UNPREDICTABLE;
11361                 if ((d + regs) > 32)
11362                     return false;
11363             }
11364                 break;
11365 
11366             default:
11367                 return false;
11368         }
11369 
11370         RegisterInfo base_reg;
11371         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11372 
11373         uint32_t Rn = ReadCoreReg (n, &success);
11374         if (!success)
11375             return false;
11376 
11377         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11378         addr_t address = Rn;
11379         if ((address % alignment) != 0)
11380             return false;
11381 
11382         EmulateInstruction::Context context;
11383         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11384         if (wback)
11385         {
11386             uint32_t Rm = ReadCoreReg (m, &success);
11387             if (!success)
11388                 return false;
11389 
11390             uint32_t offset;
11391             if (register_index)
11392                 offset = Rm;
11393             else
11394                 offset = 8 * regs;
11395 
11396             uint32_t value = Rn + offset;
11397             context.type = eContextAdjustBaseRegister;
11398             context.SetRegisterPlusOffset (base_reg, offset);
11399 
11400             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11401                 return false;
11402 
11403         }
11404 
11405         // for r = 0 to regs-1
11406         for (int r = 0; r < regs; ++r)
11407         {
11408             // for e = 0 to elements-1
11409             uint64_t assembled_data = 0;
11410             for (int e = 0; e < elements; ++e)
11411             {
11412                 // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11413                 context.type = eContextRegisterLoad;
11414                 context.SetRegisterPlusOffset (base_reg, address - Rn);
11415                 uint64_t data = MemURead (context, address, ebytes, 0, &success);
11416                 if (!success)
11417                     return false;
11418 
11419                 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data
11420 
11421                 // address = address + ebytes;
11422                 address = address + ebytes;
11423             }
11424             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data))
11425                 return false;
11426         }
11427     }
11428     return true;
11429 }
11430 
11431 // A8.6.308 VLD1 (single element to one lane)
11432 //
11433 bool
11434 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding)
11435 {
11436 #if 0
11437     if ConditionPassed() then
11438         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11439         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11440         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11441         Elem[D[d],index,esize] = MemU[address,ebytes];
11442 #endif
11443 
11444     bool success = false;
11445 
11446     if (ConditionPassed (opcode))
11447     {
11448         uint32_t ebytes;
11449         uint32_t esize;
11450         uint32_t index;
11451         uint32_t alignment;
11452         uint32_t d;
11453         uint32_t n;
11454         uint32_t m;
11455         bool wback;
11456         bool register_index;
11457 
11458         switch (encoding)
11459         {
11460             case eEncodingT1:
11461             case eEncodingA1:
11462             {
11463                 uint32_t size = Bits32 (opcode, 11, 10);
11464                 uint32_t index_align = Bits32 (opcode, 7, 4);
11465                 // if size == �11� then SEE VLD1 (single element to all lanes);
11466                 if (size == 3)
11467                    return EmulateVLD1SingleAll (opcode, encoding);
11468                 // case size of
11469                 if (size == 0) // when '00'
11470                 {
11471                     // if index_align<0> != �0� then UNDEFINED;
11472                     if (BitIsClear (index_align, 0))
11473                         return false;
11474 
11475                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11476                     ebytes = 1;
11477                     esize = 8;
11478                     index = Bits32 (index_align, 3, 1);
11479                     alignment = 1;
11480                 }
11481                 else if (size == 1) // when �01�
11482                 {
11483                     // if index_align<1> != �0� then UNDEFINED;
11484                     if (BitIsClear (index_align, 1))
11485                         return false;
11486 
11487                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11488                     ebytes = 2;
11489                     esize = 16;
11490                     index = Bits32 (index_align, 3, 2);
11491 
11492                     // alignment = if index_align<0> == �0� then 1 else 2;
11493                     if (BitIsClear (index_align, 0))
11494                         alignment = 1;
11495                     else
11496                         alignment = 2;
11497                 }
11498                 else if (size == 2) // when �10�
11499                 {
11500                     // if index_align<2> != �0� then UNDEFINED;
11501                     if (BitIsClear (index_align, 2))
11502                         return false;
11503 
11504                     // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11505                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11506                         return false;
11507 
11508                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11509                     ebytes = 4;
11510                     esize = 32;
11511                     index = Bit32 (index_align, 3);
11512 
11513                     // alignment = if index_align<1:0> == �00� then 1 else 4;
11514                     if (Bits32 (index_align, 1, 0) == 0)
11515                         alignment = 1;
11516                     else
11517                         alignment = 4;
11518                 }
11519                 else
11520                 {
11521                     return false;
11522                 }
11523                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11524                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11525                 n = Bits32 (opcode, 19, 16);
11526                 m = Bits32 (opcode, 3, 0);
11527 
11528                 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
11529                 wback = (m != 15);
11530                 register_index = ((m != 15) && (m != 13));
11531 
11532                 if (n == 15)
11533                     return false;
11534 
11535             }
11536                 break;
11537 
11538             default:
11539                 return false;
11540         }
11541 
11542         RegisterInfo base_reg;
11543         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11544 
11545         uint32_t Rn = ReadCoreReg (n, &success);
11546         if (!success)
11547             return false;
11548 
11549         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11550         addr_t address = Rn;
11551         if ((address % alignment) != 0)
11552             return false;
11553 
11554         EmulateInstruction::Context context;
11555         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11556         if (wback)
11557         {
11558             uint32_t Rm = ReadCoreReg (m, &success);
11559             if (!success)
11560                 return false;
11561 
11562             uint32_t offset;
11563             if (register_index)
11564                 offset = Rm;
11565             else
11566                 offset = ebytes;
11567 
11568             uint32_t value = Rn + offset;
11569 
11570             context.type = eContextAdjustBaseRegister;
11571             context.SetRegisterPlusOffset (base_reg, offset);
11572 
11573             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11574                 return false;
11575         }
11576 
11577         // Elem[D[d],index,esize] = MemU[address,ebytes];
11578         uint32_t element = MemURead (context, address, esize, 0, &success);
11579         if (!success)
11580             return false;
11581 
11582         element = element << (index * esize);
11583 
11584         uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11585         if (!success)
11586             return false;
11587 
11588         uint64_t all_ones = -1;
11589         uint64_t mask = all_ones << ((index+1) * esize);  // mask is all 1's to left of where 'element' goes, & all 0's
11590                                                           // at element & to the right of element.
11591         if (index > 0)
11592             mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes.
11593                                                                      // now mask should be 0's where element goes & 1's
11594                                                                      // everywhere else.
11595 
11596         uint64_t masked_reg = reg_data & mask;  // Take original reg value & zero out 'element' bits
11597         reg_data = masked_reg & element;        // Put 'element' into those bits in reg_data.
11598 
11599         context.type = eContextRegisterLoad;
11600         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data))
11601             return false;
11602     }
11603     return true;
11604 }
11605 
11606 // A8.6.391 VST1 (multiple single elements)
11607 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four regsiters, without
11608 // interleaving.  Every element of each register is stored.
11609 bool
11610 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding)
11611 {
11612 #if 0
11613     if ConditionPassed() then
11614         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11615         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11616         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11617         for r = 0 to regs-1
11618             for e = 0 to elements-1
11619                 MemU[address,ebytes] = Elem[D[d+r],e,esize];
11620                 address = address + ebytes;
11621 #endif
11622 
11623     bool success = false;
11624 
11625     if (ConditionPassed (opcode))
11626     {
11627         uint32_t regs;
11628         uint32_t alignment;
11629         uint32_t ebytes;
11630         uint32_t esize;
11631         uint32_t elements;
11632         uint32_t d;
11633         uint32_t n;
11634         uint32_t m;
11635         bool wback;
11636         bool register_index;
11637 
11638         switch (encoding)
11639         {
11640             case eEncodingT1:
11641             case eEncodingA1:
11642             {
11643                 uint32_t type = Bits32 (opcode, 11, 8);
11644                 uint32_t align = Bits32 (opcode, 5, 4);
11645 
11646                 // case type of
11647                 if (type == 7)    // when �0111�
11648                 {
11649                     // regs = 1; if align<1> == �1� then UNDEFINED;
11650                     regs = 1;
11651                     if (BitIsSet (align, 1))
11652                         return false;
11653                 }
11654                 else if (type == 10) // when �1010�
11655                 {
11656                     // regs = 2; if align == �11� then UNDEFINED;
11657                     regs = 2;
11658                     if (align == 3)
11659                         return false;
11660                 }
11661                 else if (type == 6) // when �0110�
11662                 {
11663                     // regs = 3; if align<1> == �1� then UNDEFINED;
11664                     regs = 3;
11665                     if (BitIsSet (align, 1))
11666                         return false;
11667                 }
11668                 else if (type == 2) // when �0010�
11669                     // regs = 4;
11670                     regs = 4;
11671                 else // otherwise
11672                     // SEE �Related encodings�;
11673                     return false;
11674 
11675                 // alignment = if align == �00� then 1 else 4 << UInt(align);
11676                 if (align == 0)
11677                     alignment = 1;
11678                 else
11679                     alignment = 4 << align;
11680 
11681                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11682                 ebytes = 1 << Bits32 (opcode,7, 6);
11683                 esize = 8 * ebytes;
11684                 elements = 8 / ebytes;
11685 
11686                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11687                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11688                 n = Bits32 (opcode, 19, 16);
11689                 m = Bits32 (opcode, 3, 0);
11690 
11691                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11692                 wback = (m != 15);
11693                 register_index = ((m != 15) && (m != 13));
11694 
11695                 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11696                 if ((d + regs) > 32)
11697                     return false;
11698 
11699                 if (n == 15)
11700                     return false;
11701 
11702             }
11703                 break;
11704 
11705             default:
11706                 return false;
11707         }
11708 
11709         RegisterInfo base_reg;
11710         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11711 
11712         uint32_t Rn = ReadCoreReg (n, &success);
11713         if (!success)
11714             return false;
11715 
11716         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11717         addr_t address = Rn;
11718         if ((address % alignment) != 0)
11719             return false;
11720 
11721         EmulateInstruction::Context context;
11722         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11723         if (wback)
11724         {
11725             uint32_t Rm = ReadCoreReg (m, &success);
11726             if (!success)
11727                 return false;
11728 
11729             uint32_t offset;
11730             if (register_index)
11731                 offset = Rm;
11732             else
11733                 offset = 8 * regs;
11734 
11735             context.type = eContextAdjustBaseRegister;
11736             context.SetRegisterPlusOffset (base_reg, offset);
11737 
11738             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11739                 return false;
11740         }
11741 
11742         RegisterInfo data_reg;
11743         context.type = eContextRegisterStore;
11744         // for r = 0 to regs-1
11745         for (int r = 0; r < regs; ++r)
11746         {
11747             GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
11748             uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
11749             if (!success)
11750                 return false;
11751 
11752              // for e = 0 to elements-1
11753             for (int e = 0; e < elements; ++e)
11754             {
11755                 // MemU[address,ebytes] = Elem[D[d+r],e,esize];
11756                 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize);
11757 
11758                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11759                 if (!MemUWrite (context, address, word, ebytes))
11760                     return false;
11761 
11762                 // address = address + ebytes;
11763                 address = address + ebytes;
11764             }
11765         }
11766     }
11767     return true;
11768 }
11769 
11770 // A8.6.392 VST1 (single element from one lane)
11771 // This instruction stores one element to memory from one element of a register.
11772 bool
11773 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding)
11774 {
11775 #if 0
11776     if ConditionPassed() then
11777         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11778         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11779         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11780         MemU[address,ebytes] = Elem[D[d],index,esize];
11781 #endif
11782 
11783     bool success = false;
11784 
11785     if (ConditionPassed (opcode))
11786     {
11787         uint32_t ebytes;
11788         uint32_t esize;
11789         uint32_t index;
11790         uint32_t alignment;
11791         uint32_t d;
11792         uint32_t n;
11793         uint32_t m;
11794         bool wback;
11795         bool register_index;
11796 
11797         switch (encoding)
11798         {
11799             case eEncodingT1:
11800             case eEncodingA1:
11801             {
11802                 uint32_t size = Bits32 (opcode, 11, 10);
11803                 uint32_t index_align = Bits32 (opcode, 7, 4);
11804 
11805                 // if size == �11� then UNDEFINED;
11806                 if (size == 3)
11807                     return false;
11808 
11809                 // case size of
11810                 if (size == 0) // when �00�
11811                 {
11812                     // if index_align<0> != �0� then UNDEFINED;
11813                     if (BitIsClear (index_align, 0))
11814                         return false;
11815                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11816                     ebytes = 1;
11817                     esize = 8;
11818                     index = Bits32 (index_align, 3, 1);
11819                     alignment = 1;
11820                 }
11821                 else if (size == 1) // when �01�
11822                 {
11823                     // if index_align<1> != �0� then UNDEFINED;
11824                     if (BitIsClear (index_align, 1))
11825                         return false;
11826 
11827                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11828                     ebytes = 2;
11829                     esize = 16;
11830                     index = Bits32 (index_align, 3, 2);
11831 
11832                     // alignment = if index_align<0> == �0� then 1 else 2;
11833                     if (BitIsClear (index_align, 0))
11834                         alignment = 1;
11835                     else
11836                         alignment = 2;
11837                 }
11838                 else if (size == 2) // when �10�
11839                 {
11840                     // if index_align<2> != �0� then UNDEFINED;
11841                     if (BitIsClear (index_align, 2))
11842                         return false;
11843 
11844                     // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11845                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11846                         return false;
11847 
11848                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11849                     ebytes = 4;
11850                     esize = 32;
11851                     index = Bit32 (index_align, 3);
11852 
11853                     // alignment = if index_align<1:0> == �00� then 1 else 4;
11854                     if (Bits32 (index_align, 1, 0) == 0)
11855                         alignment = 1;
11856                     else
11857                         alignment = 4;
11858                 }
11859                 else
11860                 {
11861                     return false;
11862                 }
11863                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11864                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11865                 n = Bits32 (opcode, 19, 16);
11866                 m = Bits32 (opcode, 3, 0);
11867 
11868                 // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15 then UNPREDICTABLE;
11869                 wback = (m != 15);
11870                 register_index = ((m != 15) && (m != 13));
11871 
11872                 if (n == 15)
11873                     return false;
11874             }
11875                 break;
11876 
11877             default:
11878                 return false;
11879         }
11880 
11881         RegisterInfo base_reg;
11882         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11883 
11884         uint32_t Rn = ReadCoreReg (n, &success);
11885         if (!success)
11886             return false;
11887 
11888         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11889         addr_t address = Rn;
11890         if ((address % alignment) != 0)
11891             return false;
11892 
11893         EmulateInstruction::Context context;
11894         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11895         if (wback)
11896         {
11897             uint32_t Rm = ReadCoreReg (m, &success);
11898             if (!success)
11899                 return false;
11900 
11901             uint32_t offset;
11902             if (register_index)
11903                 offset = Rm;
11904             else
11905                 offset = ebytes;
11906 
11907             context.type = eContextAdjustBaseRegister;
11908             context.SetRegisterPlusOffset (base_reg, offset);
11909 
11910             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11911                 return false;
11912         }
11913 
11914         // MemU[address,ebytes] = Elem[D[d],index,esize];
11915         uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11916         if (!success)
11917             return false;
11918 
11919         uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1,  index * esize);
11920 
11921         RegisterInfo data_reg;
11922         GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg);
11923         context.type = eContextRegisterStore;
11924         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11925 
11926         if (!MemUWrite (context, address, word, ebytes))
11927             return false;
11928     }
11929     return true;
11930 }
11931 
11932 // A8.6.309 VLD1 (single element to all lanes)
11933 // This instruction loads one element from memory into every element of one or two vectors.
11934 bool
11935 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding)
11936 {
11937 #if 0
11938     if ConditionPassed() then
11939         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11940         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11941         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11942         replicated_element = Replicate(MemU[address,ebytes], elements);
11943         for r = 0 to regs-1
11944             D[d+r] = replicated_element;
11945 #endif
11946 
11947     bool success = false;
11948 
11949     if (ConditionPassed (opcode))
11950     {
11951         uint32_t ebytes;
11952         uint32_t elements;
11953         uint32_t regs;
11954         uint32_t alignment;
11955         uint32_t d;
11956         uint32_t n;
11957         uint32_t m;
11958         bool wback;
11959         bool register_index;
11960 
11961         switch (encoding)
11962         {
11963             case eEncodingT1:
11964             case eEncodingA1:
11965             {
11966                 //if size == �11� || (size == �00� && a == �1�) then UNDEFINED;
11967                 uint32_t size = Bits32 (opcode, 7, 6);
11968                 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4)))
11969                     return false;
11970 
11971                 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2;
11972                 ebytes = 1 << size;
11973                 elements = 8 / ebytes;
11974                 if (BitIsClear (opcode, 5))
11975                     regs = 1;
11976                 else
11977                     regs = 2;
11978 
11979                 //alignment = if a == �0� then 1 else ebytes;
11980                 if (BitIsClear (opcode, 4))
11981                     alignment = 1;
11982                 else
11983                     alignment = ebytes;
11984 
11985                 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11986                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11987                 n = Bits32 (opcode, 19, 16);
11988                 m = Bits32 (opcode, 3, 0);
11989 
11990                 //wback = (m != 15); register_index = (m != 15 && m != 13);
11991                 wback = (m != 15);
11992                 register_index = ((m != 15) && (m != 13));
11993 
11994                 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11995                 if ((d + regs) > 32)
11996                     return false;
11997 
11998                 if (n == 15)
11999                     return false;
12000             }
12001             break;
12002 
12003             default:
12004                 return false;
12005         }
12006 
12007         RegisterInfo base_reg;
12008         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12009 
12010         uint32_t Rn = ReadCoreReg (n, &success);
12011         if (!success)
12012             return false;
12013 
12014         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12015         addr_t address = Rn;
12016         if ((address % alignment) != 0)
12017             return false;
12018 
12019         EmulateInstruction::Context context;
12020         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12021         if (wback)
12022         {
12023             uint32_t Rm = ReadCoreReg (m, &success);
12024             if (!success)
12025                 return false;
12026 
12027             uint32_t offset;
12028             if (register_index)
12029                 offset = Rm;
12030             else
12031                 offset = ebytes;
12032 
12033             context.type = eContextAdjustBaseRegister;
12034             context.SetRegisterPlusOffset (base_reg, offset);
12035 
12036             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
12037                 return false;
12038         }
12039 
12040         // replicated_element = Replicate(MemU[address,ebytes], elements);
12041 
12042         context.type = eContextRegisterLoad;
12043         uint64_t word = MemURead (context, address, ebytes, 0, &success);
12044         if (!success)
12045             return false;
12046 
12047         uint64_t replicated_element = 0;
12048         uint32_t esize = ebytes * 8;
12049         for (int e = 0; e < elements; ++e)
12050             replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0);
12051 
12052         // for r = 0 to regs-1
12053         for (int r = 0; r < regs; ++r)
12054         {
12055             // D[d+r] = replicated_element;
12056             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element))
12057                 return false;
12058         }
12059     }
12060     return true;
12061 }
12062 
12063 // B6.2.13 SUBS PC, LR and related instructions
12064 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack.  It subtracts the
12065 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR.
12066 bool
12067 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding)
12068 {
12069 #if 0
12070     if ConditionPassed() then
12071         EncodingSpecificOperations();
12072         if CurrentInstrSet() == InstrSet_ThumbEE then
12073             UNPREDICTABLE;
12074         operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12075         case opcode of
12076             when �0000� result = R[n] AND operand2; // AND
12077             when �0001� result = R[n] EOR operand2; // EOR
12078             when �0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12079             when �0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12080             when �0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12081             when �0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12082             when �0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12083             when �0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12084             when �1100� result = R[n] OR operand2; // ORR
12085             when �1101� result = operand2; // MOV
12086             when �1110� result = R[n] AND NOT(operand2); // BIC
12087             when �1111� result = NOT(operand2); // MVN
12088         CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12089         BranchWritePC(result);
12090 #endif
12091 
12092     bool success = false;
12093 
12094     if (ConditionPassed (opcode))
12095     {
12096         uint32_t n;
12097         uint32_t m;
12098         uint32_t imm32;
12099         bool register_form;
12100         ARM_ShifterType shift_t;
12101         uint32_t shift_n;
12102         uint32_t code;
12103 
12104         switch (encoding)
12105         {
12106             case eEncodingT1:
12107                 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
12108                 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB
12109                 n = 14;
12110                 imm32 = Bits32 (opcode, 7, 0);
12111                 register_form = false;
12112                 code = 2;
12113 
12114                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12115                 if (InITBlock() && !LastInITBlock())
12116                     return false;
12117 
12118                 break;
12119 
12120             case eEncodingA1:
12121                 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12122                 n = Bits32 (opcode, 19, 16);
12123                 imm32 = ARMExpandImm (opcode);
12124                 register_form = false;
12125                 code = Bits32 (opcode, 24, 21);
12126 
12127                 break;
12128 
12129             case eEncodingA2:
12130                 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12131                 n = Bits32 (opcode, 19, 16);
12132                 m = Bits32 (opcode, 3, 0);
12133                 register_form = true;
12134 
12135                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12136                 shift_n = DecodeImmShiftARM (opcode, shift_t);
12137 
12138                 break;
12139 
12140             default:
12141                 return false;
12142         }
12143 
12144         // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12145         uint32_t operand2;
12146         if (register_form)
12147         {
12148             uint32_t Rm = ReadCoreReg (m, &success);
12149             if (!success)
12150                 return false;
12151 
12152             operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success);
12153             if (!success)
12154                 return false;
12155         }
12156         else
12157         {
12158             operand2 = imm32;
12159         }
12160 
12161         uint32_t Rn = ReadCoreReg (n, &success);
12162         if (!success)
12163             return false;
12164 
12165         AddWithCarryResult result;
12166 
12167         // case opcode of
12168         switch (code)
12169         {
12170             case 0: // when �0000�
12171                 // result = R[n] AND operand2; // AND
12172                 result.result = Rn & operand2;
12173                 break;
12174 
12175             case 1: // when �0001�
12176                 // result = R[n] EOR operand2; // EOR
12177                 result.result = Rn ^ operand2;
12178                 break;
12179 
12180             case 2: // when �0010�
12181                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12182                 result = AddWithCarry (Rn, ~(operand2), 1);
12183                 break;
12184 
12185             case 3: // when �0011�
12186                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12187                 result = AddWithCarry (~(Rn), operand2, 1);
12188                 break;
12189 
12190             case 4: // when �0100�
12191                 // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12192                 result = AddWithCarry (Rn, operand2, 0);
12193                 break;
12194 
12195             case 5: // when �0101�
12196                 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12197                 result = AddWithCarry (Rn, operand2, APSR_C);
12198                 break;
12199 
12200             case 6: // when �0110�
12201                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12202                 result = AddWithCarry (Rn, ~(operand2), APSR_C);
12203                 break;
12204 
12205             case 7: // when �0111�
12206                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12207                 result = AddWithCarry (~(Rn), operand2, APSR_C);
12208                 break;
12209 
12210             case 10: // when �1100�
12211                 // result = R[n] OR operand2; // ORR
12212                 result.result = Rn | operand2;
12213                 break;
12214 
12215             case 11: // when �1101�
12216                 // result = operand2; // MOV
12217                 result.result = operand2;
12218                 break;
12219 
12220             case 12: // when �1110�
12221                 // result = R[n] AND NOT(operand2); // BIC
12222                 result.result = Rn & ~(operand2);
12223                 break;
12224 
12225             case 15: // when �1111�
12226                 // result = NOT(operand2); // MVN
12227                 result.result = ~(operand2);
12228                 break;
12229 
12230             default:
12231                 return false;
12232         }
12233         // CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12234 
12235         // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for
12236         // the best.
12237         uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12238         if (!success)
12239             return false;
12240 
12241         CPSRWriteByInstr (spsr, 15, true);
12242 
12243         // BranchWritePC(result);
12244         EmulateInstruction::Context context;
12245         context.type = eContextAdjustPC;
12246         context.SetImmediate (result.result);
12247 
12248         BranchWritePC (context, result.result);
12249     }
12250     return true;
12251 }
12252 
12253 EmulateInstructionARM::ARMOpcode*
12254 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12255 {
12256     static ARMOpcode
12257     g_arm_opcodes[] =
12258     {
12259         //----------------------------------------------------------------------
12260         // Prologue instructions
12261         //----------------------------------------------------------------------
12262 
12263         // push register(s)
12264         { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12265         { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
12266 
12267         // set r7 to point to a stack offset
12268         { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
12269         { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12270         // copy the stack pointer to ip
12271         { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
12272         { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
12273         { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12274 
12275         // adjust the stack pointer
12276         { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12277         { 0x0fef0010, 0x004d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12278 
12279         // push one register
12280         // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12281         { 0x0e5f0000, 0x040d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
12282 
12283         // vector push consecutive extension register(s)
12284         { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12285         { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12286 
12287         //----------------------------------------------------------------------
12288         // Epilogue instructions
12289         //----------------------------------------------------------------------
12290 
12291         { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12292         { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12293         { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12294         { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12295 
12296         //----------------------------------------------------------------------
12297         // Supervisor Call (previously Software Interrupt)
12298         //----------------------------------------------------------------------
12299         { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12300 
12301         //----------------------------------------------------------------------
12302         // Branch instructions
12303         //----------------------------------------------------------------------
12304         { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
12305         // To resolve ambiguity, "blx <label>" should come before "bl <label>".
12306         { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12307         { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12308         { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12309         // for example, "bx lr"
12310         { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12311         // bxj
12312         { 0x0ffffff0, 0x012fff20, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12313 
12314         //----------------------------------------------------------------------
12315         // Data-processing instructions
12316         //----------------------------------------------------------------------
12317         // adc (immediate)
12318         { 0x0fe00000, 0x02a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12319         // adc (register)
12320         { 0x0fe00010, 0x00a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12321         // add (immediate)
12322         { 0x0fe00000, 0x02800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
12323         // add (register)
12324         { 0x0fe00010, 0x00800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12325         // add (register-shifted register)
12326         { 0x0fe00090, 0x00800010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12327         // adr
12328         { 0x0fff0000, 0x028f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12329         { 0x0fff0000, 0x024f0000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12330         // and (immediate)
12331         { 0x0fe00000, 0x02000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12332         // and (register)
12333         { 0x0fe00010, 0x00000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12334         // bic (immediate)
12335         { 0x0fe00000, 0x03c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12336         // bic (register)
12337         { 0x0fe00010, 0x01c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12338         // eor (immediate)
12339         { 0x0fe00000, 0x02200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12340         // eor (register)
12341         { 0x0fe00010, 0x00200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12342         // orr (immediate)
12343         { 0x0fe00000, 0x03800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12344         // orr (register)
12345         { 0x0fe00010, 0x01800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12346         // rsb (immediate)
12347         { 0x0fe00000, 0x02600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12348         // rsb (register)
12349         { 0x0fe00010, 0x00600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12350         // rsc (immediate)
12351         { 0x0fe00000, 0x02e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12352         // rsc (register)
12353         { 0x0fe00010, 0x00e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12354         // sbc (immediate)
12355         { 0x0fe00000, 0x02c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12356         // sbc (register)
12357         { 0x0fe00010, 0x00c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12358         // sub (immediate, ARM)
12359         { 0x0fe00000, 0x02400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
12360         // sub (sp minus immediate)
12361         { 0x0fef0000, 0x024d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12362         // sub (register)
12363         { 0x0fe00010, 0x00400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12364         // teq (immediate)
12365         { 0x0ff0f000, 0x03300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12366         // teq (register)
12367         { 0x0ff0f010, 0x01300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12368         // tst (immediate)
12369         { 0x0ff0f000, 0x03100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12370         // tst (register)
12371         { 0x0ff0f010, 0x01100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12372 
12373         // mov (immediate)
12374         { 0x0fef0000, 0x03a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12375         { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
12376         // mov (register)
12377         { 0x0fef0ff0, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12378         // mvn (immediate)
12379         { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12380         // mvn (register)
12381         { 0x0fef0010, 0x01e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12382         // cmn (immediate)
12383         { 0x0ff0f000, 0x03700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12384         // cmn (register)
12385         { 0x0ff0f010, 0x01700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12386         // cmp (immediate)
12387         { 0x0ff0f000, 0x03500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
12388         // cmp (register)
12389         { 0x0ff0f010, 0x01500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
12390         // asr (immediate)
12391         { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
12392         // asr (register)
12393         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
12394         // lsl (immediate)
12395         { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
12396         // lsl (register)
12397         { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
12398         // lsr (immediate)
12399         { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
12400         // lsr (register)
12401         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
12402         // rrx is a special case encoding of ror (immediate)
12403         { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
12404         // ror (immediate)
12405         { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
12406         // ror (register)
12407         { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
12408         // mul
12409         { 0x0fe000f0, 0x00000090, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
12410 
12411         // subs pc, lr and related instructions
12412         { 0x0e10f000, 0x0210f000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" },
12413         { 0x0e10f010, 0x0010f000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" },
12414 
12415         //----------------------------------------------------------------------
12416         // Load instructions
12417         //----------------------------------------------------------------------
12418         { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12419         { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
12420         { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12421         { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
12422         { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
12423         { 0x0e500010, 0x06100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
12424         { 0x0e5f0000, 0x045f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
12425         { 0xfe500010, 0x06500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
12426         { 0x0e5f00f0, 0x005f00b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12427         { 0x0e5000f0, 0x001000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"  },
12428         { 0x0e5000f0, 0x005000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
12429         { 0x0e5f00f0, 0x005f00d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
12430         { 0x0e5000f0, 0x001000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12431         { 0x0e5000f0, 0x005000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
12432         { 0x0e5f00f0, 0x005f00f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12433         { 0x0e5000f0, 0x001000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12434         { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
12435         { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12436         { 0x0e100f00, 0x0c100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12437         { 0x0e100f00, 0x0c100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12438         { 0x0f300f00, 0x0d100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12439         { 0x0f300f00, 0x0d100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12440         { 0xffb00000, 0xf4200000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12441         { 0xffb00300, 0xf4a00000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12442         { 0xffb00f00, 0xf4a00c00, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12443 
12444         //----------------------------------------------------------------------
12445         // Store instructions
12446         //----------------------------------------------------------------------
12447         { 0x0fd00000, 0x08800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12448         { 0x0fd00000, 0x08000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
12449         { 0x0fd00000, 0x09000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12450         { 0x0fd00000, 0x09800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
12451         { 0x0e500010, 0x06000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
12452         { 0x0e5000f0, 0x000000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
12453         { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
12454         { 0x0e500000, 0x04400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12455         { 0x0e500000, 0x04000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12456         { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
12457         { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12458         { 0x0e100f00, 0x0c000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12459         { 0x0e100f00, 0x0c000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12460         { 0x0f300f00, 0x0d000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
12461         { 0x0f300f00, 0x0d000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
12462         { 0xffb00000, 0xf4000000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12463         { 0xffb00300, 0xf4800000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12464 
12465         //----------------------------------------------------------------------
12466         // Other instructions
12467         //----------------------------------------------------------------------
12468         { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
12469         { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
12470         { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
12471         { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
12472         { 0xfe500000, 0xf8100000, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
12473 
12474     };
12475     static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode);
12476 
12477     for (size_t i=0; i<k_num_arm_opcodes; ++i)
12478     {
12479         if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
12480             (g_arm_opcodes[i].variants & arm_isa) != 0)
12481             return &g_arm_opcodes[i];
12482     }
12483     return NULL;
12484 }
12485 
12486 
12487 EmulateInstructionARM::ARMOpcode*
12488 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12489 {
12490 
12491     static ARMOpcode
12492     g_thumb_opcodes[] =
12493     {
12494         //----------------------------------------------------------------------
12495         // Prologue instructions
12496         //----------------------------------------------------------------------
12497 
12498         // push register(s)
12499         { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12500         { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
12501         { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
12502 
12503         // set r7 to point to a stack offset
12504         { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
12505         // copy the stack pointer to r7
12506         { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
12507         // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
12508         { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
12509 
12510         // PC-relative load into register (see also EmulateADDSPRm)
12511         { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
12512 
12513         // adjust the stack pointer
12514         { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
12515         { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
12516         { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
12517         { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
12518         { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12519 
12520         // vector push consecutive extension register(s)
12521         { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12522         { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12523 
12524         //----------------------------------------------------------------------
12525         // Epilogue instructions
12526         //----------------------------------------------------------------------
12527 
12528         { 0xfffff800, 0x0000a800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
12529         { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
12530         { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12531         { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
12532         { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
12533         { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12534         { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12535 
12536         //----------------------------------------------------------------------
12537         // Supervisor Call (previously Software Interrupt)
12538         //----------------------------------------------------------------------
12539         { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
12540 
12541         //----------------------------------------------------------------------
12542         // If Then makes up to four following instructions conditional.
12543         //----------------------------------------------------------------------
12544         // The next 5 opcode _must_ come before the if then instruction
12545         { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"},
12546         { 0xffffffff, 0x0000bf10, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
12547         { 0xffffffff, 0x0000bf20, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
12548         { 0xffffffff, 0x0000bf30, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
12549         { 0xffffffff, 0x0000bf40, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
12550         { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
12551 
12552         //----------------------------------------------------------------------
12553         // Branch instructions
12554         //----------------------------------------------------------------------
12555         // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
12556         { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
12557         { 0xfffff800, 0x0000e000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
12558         { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
12559         { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
12560         // J1 == J2 == 1
12561         { 0xf800d000, 0xf000d000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12562         // J1 == J2 == 1
12563         { 0xf800d001, 0xf000c000, ARMV5_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12564         { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12565         // for example, "bx lr"
12566         { 0xffffff87, 0x00004700, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12567         // bxj
12568         { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12569         // compare and branch
12570         { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
12571         // table branch byte
12572         { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
12573         // table branch halfword
12574         { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
12575 
12576         //----------------------------------------------------------------------
12577         // Data-processing instructions
12578         //----------------------------------------------------------------------
12579         // adc (immediate)
12580         { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
12581         // adc (register)
12582         { 0xffffffc0, 0x00004140, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
12583         { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12584         // add (register)
12585         { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
12586         // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
12587         { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
12588         // adr
12589         { 0xfffff800, 0x0000a000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12590         { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12591         { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12592         // and (immediate)
12593         { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
12594         // and (register)
12595         { 0xffffffc0, 0x00004000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
12596         { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12597         // bic (immediate)
12598         { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
12599         // bic (register)
12600         { 0xffffffc0, 0x00004380, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
12601         { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12602         // eor (immediate)
12603         { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
12604         // eor (register)
12605         { 0xffffffc0, 0x00004040, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
12606         { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12607         // orr (immediate)
12608         { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
12609         // orr (register)
12610         { 0xffffffc0, 0x00004300, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
12611         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12612         // rsb (immediate)
12613         { 0xffffffc0, 0x00004240, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
12614         { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
12615         // rsb (register)
12616         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12617         // sbc (immediate)
12618         { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12619         // sbc (register)
12620         { 0xffffffc0, 0x00004180, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
12621         { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12622         // add (immediate, Thumb)
12623         { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
12624         { 0xfffff800, 0x00003000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
12625         { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
12626         { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
12627         // sub (immediate, Thumb)
12628         { 0xfffffe00, 0x00001e00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
12629         { 0xfffff800, 0x00003800, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
12630         { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
12631         { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
12632         // sub (sp minus immediate)
12633         { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
12634         { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
12635         // sub (register)
12636         { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
12637         { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
12638         // teq (immediate)
12639         { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
12640         // teq (register)
12641         { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12642         // tst (immediate)
12643         { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
12644         // tst (register)
12645         { 0xffffffc0, 0x00004200, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
12646         { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
12647 
12648 
12649         // move from high register to high register
12650         { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
12651         // move from low register to low register
12652         { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
12653         // mov{s}<c>.w <Rd>, <Rm>
12654         { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
12655         // move immediate
12656         { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
12657         { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
12658         { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
12659         // mvn (immediate)
12660         { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
12661         // mvn (register)
12662         { 0xffffffc0, 0x000043c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
12663         { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
12664         // cmn (immediate)
12665         { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12666         // cmn (register)
12667         { 0xffffffc0, 0x000042c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
12668         { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12669         // cmp (immediate)
12670         { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
12671         { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
12672         // cmp (register) (Rn and Rm both from r0-r7)
12673         { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12674         // cmp (register) (Rn and Rm not both from r0-r7)
12675         { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12676         // asr (immediate)
12677         { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
12678         { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
12679         // asr (register)
12680         { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
12681         { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12682         // lsl (immediate)
12683         { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
12684         { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
12685         // lsl (register)
12686         { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
12687         { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
12688         // lsr (immediate)
12689         { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
12690         { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
12691         // lsr (register)
12692         { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
12693         { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12694         // rrx is a special case encoding of ror (immediate)
12695         { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
12696         // ror (immediate)
12697         { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
12698         // ror (register)
12699         { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
12700         { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
12701         // mul
12702         { 0xffffffc0, 0x00004340, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
12703         // mul
12704         { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
12705 
12706         // subs pc, lr and related instructions
12707         { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" },
12708 
12709         //----------------------------------------------------------------------
12710         // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table;
12711         // otherwise the wrong instructions will be selected.
12712         //----------------------------------------------------------------------
12713 
12714         { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
12715         { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
12716 
12717         //----------------------------------------------------------------------
12718         // Load instructions
12719         //----------------------------------------------------------------------
12720         { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12721         { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
12722         { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12723         { 0xfffff800, 0x00006800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
12724         { 0xfffff800, 0x00009800, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
12725         { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
12726         { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
12727                   // Thumb2 PC-relative load into register
12728         { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
12729         { 0xfffffe00, 0x00005800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
12730         { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
12731         { 0xfffff800, 0x00007800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
12732         { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12733         { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" },
12734         { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
12735         { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
12736         { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
12737         { 0xfffff800, 0x00008800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"  },
12738         { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12739         { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"  },
12740         { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12741         { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
12742         { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12743         { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
12744         { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12745         { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
12746         { 0xfffffe00, 0x00005600, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
12747         { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"  },
12748         { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
12749         { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12750         { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12751         { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
12752         { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12753         { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
12754         { 0xfe100f00, 0xec100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12755         { 0xfe100f00, 0xec100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
12756         { 0xffe00f00, 0xed100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12757         { 0xff300f00, 0xed100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
12758         { 0xffb00000, 0xf9200000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12759         { 0xffb00300, 0xf9a00000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12760         { 0xffb00f00, 0xf9a00c00, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12761 
12762         //----------------------------------------------------------------------
12763         // Store instructions
12764         //----------------------------------------------------------------------
12765         { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12766         { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
12767         { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12768         { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
12769         { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
12770         { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
12771         { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
12772         { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
12773         { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
12774         { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
12775         { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
12776         { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
12777         { 0xfffffe00, 0x00005200, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
12778         { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12779         { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
12780         { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
12781         { 0xfe100f00, 0xec000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12782         { 0xfea00f00, 0xec000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12783         { 0xff300f00, 0xed000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12784         { 0xff300f00, 0xed000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12785         { 0xffb00000, 0xf9000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12786         { 0xffb00300, 0xf9800000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12787 
12788         //----------------------------------------------------------------------
12789         // Other instructions
12790         //----------------------------------------------------------------------
12791         { 0xffffffc0, 0x0000b240, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
12792         { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12793         { 0xffffffc0, 0x0000b200, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
12794         { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12795         { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
12796         { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12797         { 0xffffffc0, 0x0000b280, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
12798         { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12799     };
12800 
12801     const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode);
12802     for (size_t i=0; i<k_num_thumb_opcodes; ++i)
12803     {
12804         if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
12805             (g_thumb_opcodes[i].variants & arm_isa) != 0)
12806             return &g_thumb_opcodes[i];
12807     }
12808     return NULL;
12809 }
12810 
12811 bool
12812 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
12813 {
12814     m_arch = arch;
12815     m_arm_isa = 0;
12816     const char *arch_cstr = arch.GetArchitectureName ();
12817     if (arch_cstr)
12818     {
12819         if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
12820         else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
12821         else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
12822         else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
12823         else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
12824         else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
12825         else if (0 == ::strcasecmp(arch_cstr, "armv7s"))    m_arm_isa = ARMv7S;
12826         else if (0 == ::strcasecmp(arch_cstr, "arm"))       m_arm_isa = ARMvAll;
12827         else if (0 == ::strcasecmp(arch_cstr, "thumb"))     m_arm_isa = ARMvAll;
12828         else if (0 == ::strncasecmp(arch_cstr,"armv4", 5))  m_arm_isa = ARMv4;
12829         else if (0 == ::strncasecmp(arch_cstr,"armv6", 5))  m_arm_isa = ARMv6;
12830         else if (0 == ::strncasecmp(arch_cstr,"armv7", 5))  m_arm_isa = ARMv7;
12831         else if (0 == ::strncasecmp(arch_cstr,"armv8", 5))  m_arm_isa = ARMv8;
12832     }
12833     return m_arm_isa != 0;
12834 }
12835 
12836 bool
12837 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
12838 {
12839     if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
12840     {
12841         if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
12842             m_opcode_mode = eModeThumb;
12843         else
12844         {
12845             AddressClass addr_class = inst_addr.GetAddressClass();
12846 
12847             if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
12848                 m_opcode_mode = eModeARM;
12849             else if (addr_class == eAddressClassCodeAlternateISA)
12850                 m_opcode_mode = eModeThumb;
12851             else
12852                 return false;
12853         }
12854         if (m_opcode_mode == eModeThumb)
12855             m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
12856         else
12857             m_opcode_cpsr = CPSR_MODE_USR;
12858         return true;
12859     }
12860     return false;
12861 }
12862 
12863 bool
12864 EmulateInstructionARM::ReadInstruction ()
12865 {
12866     bool success = false;
12867     m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
12868     if (success)
12869     {
12870         addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
12871         if (success)
12872         {
12873             Context read_inst_context;
12874             read_inst_context.type = eContextReadOpcode;
12875             read_inst_context.SetNoArgs ();
12876 
12877             if (m_opcode_cpsr & MASK_CPSR_T)
12878             {
12879                 m_opcode_mode = eModeThumb;
12880                 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
12881 
12882                 if (success)
12883                 {
12884                     if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
12885                     {
12886                         m_opcode.SetOpcode16 (thumb_opcode);
12887                     }
12888                     else
12889                     {
12890                         m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success));
12891                     }
12892                 }
12893             }
12894             else
12895             {
12896                 m_opcode_mode = eModeARM;
12897                 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success));
12898             }
12899         }
12900     }
12901     if (!success)
12902     {
12903         m_opcode_mode = eModeInvalid;
12904         m_addr = LLDB_INVALID_ADDRESS;
12905     }
12906     return success;
12907 }
12908 
12909 uint32_t
12910 EmulateInstructionARM::ArchVersion ()
12911 {
12912     return m_arm_isa;
12913 }
12914 
12915 bool
12916 EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional)
12917 {
12918    // If we are ignoring conditions, then always return true.
12919    // this allows us to iterate over disassembly code and still
12920    // emulate an instruction even if we don't have all the right
12921    // bits set in the CPSR register...
12922     if (m_ignore_conditions)
12923         return true;
12924 
12925     if (is_conditional)
12926         *is_conditional = true;
12927 
12928     const uint32_t cond = CurrentCond (opcode);
12929 
12930     if (cond == UINT32_MAX)
12931         return false;
12932 
12933     bool result = false;
12934     switch (UnsignedBits(cond, 3, 1))
12935     {
12936     case 0:
12937 		if (m_opcode_cpsr == 0)
12938 			result = true;
12939         else
12940             result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
12941 		break;
12942     case 1:
12943         if (m_opcode_cpsr == 0)
12944             result = true;
12945         else
12946             result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
12947 		break;
12948     case 2:
12949         if (m_opcode_cpsr == 0)
12950             result = true;
12951         else
12952             result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
12953 		break;
12954     case 3:
12955         if (m_opcode_cpsr == 0)
12956             result = true;
12957         else
12958             result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
12959 		break;
12960     case 4:
12961         if (m_opcode_cpsr == 0)
12962             result = true;
12963         else
12964             result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12965 		break;
12966     case 5:
12967         if (m_opcode_cpsr == 0)
12968             result = true;
12969         else
12970 		{
12971             bool n = (m_opcode_cpsr & MASK_CPSR_N);
12972             bool v = (m_opcode_cpsr & MASK_CPSR_V);
12973             result = n == v;
12974         }
12975         break;
12976     case 6:
12977         if (m_opcode_cpsr == 0)
12978             result = true;
12979         else
12980 		{
12981             bool n = (m_opcode_cpsr & MASK_CPSR_N);
12982             bool v = (m_opcode_cpsr & MASK_CPSR_V);
12983             result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12984         }
12985         break;
12986     case 7:
12987         // Always execute (cond == 0b1110, or the special 0b1111 which gives
12988         // opcodes different meanings, but always means execution happpens.
12989         if (is_conditional)
12990             *is_conditional = false;
12991         result = true;
12992         break;
12993     }
12994 
12995     if (cond & 1)
12996         result = !result;
12997     return result;
12998 }
12999 
13000 uint32_t
13001 EmulateInstructionARM::CurrentCond (const uint32_t opcode)
13002 {
13003     switch (m_opcode_mode)
13004     {
13005     case eModeInvalid:
13006         break;
13007 
13008     case eModeARM:
13009         return UnsignedBits(opcode, 31, 28);
13010 
13011     case eModeThumb:
13012         // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
13013         // 'cond' field of the encoding.
13014         {
13015             const uint32_t byte_size = m_opcode.GetByteSize();
13016             if (byte_size == 2)
13017             {
13018                 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f)
13019                     return Bits32(opcode, 11, 7);
13020             }
13021             else if (byte_size == 4)
13022             {
13023                 if (Bits32(opcode, 31, 27) == 0x1e &&
13024                     Bits32(opcode, 15, 14) == 0x02 &&
13025                     Bits32(opcode, 12, 12) == 0x00 &&
13026                     Bits32(opcode, 25, 22) <= 0x0d)
13027                 {
13028                     return Bits32(opcode, 25, 22);
13029                 }
13030             }
13031             else
13032                 // We have an invalid thumb instruction, let's bail out.
13033                 break;
13034 
13035             return m_it_session.GetCond();
13036         }
13037     }
13038     return UINT32_MAX;  // Return invalid value
13039 }
13040 
13041 bool
13042 EmulateInstructionARM::InITBlock()
13043 {
13044     return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13045 }
13046 
13047 bool
13048 EmulateInstructionARM::LastInITBlock()
13049 {
13050     return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13051 }
13052 
13053 bool
13054 EmulateInstructionARM::BadMode (uint32_t mode)
13055 {
13056 
13057     switch (mode)
13058     {
13059         case 16: return false; // '10000'
13060         case 17: return false; // '10001'
13061         case 18: return false; // '10010'
13062         case 19: return false; // '10011'
13063         case 22: return false; // '10110'
13064         case 23: return false; // '10111'
13065         case 27: return false; // '11011'
13066         case 31: return false; // '11111'
13067         default: return true;
13068     }
13069     return true;
13070 }
13071 
13072 bool
13073 EmulateInstructionARM::CurrentModeIsPrivileged ()
13074 {
13075     uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
13076 
13077     if (BadMode (mode))
13078         return false;
13079 
13080     if (mode == 16)
13081         return false;
13082 
13083     return true;
13084 }
13085 
13086 void
13087 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
13088 {
13089     bool privileged = CurrentModeIsPrivileged();
13090 
13091     uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20;
13092 
13093     if (BitIsSet (bytemask, 3))
13094     {
13095         tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
13096         if (affect_execstate)
13097             tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
13098     }
13099 
13100     if (BitIsSet (bytemask, 2))
13101     {
13102         tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
13103     }
13104 
13105     if (BitIsSet (bytemask, 1))
13106     {
13107         if (affect_execstate)
13108             tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
13109         tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
13110         if (privileged)
13111             tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
13112     }
13113 
13114     if (BitIsSet (bytemask, 0))
13115     {
13116         if (privileged)
13117             tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
13118         if (affect_execstate)
13119             tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
13120         if (privileged)
13121             tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
13122     }
13123 
13124     m_opcode_cpsr = tmp_cpsr;
13125 }
13126 
13127 
13128 bool
13129 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
13130 {
13131     addr_t target;
13132 
13133     // Check the current instruction set.
13134     if (CurrentInstrSet() == eModeARM)
13135         target = addr & 0xfffffffc;
13136     else
13137         target = addr & 0xfffffffe;
13138 
13139     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13140         return false;
13141 
13142     return true;
13143 }
13144 
13145 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
13146 bool
13147 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
13148 {
13149     addr_t target;
13150     // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
13151     // we want to record it and issue a WriteRegister callback so the clients
13152     // can track the mode changes accordingly.
13153     bool cpsr_changed = false;
13154 
13155     if (BitIsSet(addr, 0))
13156     {
13157         if (CurrentInstrSet() != eModeThumb)
13158         {
13159             SelectInstrSet(eModeThumb);
13160             cpsr_changed = true;
13161         }
13162         target = addr & 0xfffffffe;
13163         context.SetISA (eModeThumb);
13164     }
13165     else if (BitIsClear(addr, 1))
13166     {
13167         if (CurrentInstrSet() != eModeARM)
13168         {
13169             SelectInstrSet(eModeARM);
13170             cpsr_changed = true;
13171         }
13172         target = addr & 0xfffffffc;
13173         context.SetISA (eModeARM);
13174     }
13175     else
13176         return false; // address<1:0> == '10' => UNPREDICTABLE
13177 
13178     if (cpsr_changed)
13179     {
13180         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13181             return false;
13182     }
13183     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13184         return false;
13185 
13186     return true;
13187 }
13188 
13189 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
13190 bool
13191 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
13192 {
13193     if (ArchVersion() >= ARMv5T)
13194         return BXWritePC(context, addr);
13195     else
13196         return BranchWritePC((const Context)context, addr);
13197 }
13198 
13199 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
13200 bool
13201 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
13202 {
13203     if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
13204         return BXWritePC(context, addr);
13205     else
13206         return BranchWritePC((const Context)context, addr);
13207 }
13208 
13209 EmulateInstructionARM::Mode
13210 EmulateInstructionARM::CurrentInstrSet ()
13211 {
13212     return m_opcode_mode;
13213 }
13214 
13215 // Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
13216 // ReadInstruction() is performed.  This function has a side effect of updating
13217 // the m_new_inst_cpsr member variable if necessary.
13218 bool
13219 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
13220 {
13221     m_new_inst_cpsr = m_opcode_cpsr;
13222     switch (arm_or_thumb)
13223     {
13224     default:
13225         return false;
13226     case eModeARM:
13227         // Clear the T bit.
13228         m_new_inst_cpsr &= ~MASK_CPSR_T;
13229         break;
13230     case eModeThumb:
13231         // Set the T bit.
13232         m_new_inst_cpsr |= MASK_CPSR_T;
13233         break;
13234     }
13235     return true;
13236 }
13237 
13238 // This function returns TRUE if the processor currently provides support for
13239 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
13240 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
13241 bool
13242 EmulateInstructionARM::UnalignedSupport()
13243 {
13244     return (ArchVersion() >= ARMv7);
13245 }
13246 
13247 // The main addition and subtraction instructions can produce status information
13248 // about both unsigned carry and signed overflow conditions.  This status
13249 // information can be used to synthesize multi-word additions and subtractions.
13250 EmulateInstructionARM::AddWithCarryResult
13251 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
13252 {
13253     uint32_t result;
13254     uint8_t carry_out;
13255     uint8_t overflow;
13256 
13257     uint64_t unsigned_sum = x + y + carry_in;
13258     int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
13259 
13260     result = UnsignedBits(unsigned_sum, 31, 0);
13261 //    carry_out = (result == unsigned_sum ? 0 : 1);
13262     overflow = ((int32_t)result == signed_sum ? 0 : 1);
13263 
13264     if (carry_in)
13265         carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0;
13266     else
13267         carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0;
13268 
13269     AddWithCarryResult res = { result, carry_out, overflow };
13270     return res;
13271 }
13272 
13273 uint32_t
13274 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
13275 {
13276     uint32_t reg_kind, reg_num;
13277     switch (num)
13278     {
13279     case SP_REG:
13280         reg_kind = eRegisterKindGeneric;
13281         reg_num  = LLDB_REGNUM_GENERIC_SP;
13282         break;
13283     case LR_REG:
13284         reg_kind = eRegisterKindGeneric;
13285         reg_num  = LLDB_REGNUM_GENERIC_RA;
13286         break;
13287     case PC_REG:
13288         reg_kind = eRegisterKindGeneric;
13289         reg_num  = LLDB_REGNUM_GENERIC_PC;
13290         break;
13291     default:
13292         if (num < SP_REG)
13293         {
13294             reg_kind = eRegisterKindDWARF;
13295             reg_num  = dwarf_r0 + num;
13296         }
13297         else
13298         {
13299             //assert(0 && "Invalid register number");
13300             *success = false;
13301             return UINT32_MAX;
13302         }
13303         break;
13304     }
13305 
13306     // Read our register.
13307     uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
13308 
13309     // When executing an ARM instruction , PC reads as the address of the current
13310     // instruction plus 8.
13311     // When executing a Thumb instruction , PC reads as the address of the current
13312     // instruction plus 4.
13313     if (num == 15)
13314     {
13315         if (CurrentInstrSet() == eModeARM)
13316             val += 8;
13317         else
13318             val += 4;
13319     }
13320 
13321     return val;
13322 }
13323 
13324 // Write the result to the ARM core register Rd, and optionally update the
13325 // condition flags based on the result.
13326 //
13327 // This helper method tries to encapsulate the following pseudocode from the
13328 // ARM Architecture Reference Manual:
13329 //
13330 // if d == 15 then         // Can only occur for encoding A1
13331 //     ALUWritePC(result); // setflags is always FALSE here
13332 // else
13333 //     R[d] = result;
13334 //     if setflags then
13335 //         APSR.N = result<31>;
13336 //         APSR.Z = IsZeroBit(result);
13337 //         APSR.C = carry;
13338 //         // APSR.V unchanged
13339 //
13340 // In the above case, the API client does not pass in the overflow arg, which
13341 // defaults to ~0u.
13342 bool
13343 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
13344                                                   const uint32_t result,
13345                                                   const uint32_t Rd,
13346                                                   bool setflags,
13347                                                   const uint32_t carry,
13348                                                   const uint32_t overflow)
13349 {
13350     if (Rd == 15)
13351     {
13352         if (!ALUWritePC (context, result))
13353             return false;
13354     }
13355     else
13356     {
13357         uint32_t reg_kind, reg_num;
13358         switch (Rd)
13359         {
13360         case SP_REG:
13361             reg_kind = eRegisterKindGeneric;
13362             reg_num  = LLDB_REGNUM_GENERIC_SP;
13363             break;
13364         case LR_REG:
13365             reg_kind = eRegisterKindGeneric;
13366             reg_num  = LLDB_REGNUM_GENERIC_RA;
13367             break;
13368         default:
13369             reg_kind = eRegisterKindDWARF;
13370             reg_num  = dwarf_r0 + Rd;
13371         }
13372         if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
13373             return false;
13374         if (setflags)
13375             return WriteFlags (context, result, carry, overflow);
13376     }
13377     return true;
13378 }
13379 
13380 // This helper method tries to encapsulate the following pseudocode from the
13381 // ARM Architecture Reference Manual:
13382 //
13383 // APSR.N = result<31>;
13384 // APSR.Z = IsZeroBit(result);
13385 // APSR.C = carry;
13386 // APSR.V = overflow
13387 //
13388 // Default arguments can be specified for carry and overflow parameters, which means
13389 // not to update the respective flags.
13390 bool
13391 EmulateInstructionARM::WriteFlags (Context &context,
13392                                    const uint32_t result,
13393                                    const uint32_t carry,
13394                                    const uint32_t overflow)
13395 {
13396     m_new_inst_cpsr = m_opcode_cpsr;
13397     SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
13398     SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
13399     if (carry != ~0u)
13400         SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
13401     if (overflow != ~0u)
13402         SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
13403     if (m_new_inst_cpsr != m_opcode_cpsr)
13404     {
13405         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13406             return false;
13407     }
13408     return true;
13409 }
13410 
13411 bool
13412 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
13413 {
13414     // Advance the ITSTATE bits to their values for the next instruction.
13415     if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
13416         m_it_session.ITAdvance();
13417 
13418     ARMOpcode *opcode_data = NULL;
13419 
13420     if (m_opcode_mode == eModeThumb)
13421         opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13422     else if (m_opcode_mode == eModeARM)
13423         opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13424 
13425     if (opcode_data == NULL)
13426         return false;
13427 
13428     const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
13429     m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
13430 
13431     bool success = false;
13432     if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
13433     {
13434         m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF,
13435                                                 dwarf_cpsr,
13436                                                 0,
13437                                                 &success);
13438     }
13439 
13440     // Only return false if we are unable to read the CPSR if we care about conditions
13441     if (success == false && m_ignore_conditions == false)
13442         return false;
13443 
13444     uint32_t orig_pc_value = 0;
13445     if (auto_advance_pc)
13446     {
13447         orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13448         if (!success)
13449             return false;
13450     }
13451 
13452     // Call the Emulate... function.
13453     success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
13454     if (!success)
13455         return false;
13456 
13457     if (auto_advance_pc)
13458     {
13459         uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13460         if (!success)
13461             return false;
13462 
13463         if (auto_advance_pc && (after_pc_value == orig_pc_value))
13464         {
13465             if (opcode_data->size == eSize32)
13466                 after_pc_value += 4;
13467             else if (opcode_data->size == eSize16)
13468                 after_pc_value += 2;
13469 
13470             EmulateInstruction::Context context;
13471             context.type = eContextAdvancePC;
13472             context.SetNoArgs();
13473             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
13474                 return false;
13475 
13476         }
13477     }
13478     return true;
13479 }
13480 
13481 bool
13482 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data)
13483 {
13484     if (!test_data)
13485     {
13486         out_stream->Printf ("TestEmulation: Missing test data.\n");
13487         return false;
13488     }
13489 
13490     static ConstString opcode_key ("opcode");
13491     static ConstString before_key ("before_state");
13492     static ConstString after_key ("after_state");
13493 
13494     OptionValueSP value_sp = test_data->GetValueForKey (opcode_key);
13495 
13496     uint32_t test_opcode;
13497     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64))
13498     {
13499         out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n");
13500         return false;
13501     }
13502     test_opcode = value_sp->GetUInt64Value ();
13503 
13504     if (arch.GetTriple().getArch() == llvm::Triple::arm)
13505     {
13506         m_opcode_mode = eModeARM;
13507         m_opcode.SetOpcode32 (test_opcode);
13508     }
13509     else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
13510     {
13511         m_opcode_mode = eModeThumb;
13512         if (test_opcode < 0x10000)
13513             m_opcode.SetOpcode16 (test_opcode);
13514         else
13515             m_opcode.SetOpcode32 (test_opcode);
13516 
13517     }
13518     else
13519     {
13520         out_stream->Printf ("TestEmulation:  Invalid arch.\n");
13521         return false;
13522     }
13523 
13524     EmulationStateARM before_state;
13525     EmulationStateARM after_state;
13526 
13527     value_sp = test_data->GetValueForKey (before_key);
13528     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13529     {
13530         out_stream->Printf ("TestEmulation:  Failed to find 'before' state.\n");
13531         return false;
13532     }
13533 
13534     OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary ();
13535     if (!before_state.LoadStateFromDictionary (state_dictionary))
13536     {
13537         out_stream->Printf ("TestEmulation:  Failed loading 'before' state.\n");
13538         return false;
13539     }
13540 
13541     value_sp = test_data->GetValueForKey (after_key);
13542     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13543     {
13544         out_stream->Printf ("TestEmulation:  Failed to find 'after' state.\n");
13545         return false;
13546     }
13547 
13548     state_dictionary = value_sp->GetAsDictionary ();
13549     if (!after_state.LoadStateFromDictionary (state_dictionary))
13550     {
13551         out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n");
13552         return false;
13553     }
13554 
13555     SetBaton ((void *) &before_state);
13556     SetCallbacks (&EmulationStateARM::ReadPseudoMemory,
13557                   &EmulationStateARM::WritePseudoMemory,
13558                   &EmulationStateARM::ReadPseudoRegister,
13559                   &EmulationStateARM::WritePseudoRegister);
13560 
13561     bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC);
13562     if (!success)
13563     {
13564         out_stream->Printf ("TestEmulation:  EvaluateInstruction() failed.\n");
13565         return false;
13566     }
13567 
13568     success = before_state.CompareState (after_state);
13569     if (!success)
13570         out_stream->Printf ("TestEmulation:  'before' and 'after' states do not match.\n");
13571 
13572     return success;
13573 }
13574 //
13575 //
13576 //const char *
13577 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
13578 //{
13579 //    if (reg_kind == eRegisterKindGeneric)
13580 //    {
13581 //        switch (reg_num)
13582 //        {
13583 //        case LLDB_REGNUM_GENERIC_PC:    return "pc";
13584 //        case LLDB_REGNUM_GENERIC_SP:    return "sp";
13585 //        case LLDB_REGNUM_GENERIC_FP:    return "fp";
13586 //        case LLDB_REGNUM_GENERIC_RA:    return "lr";
13587 //        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
13588 //        default: return NULL;
13589 //        }
13590 //    }
13591 //    else if (reg_kind == eRegisterKindDWARF)
13592 //    {
13593 //        return GetARMDWARFRegisterName (reg_num);
13594 //    }
13595 //    return NULL;
13596 //}
13597 //
13598 bool
13599 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
13600 {
13601     unwind_plan.Clear();
13602     unwind_plan.SetRegisterKind (eRegisterKindDWARF);
13603 
13604     UnwindPlan::RowSP row(new UnwindPlan::Row);
13605 
13606     // Our previous Call Frame Address is the stack pointer
13607     row->SetCFARegister (dwarf_sp);
13608 
13609     // Our previous PC is in the LR
13610     row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true);
13611     unwind_plan.AppendRow (row);
13612 
13613     // All other registers are the same.
13614 
13615     unwind_plan.SetSourceName ("EmulateInstructionARM");
13616     unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
13617     unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
13618     return true;
13619 }
13620