1 //===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include <stdlib.h>
11 
12 #include "EmulateInstructionARM.h"
13 #include "EmulationStateARM.h"
14 #include "lldb/Core/ArchSpec.h"
15 #include "lldb/Core/Address.h"
16 #include "lldb/Core/ConstString.h"
17 #include "lldb/Core/PluginManager.h"
18 #include "lldb/Core/Stream.h"
19 #include "lldb/Symbol/UnwindPlan.h"
20 
21 #include "Plugins/Process/Utility/ARMDefines.h"
22 #include "Plugins/Process/Utility/ARMUtils.h"
23 #include "Utility/ARM_DWARF_Registers.h"
24 
25 #include "llvm/Support/MathExtras.h" // for SignExtend32 template function
26                                      // and CountTrailingZeros_32 function
27 
28 using namespace lldb;
29 using namespace lldb_private;
30 
31 // Convenient macro definitions.
32 #define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS)
33 #define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS)
34 
35 #define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
36 
37 //----------------------------------------------------------------------
38 //
39 // ITSession implementation
40 //
41 //----------------------------------------------------------------------
42 
43 // A8.6.50
44 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
45 static uint32_t
46 CountITSize (uint32_t ITMask) {
47     // First count the trailing zeros of the IT mask.
48     uint32_t TZ = llvm::CountTrailingZeros_32(ITMask);
49     if (TZ > 3)
50     {
51         printf("Encoding error: IT Mask '0000'\n");
52         return 0;
53     }
54     return (4 - TZ);
55 }
56 
57 // Init ITState.  Note that at least one bit is always 1 in mask.
58 bool ITSession::InitIT(uint32_t bits7_0)
59 {
60     ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
61     if (ITCounter == 0)
62         return false;
63 
64     // A8.6.50 IT
65     unsigned short FirstCond = Bits32(bits7_0, 7, 4);
66     if (FirstCond == 0xF)
67     {
68         printf("Encoding error: IT FirstCond '1111'\n");
69         return false;
70     }
71     if (FirstCond == 0xE && ITCounter != 1)
72     {
73         printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
74         return false;
75     }
76 
77     ITState = bits7_0;
78     return true;
79 }
80 
81 // Update ITState if necessary.
82 void ITSession::ITAdvance()
83 {
84     //assert(ITCounter);
85     --ITCounter;
86     if (ITCounter == 0)
87         ITState = 0;
88     else
89     {
90         unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
91         SetBits32(ITState, 4, 0, NewITState4_0);
92     }
93 }
94 
95 // Return true if we're inside an IT Block.
96 bool ITSession::InITBlock()
97 {
98     return ITCounter != 0;
99 }
100 
101 // Return true if we're the last instruction inside an IT Block.
102 bool ITSession::LastInITBlock()
103 {
104     return ITCounter == 1;
105 }
106 
107 // Get condition bits for the current thumb instruction.
108 uint32_t ITSession::GetCond()
109 {
110     if (InITBlock())
111         return Bits32(ITState, 7, 4);
112     else
113         return COND_AL;
114 }
115 
116 // ARM constants used during decoding
117 #define REG_RD          0
118 #define LDM_REGLIST     1
119 #define SP_REG          13
120 #define LR_REG          14
121 #define PC_REG          15
122 #define PC_REGLIST_BIT  0x8000
123 
124 #define ARMv4     (1u << 0)
125 #define ARMv4T    (1u << 1)
126 #define ARMv5T    (1u << 2)
127 #define ARMv5TE   (1u << 3)
128 #define ARMv5TEJ  (1u << 4)
129 #define ARMv6     (1u << 5)
130 #define ARMv6K    (1u << 6)
131 #define ARMv6T2   (1u << 7)
132 #define ARMv7     (1u << 8)
133 #define ARMv7S    (1u << 9)
134 #define ARMv8     (1u << 10)
135 #define ARMvAll   (0xffffffffu)
136 
137 #define ARMV4T_ABOVE  (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
138 #define ARMV5_ABOVE   (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
139 #define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
140 #define ARMV5J_ABOVE  (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
141 #define ARMV6_ABOVE   (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
142 #define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv7S|ARMv8)
143 #define ARMV7_ABOVE   (ARMv7|ARMv7S|ARMv8)
144 
145 #define No_VFP  0
146 #define VFPv1   (1u << 1)
147 #define VFPv2   (1u << 2)
148 #define VFPv3   (1u << 3)
149 #define AdvancedSIMD (1u << 4)
150 
151 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
152 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
153 #define VFPv2v3     (VFPv2 | VFPv3)
154 
155 //----------------------------------------------------------------------
156 //
157 // EmulateInstructionARM implementation
158 //
159 //----------------------------------------------------------------------
160 
161 void
162 EmulateInstructionARM::Initialize ()
163 {
164     PluginManager::RegisterPlugin (GetPluginNameStatic (),
165                                    GetPluginDescriptionStatic (),
166                                    CreateInstance);
167 }
168 
169 void
170 EmulateInstructionARM::Terminate ()
171 {
172     PluginManager::UnregisterPlugin (CreateInstance);
173 }
174 
175 const char *
176 EmulateInstructionARM::GetPluginNameStatic ()
177 {
178     return "lldb.emulate-instruction.arm";
179 }
180 
181 const char *
182 EmulateInstructionARM::GetPluginDescriptionStatic ()
183 {
184     return "Emulate instructions for the ARM architecture.";
185 }
186 
187 EmulateInstruction *
188 EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type)
189 {
190     if (EmulateInstructionARM::SupportsEmulatingIntructionsOfTypeStatic(inst_type))
191     {
192         if (arch.GetTriple().getArch() == llvm::Triple::arm)
193         {
194             std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
195 
196             if (emulate_insn_ap.get())
197                 return emulate_insn_ap.release();
198         }
199         else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
200         {
201             std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
202 
203             if (emulate_insn_ap.get())
204                 return emulate_insn_ap.release();
205         }
206     }
207 
208     return NULL;
209 }
210 
211 bool
212 EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch)
213 {
214     if (arch.GetTriple().getArch () == llvm::Triple::arm)
215         return true;
216     else if (arch.GetTriple().getArch () == llvm::Triple::thumb)
217         return true;
218 
219     return false;
220 }
221 
222 // Write "bits (32) UNKNOWN" to memory address "address".  Helper function for many ARM instructions.
223 bool
224 EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address)
225 {
226     EmulateInstruction::Context context;
227     context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
228     context.SetNoArgs ();
229 
230     uint32_t random_data = rand ();
231     const uint32_t addr_byte_size = GetAddressByteSize();
232 
233     if (!MemAWrite (context, address, random_data, addr_byte_size))
234         return false;
235 
236     return true;
237 }
238 
239 // Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM instructions.
240 bool
241 EmulateInstructionARM::WriteBits32Unknown (int n)
242 {
243     EmulateInstruction::Context context;
244     context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
245     context.SetNoArgs ();
246 
247     bool success;
248     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
249 
250     if (!success)
251         return false;
252 
253     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
254         return false;
255 
256     return true;
257 }
258 
259 bool
260 EmulateInstructionARM::GetRegisterInfo (uint32_t reg_kind, uint32_t reg_num, RegisterInfo &reg_info)
261 {
262     if (reg_kind == eRegisterKindGeneric)
263     {
264         switch (reg_num)
265         {
266             case LLDB_REGNUM_GENERIC_PC:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break;
267             case LLDB_REGNUM_GENERIC_SP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break;
268             case LLDB_REGNUM_GENERIC_FP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break;
269             case LLDB_REGNUM_GENERIC_RA:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break;
270             case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break;
271             default: return false;
272         }
273     }
274 
275     if (reg_kind == eRegisterKindDWARF)
276         return GetARMDWARFRegisterInfo(reg_num, reg_info);
277     return false;
278 }
279 
280 uint32_t
281 EmulateInstructionARM::GetFramePointerRegisterNumber () const
282 {
283     if (m_opcode_mode == eModeThumb || m_arch.GetTriple().getOS() == llvm::Triple::Darwin)
284         return 7;
285     else
286         return 11;
287 }
288 
289 uint32_t
290 EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const
291 {
292     if (m_opcode_mode == eModeThumb || m_arch.GetTriple().getOS() == llvm::Triple::Darwin)
293         return dwarf_r7;
294     else
295         return dwarf_r11;
296 }
297 
298 // Push Multiple Registers stores multiple registers to the stack, storing to
299 // consecutive memory locations ending just below the address in SP, and updates
300 // SP to point to the start of the stored data.
301 bool
302 EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding)
303 {
304 #if 0
305     // ARM pseudo code...
306     if (ConditionPassed())
307     {
308         EncodingSpecificOperations();
309         NullCheckIfThumbEE(13);
310         address = SP - 4*BitCount(registers);
311 
312         for (i = 0 to 14)
313         {
314             if (registers<i> == '1')
315             {
316                 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
317                     MemA[address,4] = bits(32) UNKNOWN;
318                 else
319                     MemA[address,4] = R[i];
320                 address = address + 4;
321             }
322         }
323 
324         if (registers<15> == '1') // Only possible for encoding A1 or A2
325             MemA[address,4] = PCStoreValue();
326 
327         SP = SP - 4*BitCount(registers);
328     }
329 #endif
330 
331     bool conditional = false;
332     bool success = false;
333     if (ConditionPassed(opcode, &conditional))
334     {
335         const uint32_t addr_byte_size = GetAddressByteSize();
336         const addr_t sp = ReadCoreReg (SP_REG, &success);
337         if (!success)
338             return false;
339         uint32_t registers = 0;
340         uint32_t Rt; // the source register
341         switch (encoding) {
342         case eEncodingT1:
343             registers = Bits32(opcode, 7, 0);
344             // The M bit represents LR.
345             if (Bit32(opcode, 8))
346                 registers |= (1u << 14);
347             // if BitCount(registers) < 1 then UNPREDICTABLE;
348             if (BitCount(registers) < 1)
349                 return false;
350             break;
351         case eEncodingT2:
352             // Ignore bits 15 & 13.
353             registers = Bits32(opcode, 15, 0) & ~0xa000;
354             // if BitCount(registers) < 2 then UNPREDICTABLE;
355             if (BitCount(registers) < 2)
356                 return false;
357             break;
358         case eEncodingT3:
359             Rt = Bits32(opcode, 15, 12);
360             // if BadReg(t) then UNPREDICTABLE;
361             if (BadReg(Rt))
362                 return false;
363             registers = (1u << Rt);
364             break;
365         case eEncodingA1:
366             registers = Bits32(opcode, 15, 0);
367             // Instead of return false, let's handle the following case as well,
368             // which amounts to pushing one reg onto the full descending stacks.
369             // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
370             break;
371         case eEncodingA2:
372             Rt = Bits32(opcode, 15, 12);
373             // if t == 13 then UNPREDICTABLE;
374             if (Rt == dwarf_sp)
375                 return false;
376             registers = (1u << Rt);
377             break;
378         default:
379             return false;
380         }
381         addr_t sp_offset = addr_byte_size * BitCount (registers);
382         addr_t addr = sp - sp_offset;
383         uint32_t i;
384 
385         EmulateInstruction::Context context;
386         if (conditional)
387             context.type = EmulateInstruction::eContextRegisterStore;
388         else
389             context.type = EmulateInstruction::eContextPushRegisterOnStack;
390         RegisterInfo reg_info;
391         RegisterInfo sp_reg;
392         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
393         for (i=0; i<15; ++i)
394         {
395             if (BitIsSet (registers, i))
396             {
397                 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info);
398                 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
399                 uint32_t reg_value = ReadCoreReg(i, &success);
400                 if (!success)
401                     return false;
402                 if (!MemAWrite (context, addr, reg_value, addr_byte_size))
403                     return false;
404                 addr += addr_byte_size;
405             }
406         }
407 
408         if (BitIsSet (registers, 15))
409         {
410             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info);
411             context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
412             const uint32_t pc = ReadCoreReg(PC_REG, &success);
413             if (!success)
414                 return false;
415             if (!MemAWrite (context, addr, pc, addr_byte_size))
416                 return false;
417         }
418 
419         context.type = EmulateInstruction::eContextAdjustStackPointer;
420         context.SetImmediateSigned (-sp_offset);
421 
422         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
423             return false;
424     }
425     return true;
426 }
427 
428 // Pop Multiple Registers loads multiple registers from the stack, loading from
429 // consecutive memory locations staring at the address in SP, and updates
430 // SP to point just above the loaded data.
431 bool
432 EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding)
433 {
434 #if 0
435     // ARM pseudo code...
436     if (ConditionPassed())
437     {
438         EncodingSpecificOperations(); NullCheckIfThumbEE(13);
439         address = SP;
440         for i = 0 to 14
441             if registers<i> == '1' then
442                 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
443         if registers<15> == '1' then
444             if UnalignedAllowed then
445                 LoadWritePC(MemU[address,4]);
446             else
447                 LoadWritePC(MemA[address,4]);
448         if registers<13> == '0' then SP = SP + 4*BitCount(registers);
449         if registers<13> == '1' then SP = bits(32) UNKNOWN;
450     }
451 #endif
452 
453     bool success = false;
454 
455     bool conditional = false;
456     if (ConditionPassed(opcode, &conditional))
457     {
458         const uint32_t addr_byte_size = GetAddressByteSize();
459         const addr_t sp = ReadCoreReg (SP_REG, &success);
460         if (!success)
461             return false;
462         uint32_t registers = 0;
463         uint32_t Rt; // the destination register
464         switch (encoding) {
465         case eEncodingT1:
466             registers = Bits32(opcode, 7, 0);
467             // The P bit represents PC.
468             if (Bit32(opcode, 8))
469                 registers |= (1u << 15);
470             // if BitCount(registers) < 1 then UNPREDICTABLE;
471             if (BitCount(registers) < 1)
472                 return false;
473             break;
474         case eEncodingT2:
475             // Ignore bit 13.
476             registers = Bits32(opcode, 15, 0) & ~0x2000;
477             // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
478             if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
479                 return false;
480             // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
481             if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
482                 return false;
483             break;
484         case eEncodingT3:
485             Rt = Bits32(opcode, 15, 12);
486             // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
487             if (Rt == 13)
488                 return false;
489             if (Rt == 15 && InITBlock() && !LastInITBlock())
490                 return false;
491             registers = (1u << Rt);
492             break;
493         case eEncodingA1:
494             registers = Bits32(opcode, 15, 0);
495             // Instead of return false, let's handle the following case as well,
496             // which amounts to popping one reg from the full descending stacks.
497             // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
498 
499             // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
500             if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
501                 return false;
502             break;
503         case eEncodingA2:
504             Rt = Bits32(opcode, 15, 12);
505             // if t == 13 then UNPREDICTABLE;
506             if (Rt == dwarf_sp)
507                 return false;
508             registers = (1u << Rt);
509             break;
510         default:
511             return false;
512         }
513         addr_t sp_offset = addr_byte_size * BitCount (registers);
514         addr_t addr = sp;
515         uint32_t i, data;
516 
517         EmulateInstruction::Context context;
518         if (conditional)
519             context.type = EmulateInstruction::eContextRegisterLoad;
520         else
521             context.type = EmulateInstruction::eContextPopRegisterOffStack;
522 
523         RegisterInfo sp_reg;
524         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
525 
526         for (i=0; i<15; ++i)
527         {
528             if (BitIsSet (registers, i))
529             {
530                 context.SetRegisterPlusOffset (sp_reg, addr - sp);
531                 data = MemARead(context, addr, 4, 0, &success);
532                 if (!success)
533                     return false;
534                 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data))
535                     return false;
536                 addr += addr_byte_size;
537             }
538         }
539 
540         if (BitIsSet (registers, 15))
541         {
542             context.SetRegisterPlusOffset (sp_reg, addr - sp);
543             data = MemARead(context, addr, 4, 0, &success);
544             if (!success)
545                 return false;
546             // In ARMv5T and above, this is an interworking branch.
547             if (!LoadWritePC(context, data))
548                 return false;
549             addr += addr_byte_size;
550         }
551 
552         context.type = EmulateInstruction::eContextAdjustStackPointer;
553         context.SetImmediateSigned (sp_offset);
554 
555         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
556             return false;
557     }
558     return true;
559 }
560 
561 // Set r7 or ip to point to saved value residing within the stack.
562 // ADD (SP plus immediate)
563 bool
564 EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding)
565 {
566 #if 0
567     // ARM pseudo code...
568     if (ConditionPassed())
569     {
570         EncodingSpecificOperations();
571         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
572         if d == 15 then
573            ALUWritePC(result); // setflags is always FALSE here
574         else
575             R[d] = result;
576             if setflags then
577                 APSR.N = result<31>;
578                 APSR.Z = IsZeroBit(result);
579                 APSR.C = carry;
580                 APSR.V = overflow;
581     }
582 #endif
583 
584     bool success = false;
585 
586     if (ConditionPassed(opcode))
587     {
588         const addr_t sp = ReadCoreReg (SP_REG, &success);
589         if (!success)
590             return false;
591         uint32_t Rd; // the destination register
592         uint32_t imm32;
593         switch (encoding) {
594         case eEncodingT1:
595             Rd = 7;
596             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
597             break;
598         case eEncodingA1:
599             Rd = Bits32(opcode, 15, 12);
600             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
601             break;
602         default:
603             return false;
604         }
605         addr_t sp_offset = imm32;
606         addr_t addr = sp + sp_offset; // a pointer to the stack area
607 
608         EmulateInstruction::Context context;
609         context.type = eContextSetFramePointer;
610         RegisterInfo sp_reg;
611         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
612         context.SetRegisterPlusOffset (sp_reg, sp_offset);
613 
614         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
615             return false;
616     }
617     return true;
618 }
619 
620 // Set r7 or ip to the current stack pointer.
621 // MOV (register)
622 bool
623 EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding)
624 {
625 #if 0
626     // ARM pseudo code...
627     if (ConditionPassed())
628     {
629         EncodingSpecificOperations();
630         result = R[m];
631         if d == 15 then
632             ALUWritePC(result); // setflags is always FALSE here
633         else
634             R[d] = result;
635             if setflags then
636                 APSR.N = result<31>;
637                 APSR.Z = IsZeroBit(result);
638                 // APSR.C unchanged
639                 // APSR.V unchanged
640     }
641 #endif
642 
643     bool success = false;
644 
645     if (ConditionPassed(opcode))
646     {
647         const addr_t sp = ReadCoreReg (SP_REG, &success);
648         if (!success)
649             return false;
650         uint32_t Rd; // the destination register
651         switch (encoding) {
652         case eEncodingT1:
653             Rd = 7;
654             break;
655         case eEncodingA1:
656             Rd = 12;
657             break;
658         default:
659             return false;
660         }
661 
662         EmulateInstruction::Context context;
663         if (Rd == GetFramePointerRegisterNumber())
664             context.type = EmulateInstruction::eContextSetFramePointer;
665         else
666             context.type = EmulateInstruction::eContextRegisterPlusOffset;
667         RegisterInfo sp_reg;
668         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
669         context.SetRegisterPlusOffset (sp_reg, 0);
670 
671         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
672             return false;
673     }
674     return true;
675 }
676 
677 // Move from high register (r8-r15) to low register (r0-r7).
678 // MOV (register)
679 bool
680 EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding)
681 {
682     return EmulateMOVRdRm (opcode, encoding);
683 }
684 
685 // Move from register to register.
686 // MOV (register)
687 bool
688 EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding)
689 {
690 #if 0
691     // ARM pseudo code...
692     if (ConditionPassed())
693     {
694         EncodingSpecificOperations();
695         result = R[m];
696         if d == 15 then
697             ALUWritePC(result); // setflags is always FALSE here
698         else
699             R[d] = result;
700             if setflags then
701                 APSR.N = result<31>;
702                 APSR.Z = IsZeroBit(result);
703                 // APSR.C unchanged
704                 // APSR.V unchanged
705     }
706 #endif
707 
708     bool success = false;
709 
710     if (ConditionPassed(opcode))
711     {
712         uint32_t Rm; // the source register
713         uint32_t Rd; // the destination register
714         bool setflags;
715         switch (encoding) {
716         case eEncodingT1:
717             Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
718             Rm = Bits32(opcode, 6, 3);
719             setflags = false;
720             if (Rd == 15 && InITBlock() && !LastInITBlock())
721                 return false;
722             break;
723         case eEncodingT2:
724             Rd = Bits32(opcode, 2, 0);
725             Rm = Bits32(opcode, 5, 3);
726             setflags = true;
727             if (InITBlock())
728                 return false;
729             break;
730         case eEncodingT3:
731             Rd = Bits32(opcode, 11, 8);
732             Rm = Bits32(opcode, 3, 0);
733             setflags = BitIsSet(opcode, 20);
734             // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
735             if (setflags && (BadReg(Rd) || BadReg(Rm)))
736                 return false;
737             // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE;
738             if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
739                 return false;
740             break;
741         case eEncodingA1:
742             Rd = Bits32(opcode, 15, 12);
743             Rm = Bits32(opcode, 3, 0);
744             setflags = BitIsSet(opcode, 20);
745 
746             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
747             if (Rd == 15 && setflags)
748                 return EmulateSUBSPcLrEtc (opcode, encoding);
749             break;
750         default:
751             return false;
752         }
753         uint32_t result = ReadCoreReg(Rm, &success);
754         if (!success)
755             return false;
756 
757         // The context specifies that Rm is to be moved into Rd.
758         EmulateInstruction::Context context;
759         context.type = EmulateInstruction::eContextRegisterLoad;
760         RegisterInfo dwarf_reg;
761         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
762         context.SetRegister (dwarf_reg);
763 
764         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
765             return false;
766     }
767     return true;
768 }
769 
770 // Move (immediate) writes an immediate value to the destination register.  It
771 // can optionally update the condition flags based on the value.
772 // MOV (immediate)
773 bool
774 EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding)
775 {
776 #if 0
777     // ARM pseudo code...
778     if (ConditionPassed())
779     {
780         EncodingSpecificOperations();
781         result = imm32;
782         if d == 15 then         // Can only occur for ARM encoding
783             ALUWritePC(result); // setflags is always FALSE here
784         else
785             R[d] = result;
786             if setflags then
787                 APSR.N = result<31>;
788                 APSR.Z = IsZeroBit(result);
789                 APSR.C = carry;
790                 // APSR.V unchanged
791     }
792 #endif
793 
794     if (ConditionPassed(opcode))
795     {
796         uint32_t Rd; // the destination register
797         uint32_t imm32; // the immediate value to be written to Rd
798         uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
799                             // for setflags == false, this value is a don't care
800                             // initialized to 0 to silence the static analyzer
801         bool setflags;
802         switch (encoding) {
803             case eEncodingT1:
804                 Rd = Bits32(opcode, 10, 8);
805                 setflags = !InITBlock();
806                 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
807                 carry = APSR_C;
808 
809                 break;
810 
811             case eEncodingT2:
812                 Rd = Bits32(opcode, 11, 8);
813                 setflags = BitIsSet(opcode, 20);
814                 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
815                 if (BadReg(Rd))
816                   return false;
817 
818                 break;
819 
820             case eEncodingT3:
821             {
822                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32);
823                 Rd = Bits32 (opcode, 11, 8);
824                 setflags = false;
825                 uint32_t imm4 = Bits32 (opcode, 19, 16);
826                 uint32_t imm3 = Bits32 (opcode, 14, 12);
827                 uint32_t i = Bit32 (opcode, 26);
828                 uint32_t imm8 = Bits32 (opcode, 7, 0);
829                 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
830 
831                 // if BadReg(d) then UNPREDICTABLE;
832                 if (BadReg (Rd))
833                     return false;
834             }
835                 break;
836 
837             case eEncodingA1:
838                 // d = UInt(Rd); setflags = (S == �1�); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C);
839                 Rd = Bits32 (opcode, 15, 12);
840                 setflags = BitIsSet (opcode, 20);
841                 imm32 = ARMExpandImm_C (opcode, APSR_C, carry);
842 
843                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
844                 if ((Rd == 15) && setflags)
845                     return EmulateSUBSPcLrEtc (opcode, encoding);
846 
847                 break;
848 
849             case eEncodingA2:
850             {
851                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
852                 Rd = Bits32 (opcode, 15, 12);
853                 setflags = false;
854                 uint32_t imm4 = Bits32 (opcode, 19, 16);
855                 uint32_t imm12 = Bits32 (opcode, 11, 0);
856                 imm32 = (imm4 << 12) | imm12;
857 
858                 // if d == 15 then UNPREDICTABLE;
859                 if (Rd == 15)
860                     return false;
861             }
862                 break;
863 
864             default:
865                 return false;
866         }
867         uint32_t result = imm32;
868 
869         // The context specifies that an immediate is to be moved into Rd.
870         EmulateInstruction::Context context;
871         context.type = EmulateInstruction::eContextImmediate;
872         context.SetNoArgs ();
873 
874         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
875             return false;
876     }
877     return true;
878 }
879 
880 // MUL multiplies two register values.  The least significant 32 bits of the result are written to the destination
881 // register.  These 32 bits do not depend on whether the source register values are considered to be signed values or
882 // unsigned values.
883 //
884 // Optionally, it can update the condition flags based on the result.  In the Thumb instruction set, this option is
885 // limited to only a few forms of the instruction.
886 bool
887 EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding)
888 {
889 #if 0
890     if ConditionPassed() then
891         EncodingSpecificOperations();
892         operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
893         operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
894         result = operand1 * operand2;
895         R[d] = result<31:0>;
896         if setflags then
897             APSR.N = result<31>;
898             APSR.Z = IsZeroBit(result);
899             if ArchVersion() == 4 then
900                 APSR.C = bit UNKNOWN;
901             // else APSR.C unchanged
902             // APSR.V always unchanged
903 #endif
904 
905     if (ConditionPassed(opcode))
906     {
907         uint32_t d;
908         uint32_t n;
909         uint32_t m;
910         bool setflags;
911 
912         // EncodingSpecificOperations();
913         switch (encoding)
914         {
915             case eEncodingT1:
916                 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
917                 d = Bits32 (opcode, 2, 0);
918                 n = Bits32 (opcode, 5, 3);
919                 m = Bits32 (opcode, 2, 0);
920                 setflags = !InITBlock();
921 
922                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
923                 if ((ArchVersion() < ARMv6) && (d == n))
924                     return false;
925 
926                 break;
927 
928             case eEncodingT2:
929                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
930                 d = Bits32 (opcode, 11, 8);
931                 n = Bits32 (opcode, 19, 16);
932                 m = Bits32 (opcode, 3, 0);
933                 setflags = false;
934 
935                 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
936                 if (BadReg (d) || BadReg (n) || BadReg (m))
937                     return false;
938 
939                 break;
940 
941             case eEncodingA1:
942                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
943                 d = Bits32 (opcode, 19, 16);
944                 n = Bits32 (opcode, 3, 0);
945                 m = Bits32 (opcode, 11, 8);
946                 setflags = BitIsSet (opcode, 20);
947 
948                 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
949                 if ((d == 15) ||  (n == 15) || (m == 15))
950                     return false;
951 
952                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
953                 if ((ArchVersion() < ARMv6) && (d == n))
954                     return false;
955 
956                 break;
957 
958             default:
959                 return false;
960         }
961 
962         bool success = false;
963 
964         // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
965         uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
966         if (!success)
967             return false;
968 
969         // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
970         uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
971         if (!success)
972             return false;
973 
974         // result = operand1 * operand2;
975         uint64_t result = operand1 * operand2;
976 
977         // R[d] = result<31:0>;
978         RegisterInfo op1_reg;
979         RegisterInfo op2_reg;
980         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
981         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
982 
983         EmulateInstruction::Context context;
984         context.type = eContextArithmetic;
985         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
986 
987         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result)))
988             return false;
989 
990         // if setflags then
991         if (setflags)
992         {
993             // APSR.N = result<31>;
994             // APSR.Z = IsZeroBit(result);
995             m_new_inst_cpsr = m_opcode_cpsr;
996             SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31));
997             SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
998             if (m_new_inst_cpsr != m_opcode_cpsr)
999             {
1000                 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1001                     return false;
1002             }
1003 
1004             // if ArchVersion() == 4 then
1005                 // APSR.C = bit UNKNOWN;
1006         }
1007     }
1008     return true;
1009 }
1010 
1011 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register.
1012 // It can optionally update the condition flags based on the value.
1013 bool
1014 EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding)
1015 {
1016 #if 0
1017     // ARM pseudo code...
1018     if (ConditionPassed())
1019     {
1020         EncodingSpecificOperations();
1021         result = NOT(imm32);
1022         if d == 15 then         // Can only occur for ARM encoding
1023             ALUWritePC(result); // setflags is always FALSE here
1024         else
1025             R[d] = result;
1026             if setflags then
1027                 APSR.N = result<31>;
1028                 APSR.Z = IsZeroBit(result);
1029                 APSR.C = carry;
1030                 // APSR.V unchanged
1031     }
1032 #endif
1033 
1034     if (ConditionPassed(opcode))
1035     {
1036         uint32_t Rd; // the destination register
1037         uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1038         uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1039         bool setflags;
1040         switch (encoding) {
1041         case eEncodingT1:
1042             Rd = Bits32(opcode, 11, 8);
1043             setflags = BitIsSet(opcode, 20);
1044             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1045             break;
1046         case eEncodingA1:
1047             Rd = Bits32(opcode, 15, 12);
1048             setflags = BitIsSet(opcode, 20);
1049             imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1050 
1051             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1052             if (Rd == 15 && setflags)
1053                 return EmulateSUBSPcLrEtc (opcode, encoding);
1054             break;
1055         default:
1056             return false;
1057         }
1058         uint32_t result = ~imm32;
1059 
1060         // The context specifies that an immediate is to be moved into Rd.
1061         EmulateInstruction::Context context;
1062         context.type = EmulateInstruction::eContextImmediate;
1063         context.SetNoArgs ();
1064 
1065         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1066             return false;
1067     }
1068     return true;
1069 }
1070 
1071 // Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register.
1072 // It can optionally update the condition flags based on the result.
1073 bool
1074 EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding)
1075 {
1076 #if 0
1077     // ARM pseudo code...
1078     if (ConditionPassed())
1079     {
1080         EncodingSpecificOperations();
1081         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1082         result = NOT(shifted);
1083         if d == 15 then         // Can only occur for ARM encoding
1084             ALUWritePC(result); // setflags is always FALSE here
1085         else
1086             R[d] = result;
1087             if setflags then
1088                 APSR.N = result<31>;
1089                 APSR.Z = IsZeroBit(result);
1090                 APSR.C = carry;
1091                 // APSR.V unchanged
1092     }
1093 #endif
1094 
1095     if (ConditionPassed(opcode))
1096     {
1097         uint32_t Rm; // the source register
1098         uint32_t Rd; // the destination register
1099         ARM_ShifterType shift_t;
1100         uint32_t shift_n; // the shift applied to the value read from Rm
1101         bool setflags;
1102         uint32_t carry; // the carry bit after the shift operation
1103         switch (encoding) {
1104         case eEncodingT1:
1105             Rd = Bits32(opcode, 2, 0);
1106             Rm = Bits32(opcode, 5, 3);
1107             setflags = !InITBlock();
1108             shift_t = SRType_LSL;
1109             shift_n = 0;
1110             if (InITBlock())
1111                 return false;
1112             break;
1113         case eEncodingT2:
1114             Rd = Bits32(opcode, 11, 8);
1115             Rm = Bits32(opcode, 3, 0);
1116             setflags = BitIsSet(opcode, 20);
1117             shift_n = DecodeImmShiftThumb(opcode, shift_t);
1118             // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1119             if (BadReg(Rd) || BadReg(Rm))
1120                 return false;
1121             break;
1122         case eEncodingA1:
1123             Rd = Bits32(opcode, 15, 12);
1124             Rm = Bits32(opcode, 3, 0);
1125             setflags = BitIsSet(opcode, 20);
1126             shift_n = DecodeImmShiftARM(opcode, shift_t);
1127             break;
1128         default:
1129             return false;
1130         }
1131         bool success = false;
1132         uint32_t value = ReadCoreReg(Rm, &success);
1133         if (!success)
1134             return false;
1135 
1136         uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1137         if (!success)
1138             return false;
1139         uint32_t result = ~shifted;
1140 
1141         // The context specifies that an immediate is to be moved into Rd.
1142         EmulateInstruction::Context context;
1143         context.type = EmulateInstruction::eContextImmediate;
1144         context.SetNoArgs ();
1145 
1146         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1147             return false;
1148     }
1149     return true;
1150 }
1151 
1152 // PC relative immediate load into register, possibly followed by ADD (SP plus register).
1153 // LDR (literal)
1154 bool
1155 EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding)
1156 {
1157 #if 0
1158     // ARM pseudo code...
1159     if (ConditionPassed())
1160     {
1161         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1162         base = Align(PC,4);
1163         address = if add then (base + imm32) else (base - imm32);
1164         data = MemU[address,4];
1165         if t == 15 then
1166             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1167         elsif UnalignedSupport() || address<1:0> = '00' then
1168             R[t] = data;
1169         else // Can only apply before ARMv7
1170             if CurrentInstrSet() == InstrSet_ARM then
1171                 R[t] = ROR(data, 8*UInt(address<1:0>));
1172             else
1173                 R[t] = bits(32) UNKNOWN;
1174     }
1175 #endif
1176 
1177     if (ConditionPassed(opcode))
1178     {
1179         bool success = false;
1180         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1181         if (!success)
1182             return false;
1183 
1184         // PC relative immediate load context
1185         EmulateInstruction::Context context;
1186         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1187         RegisterInfo pc_reg;
1188         GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
1189         context.SetRegisterPlusOffset (pc_reg, 0);
1190 
1191         uint32_t Rt;    // the destination register
1192         uint32_t imm32; // immediate offset from the PC
1193         bool add;       // +imm32 or -imm32?
1194         addr_t base;    // the base address
1195         addr_t address; // the PC relative address
1196         uint32_t data;  // the literal data value from the PC relative load
1197         switch (encoding) {
1198         case eEncodingT1:
1199             Rt = Bits32(opcode, 10, 8);
1200             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1201             add = true;
1202             break;
1203         case eEncodingT2:
1204             Rt = Bits32(opcode, 15, 12);
1205             imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1206             add = BitIsSet(opcode, 23);
1207             if (Rt == 15 && InITBlock() && !LastInITBlock())
1208                 return false;
1209             break;
1210         default:
1211             return false;
1212         }
1213 
1214         base = Align(pc, 4);
1215         if (add)
1216             address = base + imm32;
1217         else
1218             address = base - imm32;
1219 
1220         context.SetRegisterPlusOffset(pc_reg, address - base);
1221         data = MemURead(context, address, 4, 0, &success);
1222         if (!success)
1223             return false;
1224 
1225         if (Rt == 15)
1226         {
1227             if (Bits32(address, 1, 0) == 0)
1228             {
1229                 // In ARMv5T and above, this is an interworking branch.
1230                 if (!LoadWritePC(context, data))
1231                     return false;
1232             }
1233             else
1234                 return false;
1235         }
1236         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
1237         {
1238             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
1239                 return false;
1240         }
1241         else // We don't handle ARM for now.
1242             return false;
1243 
1244     }
1245     return true;
1246 }
1247 
1248 // An add operation to adjust the SP.
1249 // ADD (SP plus immediate)
1250 bool
1251 EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding)
1252 {
1253 #if 0
1254     // ARM pseudo code...
1255     if (ConditionPassed())
1256     {
1257         EncodingSpecificOperations();
1258         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1259         if d == 15 then // Can only occur for ARM encoding
1260             ALUWritePC(result); // setflags is always FALSE here
1261         else
1262             R[d] = result;
1263             if setflags then
1264                 APSR.N = result<31>;
1265                 APSR.Z = IsZeroBit(result);
1266                 APSR.C = carry;
1267                 APSR.V = overflow;
1268     }
1269 #endif
1270 
1271     bool success = false;
1272 
1273     if (ConditionPassed(opcode))
1274     {
1275         const addr_t sp = ReadCoreReg (SP_REG, &success);
1276         if (!success)
1277             return false;
1278         uint32_t imm32; // the immediate operand
1279         uint32_t d;
1280         bool setflags;
1281         switch (encoding)
1282         {
1283             case eEncodingT1:
1284                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1285                 d = Bits32 (opcode, 10, 8);
1286                 setflags = false;
1287                 imm32 = (Bits32 (opcode, 7, 0) << 2);
1288 
1289                 break;
1290 
1291             case eEncodingT2:
1292                 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1293                 d = 13;
1294                 setflags = false;
1295                 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1296 
1297                 break;
1298 
1299             default:
1300                 return false;
1301         }
1302         addr_t sp_offset = imm32;
1303         addr_t addr = sp + sp_offset; // the adjusted stack pointer value
1304 
1305         EmulateInstruction::Context context;
1306         context.type = EmulateInstruction::eContextAdjustStackPointer;
1307         RegisterInfo sp_reg;
1308         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1309         context.SetRegisterPlusOffset (sp_reg, sp_offset);
1310 
1311         if (d == 15)
1312         {
1313             if (!ALUWritePC (context, addr))
1314                 return false;
1315         }
1316         else
1317         {
1318             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr))
1319                 return false;
1320         }
1321     }
1322     return true;
1323 }
1324 
1325 // An add operation to adjust the SP.
1326 // ADD (SP plus register)
1327 bool
1328 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding)
1329 {
1330 #if 0
1331     // ARM pseudo code...
1332     if (ConditionPassed())
1333     {
1334         EncodingSpecificOperations();
1335         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1336         (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1337         if d == 15 then
1338             ALUWritePC(result); // setflags is always FALSE here
1339         else
1340             R[d] = result;
1341             if setflags then
1342                 APSR.N = result<31>;
1343                 APSR.Z = IsZeroBit(result);
1344                 APSR.C = carry;
1345                 APSR.V = overflow;
1346     }
1347 #endif
1348 
1349     bool success = false;
1350 
1351     if (ConditionPassed(opcode))
1352     {
1353         const addr_t sp = ReadCoreReg (SP_REG, &success);
1354         if (!success)
1355             return false;
1356         uint32_t Rm; // the second operand
1357         switch (encoding) {
1358         case eEncodingT2:
1359             Rm = Bits32(opcode, 6, 3);
1360             break;
1361         default:
1362             return false;
1363         }
1364         int32_t reg_value = ReadCoreReg(Rm, &success);
1365         if (!success)
1366             return false;
1367 
1368         addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1369 
1370         EmulateInstruction::Context context;
1371         context.type = eContextArithmetic;
1372         RegisterInfo sp_reg;
1373         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1374 
1375         RegisterInfo other_reg;
1376         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1377         context.SetRegisterRegisterOperands (sp_reg, other_reg);
1378 
1379         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
1380             return false;
1381     }
1382     return true;
1383 }
1384 
1385 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
1386 // at a PC-relative address, and changes instruction set from ARM to Thumb, or
1387 // from Thumb to ARM.
1388 // BLX (immediate)
1389 bool
1390 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding)
1391 {
1392 #if 0
1393     // ARM pseudo code...
1394     if (ConditionPassed())
1395     {
1396         EncodingSpecificOperations();
1397         if CurrentInstrSet() == InstrSet_ARM then
1398             LR = PC - 4;
1399         else
1400             LR = PC<31:1> : '1';
1401         if targetInstrSet == InstrSet_ARM then
1402             targetAddress = Align(PC,4) + imm32;
1403         else
1404             targetAddress = PC + imm32;
1405         SelectInstrSet(targetInstrSet);
1406         BranchWritePC(targetAddress);
1407     }
1408 #endif
1409 
1410     bool success = true;
1411 
1412     if (ConditionPassed(opcode))
1413     {
1414         EmulateInstruction::Context context;
1415         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1416         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1417         if (!success)
1418             return false;
1419         addr_t lr; // next instruction address
1420         addr_t target; // target address
1421         int32_t imm32; // PC-relative offset
1422         switch (encoding) {
1423         case eEncodingT1:
1424             {
1425             lr = pc | 1u; // return address
1426             uint32_t S = Bit32(opcode, 26);
1427             uint32_t imm10 = Bits32(opcode, 25, 16);
1428             uint32_t J1 = Bit32(opcode, 13);
1429             uint32_t J2 = Bit32(opcode, 11);
1430             uint32_t imm11 = Bits32(opcode, 10, 0);
1431             uint32_t I1 = !(J1 ^ S);
1432             uint32_t I2 = !(J2 ^ S);
1433             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1434             imm32 = llvm::SignExtend32<25>(imm25);
1435             target = pc + imm32;
1436             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
1437             if (InITBlock() && !LastInITBlock())
1438                 return false;
1439             break;
1440             }
1441         case eEncodingT2:
1442             {
1443             lr = pc | 1u; // return address
1444             uint32_t S = Bit32(opcode, 26);
1445             uint32_t imm10H = Bits32(opcode, 25, 16);
1446             uint32_t J1 = Bit32(opcode, 13);
1447             uint32_t J2 = Bit32(opcode, 11);
1448             uint32_t imm10L = Bits32(opcode, 10, 1);
1449             uint32_t I1 = !(J1 ^ S);
1450             uint32_t I2 = !(J2 ^ S);
1451             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
1452             imm32 = llvm::SignExtend32<25>(imm25);
1453             target = Align(pc, 4) + imm32;
1454             context.SetISAAndImmediateSigned (eModeARM, 4 + imm32);
1455             if (InITBlock() && !LastInITBlock())
1456                 return false;
1457             break;
1458             }
1459         case eEncodingA1:
1460             lr = pc - 4; // return address
1461             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1462             target = Align(pc, 4) + imm32;
1463             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
1464             break;
1465         case eEncodingA2:
1466             lr = pc - 4; // return address
1467             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
1468             target = pc + imm32;
1469             context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32);
1470             break;
1471         default:
1472             return false;
1473         }
1474         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1475             return false;
1476         if (!BranchWritePC(context, target))
1477             return false;
1478     }
1479     return true;
1480 }
1481 
1482 // Branch with Link and Exchange (register) calls a subroutine at an address and
1483 // instruction set specified by a register.
1484 // BLX (register)
1485 bool
1486 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding)
1487 {
1488 #if 0
1489     // ARM pseudo code...
1490     if (ConditionPassed())
1491     {
1492         EncodingSpecificOperations();
1493         target = R[m];
1494         if CurrentInstrSet() == InstrSet_ARM then
1495             next_instr_addr = PC - 4;
1496             LR = next_instr_addr;
1497         else
1498             next_instr_addr = PC - 2;
1499             LR = next_instr_addr<31:1> : '1';
1500         BXWritePC(target);
1501     }
1502 #endif
1503 
1504     bool success = false;
1505 
1506     if (ConditionPassed(opcode))
1507     {
1508         EmulateInstruction::Context context;
1509         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1510         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1511         addr_t lr; // next instruction address
1512         if (!success)
1513             return false;
1514         uint32_t Rm; // the register with the target address
1515         switch (encoding) {
1516         case eEncodingT1:
1517             lr = (pc - 2) | 1u; // return address
1518             Rm = Bits32(opcode, 6, 3);
1519             // if m == 15 then UNPREDICTABLE;
1520             if (Rm == 15)
1521                 return false;
1522             if (InITBlock() && !LastInITBlock())
1523                 return false;
1524             break;
1525         case eEncodingA1:
1526             lr = pc - 4; // return address
1527             Rm = Bits32(opcode, 3, 0);
1528             // if m == 15 then UNPREDICTABLE;
1529             if (Rm == 15)
1530                 return false;
1531             break;
1532         default:
1533             return false;
1534         }
1535         addr_t target = ReadCoreReg (Rm, &success);
1536         if (!success)
1537             return false;
1538         RegisterInfo dwarf_reg;
1539         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1540         context.SetRegister (dwarf_reg);
1541         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1542             return false;
1543         if (!BXWritePC(context, target))
1544             return false;
1545     }
1546     return true;
1547 }
1548 
1549 // Branch and Exchange causes a branch to an address and instruction set specified by a register.
1550 bool
1551 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding)
1552 {
1553 #if 0
1554     // ARM pseudo code...
1555     if (ConditionPassed())
1556     {
1557         EncodingSpecificOperations();
1558         BXWritePC(R[m]);
1559     }
1560 #endif
1561 
1562     if (ConditionPassed(opcode))
1563     {
1564         EmulateInstruction::Context context;
1565         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1566         uint32_t Rm; // the register with the target address
1567         switch (encoding) {
1568         case eEncodingT1:
1569             Rm = Bits32(opcode, 6, 3);
1570             if (InITBlock() && !LastInITBlock())
1571                 return false;
1572             break;
1573         case eEncodingA1:
1574             Rm = Bits32(opcode, 3, 0);
1575             break;
1576         default:
1577             return false;
1578         }
1579         bool success = false;
1580         addr_t target = ReadCoreReg (Rm, &success);
1581         if (!success)
1582             return false;
1583 
1584         RegisterInfo dwarf_reg;
1585         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1586         context.SetRegister (dwarf_reg);
1587         if (!BXWritePC(context, target))
1588             return false;
1589     }
1590     return true;
1591 }
1592 
1593 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an
1594 // address and instruction set specified by a register as though it were a BX instruction.
1595 //
1596 // TODO: Emulate Jazelle architecture?
1597 //       We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation.
1598 bool
1599 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding)
1600 {
1601 #if 0
1602     // ARM pseudo code...
1603     if (ConditionPassed())
1604     {
1605         EncodingSpecificOperations();
1606         if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
1607             BXWritePC(R[m]);
1608         else
1609             if JazelleAcceptsExecution() then
1610                 SwitchToJazelleExecution();
1611             else
1612                 SUBARCHITECTURE_DEFINED handler call;
1613     }
1614 #endif
1615 
1616     if (ConditionPassed(opcode))
1617     {
1618         EmulateInstruction::Context context;
1619         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1620         uint32_t Rm; // the register with the target address
1621         switch (encoding) {
1622         case eEncodingT1:
1623             Rm = Bits32(opcode, 19, 16);
1624             if (BadReg(Rm))
1625                 return false;
1626             if (InITBlock() && !LastInITBlock())
1627                 return false;
1628             break;
1629         case eEncodingA1:
1630             Rm = Bits32(opcode, 3, 0);
1631             if (Rm == 15)
1632                 return false;
1633             break;
1634         default:
1635             return false;
1636         }
1637         bool success = false;
1638         addr_t target = ReadCoreReg (Rm, &success);
1639         if (!success)
1640             return false;
1641 
1642         RegisterInfo dwarf_reg;
1643         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1644         context.SetRegister (dwarf_reg);
1645         if (!BXWritePC(context, target))
1646             return false;
1647     }
1648     return true;
1649 }
1650 
1651 // Set r7 to point to some ip offset.
1652 // SUB (immediate)
1653 bool
1654 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding)
1655 {
1656 #if 0
1657     // ARM pseudo code...
1658     if (ConditionPassed())
1659     {
1660         EncodingSpecificOperations();
1661         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1662         if d == 15 then // Can only occur for ARM encoding
1663            ALUWritePC(result); // setflags is always FALSE here
1664         else
1665             R[d] = result;
1666             if setflags then
1667                 APSR.N = result<31>;
1668                 APSR.Z = IsZeroBit(result);
1669                 APSR.C = carry;
1670                 APSR.V = overflow;
1671     }
1672 #endif
1673 
1674     if (ConditionPassed(opcode))
1675     {
1676         bool success = false;
1677         const addr_t ip = ReadCoreReg (12, &success);
1678         if (!success)
1679             return false;
1680         uint32_t imm32;
1681         switch (encoding) {
1682         case eEncodingA1:
1683             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1684             break;
1685         default:
1686             return false;
1687         }
1688         addr_t ip_offset = imm32;
1689         addr_t addr = ip - ip_offset; // the adjusted ip value
1690 
1691         EmulateInstruction::Context context;
1692         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1693         RegisterInfo dwarf_reg;
1694         GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg);
1695         context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
1696 
1697         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
1698             return false;
1699     }
1700     return true;
1701 }
1702 
1703 // Set ip to point to some stack offset.
1704 // SUB (SP minus immediate)
1705 bool
1706 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding)
1707 {
1708 #if 0
1709     // ARM pseudo code...
1710     if (ConditionPassed())
1711     {
1712         EncodingSpecificOperations();
1713         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1714         if d == 15 then // Can only occur for ARM encoding
1715            ALUWritePC(result); // setflags is always FALSE here
1716         else
1717             R[d] = result;
1718             if setflags then
1719                 APSR.N = result<31>;
1720                 APSR.Z = IsZeroBit(result);
1721                 APSR.C = carry;
1722                 APSR.V = overflow;
1723     }
1724 #endif
1725 
1726     if (ConditionPassed(opcode))
1727     {
1728         bool success = false;
1729         const addr_t sp = ReadCoreReg (SP_REG, &success);
1730         if (!success)
1731             return false;
1732         uint32_t imm32;
1733         switch (encoding) {
1734         case eEncodingA1:
1735             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1736             break;
1737         default:
1738             return false;
1739         }
1740         addr_t sp_offset = imm32;
1741         addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1742 
1743         EmulateInstruction::Context context;
1744         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1745         RegisterInfo dwarf_reg;
1746         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
1747         context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
1748 
1749         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
1750             return false;
1751     }
1752     return true;
1753 }
1754 
1755 // This instruction subtracts an immediate value from the SP value, and writes
1756 // the result to the destination register.
1757 //
1758 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage.
1759 bool
1760 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding)
1761 {
1762 #if 0
1763     // ARM pseudo code...
1764     if (ConditionPassed())
1765     {
1766         EncodingSpecificOperations();
1767         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1768         if d == 15 then        // Can only occur for ARM encoding
1769            ALUWritePC(result); // setflags is always FALSE here
1770         else
1771             R[d] = result;
1772             if setflags then
1773                 APSR.N = result<31>;
1774                 APSR.Z = IsZeroBit(result);
1775                 APSR.C = carry;
1776                 APSR.V = overflow;
1777     }
1778 #endif
1779 
1780     bool success = false;
1781     if (ConditionPassed(opcode))
1782     {
1783         const addr_t sp = ReadCoreReg (SP_REG, &success);
1784         if (!success)
1785             return false;
1786 
1787         uint32_t Rd;
1788         bool setflags;
1789         uint32_t imm32;
1790         switch (encoding) {
1791         case eEncodingT1:
1792             Rd = 13;
1793             setflags = false;
1794             imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1795             break;
1796         case eEncodingT2:
1797             Rd = Bits32(opcode, 11, 8);
1798             setflags = BitIsSet(opcode, 20);
1799             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1800             if (Rd == 15 && setflags)
1801                 return EmulateCMPImm(opcode, eEncodingT2);
1802             if (Rd == 15 && !setflags)
1803                 return false;
1804             break;
1805         case eEncodingT3:
1806             Rd = Bits32(opcode, 11, 8);
1807             setflags = false;
1808             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
1809             if (Rd == 15)
1810                 return false;
1811             break;
1812         case eEncodingA1:
1813             Rd = Bits32(opcode, 15, 12);
1814             setflags = BitIsSet(opcode, 20);
1815             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1816 
1817             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1818             if (Rd == 15 && setflags)
1819                 return EmulateSUBSPcLrEtc (opcode, encoding);
1820             break;
1821         default:
1822             return false;
1823         }
1824         AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
1825 
1826         EmulateInstruction::Context context;
1827         if (Rd == 13)
1828         {
1829             uint64_t imm64 = imm32;  // Need to expand it to 64 bits before attempting to negate it, or the wrong
1830                                      // value gets passed down to context.SetImmediateSigned.
1831             context.type = EmulateInstruction::eContextAdjustStackPointer;
1832             context.SetImmediateSigned (-imm64); // the stack pointer offset
1833         }
1834         else
1835         {
1836             context.type = EmulateInstruction::eContextImmediate;
1837             context.SetNoArgs ();
1838         }
1839 
1840         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
1841             return false;
1842     }
1843     return true;
1844 }
1845 
1846 // A store operation to the stack that also updates the SP.
1847 bool
1848 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding)
1849 {
1850 #if 0
1851     // ARM pseudo code...
1852     if (ConditionPassed())
1853     {
1854         EncodingSpecificOperations();
1855         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1856         address = if index then offset_addr else R[n];
1857         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1858         if wback then R[n] = offset_addr;
1859     }
1860 #endif
1861 
1862     bool conditional = false;
1863     bool success = false;
1864     if (ConditionPassed(opcode, &conditional))
1865     {
1866         const uint32_t addr_byte_size = GetAddressByteSize();
1867         const addr_t sp = ReadCoreReg (SP_REG, &success);
1868         if (!success)
1869             return false;
1870         uint32_t Rt; // the source register
1871         uint32_t imm12;
1872         uint32_t Rn;  // This function assumes Rn is the SP, but we should verify that.
1873 
1874         bool index;
1875         bool add;
1876         bool wback;
1877         switch (encoding) {
1878         case eEncodingA1:
1879             Rt = Bits32(opcode, 15, 12);
1880             imm12 = Bits32(opcode, 11, 0);
1881             Rn = Bits32 (opcode, 19, 16);
1882 
1883             if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
1884                 return false;
1885 
1886             index = BitIsSet (opcode, 24);
1887             add = BitIsSet (opcode, 23);
1888             wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
1889 
1890             if (wback && ((Rn == 15) || (Rn == Rt)))
1891                 return false;
1892             break;
1893         default:
1894             return false;
1895         }
1896         addr_t offset_addr;
1897         if (add)
1898             offset_addr = sp + imm12;
1899         else
1900             offset_addr = sp - imm12;
1901 
1902         addr_t addr;
1903         if (index)
1904             addr = offset_addr;
1905         else
1906             addr = sp;
1907 
1908         EmulateInstruction::Context context;
1909         if (conditional)
1910             context.type = EmulateInstruction::eContextRegisterStore;
1911         else
1912             context.type = EmulateInstruction::eContextPushRegisterOnStack;
1913         RegisterInfo sp_reg;
1914         RegisterInfo dwarf_reg;
1915 
1916         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1917         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
1918         context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
1919         if (Rt != 15)
1920         {
1921             uint32_t reg_value = ReadCoreReg(Rt, &success);
1922             if (!success)
1923                 return false;
1924             if (!MemUWrite (context, addr, reg_value, addr_byte_size))
1925                 return false;
1926         }
1927         else
1928         {
1929             const uint32_t pc = ReadCoreReg(PC_REG, &success);
1930             if (!success)
1931                 return false;
1932             if (!MemUWrite (context, addr, pc, addr_byte_size))
1933                 return false;
1934         }
1935 
1936 
1937         if (wback)
1938         {
1939             context.type = EmulateInstruction::eContextAdjustStackPointer;
1940             context.SetImmediateSigned (addr - sp);
1941             if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr))
1942                 return false;
1943         }
1944     }
1945     return true;
1946 }
1947 
1948 // Vector Push stores multiple extension registers to the stack.
1949 // It also updates SP to point to the start of the stored data.
1950 bool
1951 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding)
1952 {
1953 #if 0
1954     // ARM pseudo code...
1955     if (ConditionPassed())
1956     {
1957         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1958         address = SP - imm32;
1959         SP = SP - imm32;
1960         if single_regs then
1961             for r = 0 to regs-1
1962                 MemA[address,4] = S[d+r]; address = address+4;
1963         else
1964             for r = 0 to regs-1
1965                 // Store as two word-aligned words in the correct order for current endianness.
1966                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
1967                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
1968                 address = address+8;
1969     }
1970 #endif
1971 
1972     bool success = false;
1973     bool conditional = false;
1974     if (ConditionPassed(opcode, &conditional))
1975     {
1976         const uint32_t addr_byte_size = GetAddressByteSize();
1977         const addr_t sp = ReadCoreReg (SP_REG, &success);
1978         if (!success)
1979             return false;
1980         bool single_regs;
1981         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
1982         uint32_t imm32; // stack offset
1983         uint32_t regs;  // number of registers
1984         switch (encoding) {
1985         case eEncodingT1:
1986         case eEncodingA1:
1987             single_regs = false;
1988             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
1989             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1990             // If UInt(imm8) is odd, see "FSTMX".
1991             regs = Bits32(opcode, 7, 0) / 2;
1992             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1993             if (regs == 0 || regs > 16 || (d + regs) > 32)
1994                 return false;
1995             break;
1996         case eEncodingT2:
1997         case eEncodingA2:
1998             single_regs = true;
1999             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2000             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2001             regs = Bits32(opcode, 7, 0);
2002             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2003             if (regs == 0 || regs > 16 || (d + regs) > 32)
2004                 return false;
2005             break;
2006         default:
2007             return false;
2008         }
2009         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2010         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2011         addr_t sp_offset = imm32;
2012         addr_t addr = sp - sp_offset;
2013         uint32_t i;
2014 
2015         EmulateInstruction::Context context;
2016         if (conditional)
2017             context.type = EmulateInstruction::eContextRegisterStore;
2018         else
2019             context.type = EmulateInstruction::eContextPushRegisterOnStack;
2020         RegisterInfo dwarf_reg;
2021         RegisterInfo sp_reg;
2022         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2023         for (i=0; i<regs; ++i)
2024         {
2025             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2026             context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
2027             // uint64_t to accommodate 64-bit registers.
2028             uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success);
2029             if (!success)
2030                 return false;
2031             if (!MemAWrite (context, addr, reg_value, reg_byte_size))
2032                 return false;
2033             addr += reg_byte_size;
2034         }
2035 
2036         context.type = EmulateInstruction::eContextAdjustStackPointer;
2037         context.SetImmediateSigned (-sp_offset);
2038 
2039         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2040             return false;
2041     }
2042     return true;
2043 }
2044 
2045 // Vector Pop loads multiple extension registers from the stack.
2046 // It also updates SP to point just above the loaded data.
2047 bool
2048 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding)
2049 {
2050 #if 0
2051     // ARM pseudo code...
2052     if (ConditionPassed())
2053     {
2054         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2055         address = SP;
2056         SP = SP + imm32;
2057         if single_regs then
2058             for r = 0 to regs-1
2059                 S[d+r] = MemA[address,4]; address = address+4;
2060         else
2061             for r = 0 to regs-1
2062                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2063                 // Combine the word-aligned words in the correct order for current endianness.
2064                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2065     }
2066 #endif
2067 
2068     bool success = false;
2069     bool conditional = false;
2070     if (ConditionPassed(opcode, &conditional))
2071     {
2072         const uint32_t addr_byte_size = GetAddressByteSize();
2073         const addr_t sp = ReadCoreReg (SP_REG, &success);
2074         if (!success)
2075             return false;
2076         bool single_regs;
2077         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2078         uint32_t imm32; // stack offset
2079         uint32_t regs;  // number of registers
2080         switch (encoding) {
2081         case eEncodingT1:
2082         case eEncodingA1:
2083             single_regs = false;
2084             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2085             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2086             // If UInt(imm8) is odd, see "FLDMX".
2087             regs = Bits32(opcode, 7, 0) / 2;
2088             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2089             if (regs == 0 || regs > 16 || (d + regs) > 32)
2090                 return false;
2091             break;
2092         case eEncodingT2:
2093         case eEncodingA2:
2094             single_regs = true;
2095             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2096             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2097             regs = Bits32(opcode, 7, 0);
2098             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2099             if (regs == 0 || regs > 16 || (d + regs) > 32)
2100                 return false;
2101             break;
2102         default:
2103             return false;
2104         }
2105         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2106         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2107         addr_t sp_offset = imm32;
2108         addr_t addr = sp;
2109         uint32_t i;
2110         uint64_t data; // uint64_t to accomodate 64-bit registers.
2111 
2112         EmulateInstruction::Context context;
2113         if (conditional)
2114             context.type = EmulateInstruction::eContextRegisterLoad;
2115         else
2116             context.type = EmulateInstruction::eContextPopRegisterOffStack;
2117         RegisterInfo dwarf_reg;
2118         RegisterInfo sp_reg;
2119         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2120         for (i=0; i<regs; ++i)
2121         {
2122             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2123             context.SetRegisterPlusOffset (sp_reg, addr - sp);
2124             data = MemARead(context, addr, reg_byte_size, 0, &success);
2125             if (!success)
2126                 return false;
2127             if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2128                 return false;
2129             addr += reg_byte_size;
2130         }
2131 
2132         context.type = EmulateInstruction::eContextAdjustStackPointer;
2133         context.SetImmediateSigned (sp_offset);
2134 
2135         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2136             return false;
2137     }
2138     return true;
2139 }
2140 
2141 // SVC (previously SWI)
2142 bool
2143 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding)
2144 {
2145 #if 0
2146     // ARM pseudo code...
2147     if (ConditionPassed())
2148     {
2149         EncodingSpecificOperations();
2150         CallSupervisor();
2151     }
2152 #endif
2153 
2154     bool success = false;
2155 
2156     if (ConditionPassed(opcode))
2157     {
2158         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2159         addr_t lr; // next instruction address
2160         if (!success)
2161             return false;
2162         uint32_t imm32; // the immediate constant
2163         uint32_t mode;  // ARM or Thumb mode
2164         switch (encoding) {
2165         case eEncodingT1:
2166             lr = (pc + 2) | 1u; // return address
2167             imm32 = Bits32(opcode, 7, 0);
2168             mode = eModeThumb;
2169             break;
2170         case eEncodingA1:
2171             lr = pc + 4; // return address
2172             imm32 = Bits32(opcode, 23, 0);
2173             mode = eModeARM;
2174             break;
2175         default:
2176             return false;
2177         }
2178 
2179         EmulateInstruction::Context context;
2180         context.type = EmulateInstruction::eContextSupervisorCall;
2181         context.SetISAAndImmediate (mode, imm32);
2182         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
2183             return false;
2184     }
2185     return true;
2186 }
2187 
2188 // If Then makes up to four following instructions (the IT block) conditional.
2189 bool
2190 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding)
2191 {
2192 #if 0
2193     // ARM pseudo code...
2194     EncodingSpecificOperations();
2195     ITSTATE.IT<7:0> = firstcond:mask;
2196 #endif
2197 
2198     m_it_session.InitIT(Bits32(opcode, 7, 0));
2199     return true;
2200 }
2201 
2202 bool
2203 EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding)
2204 {
2205     // NOP, nothing to do...
2206     return true;
2207 }
2208 
2209 // Branch causes a branch to a target address.
2210 bool
2211 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding)
2212 {
2213 #if 0
2214     // ARM pseudo code...
2215     if (ConditionPassed())
2216     {
2217         EncodingSpecificOperations();
2218         BranchWritePC(PC + imm32);
2219     }
2220 #endif
2221 
2222     bool success = false;
2223 
2224     if (ConditionPassed(opcode))
2225     {
2226         EmulateInstruction::Context context;
2227         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2228         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2229         if (!success)
2230             return false;
2231         addr_t target; // target address
2232         int32_t imm32; // PC-relative offset
2233         switch (encoding) {
2234         case eEncodingT1:
2235             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2236             imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2237             target = pc + imm32;
2238             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2239             break;
2240         case eEncodingT2:
2241             imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0));
2242             target = pc + imm32;
2243             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2244             break;
2245         case eEncodingT3:
2246             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2247             {
2248             uint32_t S = Bit32(opcode, 26);
2249             uint32_t imm6 = Bits32(opcode, 21, 16);
2250             uint32_t J1 = Bit32(opcode, 13);
2251             uint32_t J2 = Bit32(opcode, 11);
2252             uint32_t imm11 = Bits32(opcode, 10, 0);
2253             uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2254             imm32 = llvm::SignExtend32<21>(imm21);
2255             target = pc + imm32;
2256             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2257             break;
2258             }
2259         case eEncodingT4:
2260             {
2261             uint32_t S = Bit32(opcode, 26);
2262             uint32_t imm10 = Bits32(opcode, 25, 16);
2263             uint32_t J1 = Bit32(opcode, 13);
2264             uint32_t J2 = Bit32(opcode, 11);
2265             uint32_t imm11 = Bits32(opcode, 10, 0);
2266             uint32_t I1 = !(J1 ^ S);
2267             uint32_t I2 = !(J2 ^ S);
2268             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2269             imm32 = llvm::SignExtend32<25>(imm25);
2270             target = pc + imm32;
2271             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2272             break;
2273             }
2274         case eEncodingA1:
2275             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2276             target = pc + imm32;
2277             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
2278             break;
2279         default:
2280             return false;
2281         }
2282         if (!BranchWritePC(context, target))
2283             return false;
2284     }
2285     return true;
2286 }
2287 
2288 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
2289 // zero and conditionally branch forward a constant value.  They do not affect the condition flags.
2290 // CBNZ, CBZ
2291 bool
2292 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding)
2293 {
2294 #if 0
2295     // ARM pseudo code...
2296     EncodingSpecificOperations();
2297     if nonzero ^ IsZero(R[n]) then
2298         BranchWritePC(PC + imm32);
2299 #endif
2300 
2301     bool success = false;
2302 
2303     // Read the register value from the operand register Rn.
2304     uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2305     if (!success)
2306         return false;
2307 
2308     EmulateInstruction::Context context;
2309     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2310     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2311     if (!success)
2312         return false;
2313 
2314     addr_t target;  // target address
2315     uint32_t imm32; // PC-relative offset to branch forward
2316     bool nonzero;
2317     switch (encoding) {
2318     case eEncodingT1:
2319         imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2320         nonzero = BitIsSet(opcode, 11);
2321         target = pc + imm32;
2322         context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2323         break;
2324     default:
2325         return false;
2326     }
2327     if (nonzero ^ (reg_val == 0))
2328         if (!BranchWritePC(context, target))
2329             return false;
2330 
2331     return true;
2332 }
2333 
2334 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
2335 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2336 // The branch length is twice the value of the byte returned from the table.
2337 //
2338 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
2339 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2340 // The branch length is twice the value of the halfword returned from the table.
2341 // TBB, TBH
2342 bool
2343 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding)
2344 {
2345 #if 0
2346     // ARM pseudo code...
2347     EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2348     if is_tbh then
2349         halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2350     else
2351         halfwords = UInt(MemU[R[n]+R[m], 1]);
2352     BranchWritePC(PC + 2*halfwords);
2353 #endif
2354 
2355     bool success = false;
2356 
2357     uint32_t Rn;     // the base register which contains the address of the table of branch lengths
2358     uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
2359     bool is_tbh;     // true if table branch halfword
2360     switch (encoding) {
2361     case eEncodingT1:
2362         Rn = Bits32(opcode, 19, 16);
2363         Rm = Bits32(opcode, 3, 0);
2364         is_tbh = BitIsSet(opcode, 4);
2365         if (Rn == 13 || BadReg(Rm))
2366             return false;
2367         if (InITBlock() && !LastInITBlock())
2368             return false;
2369         break;
2370     default:
2371         return false;
2372     }
2373 
2374     // Read the address of the table from the operand register Rn.
2375     // The PC can be used, in which case the table immediately follows this instruction.
2376     uint32_t base = ReadCoreReg(Rm, &success);
2377     if (!success)
2378         return false;
2379 
2380     // the table index
2381     uint32_t index = ReadCoreReg(Rm, &success);
2382     if (!success)
2383         return false;
2384 
2385     // the offsetted table address
2386     addr_t addr = base + (is_tbh ? index*2 : index);
2387 
2388     // PC-relative offset to branch forward
2389     EmulateInstruction::Context context;
2390     context.type = EmulateInstruction::eContextTableBranchReadMemory;
2391     uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2392     if (!success)
2393         return false;
2394 
2395     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2396     if (!success)
2397         return false;
2398 
2399     // target address
2400     addr_t target = pc + offset;
2401     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2402     context.SetISAAndImmediateSigned (eModeThumb, 4 + offset);
2403 
2404     if (!BranchWritePC(context, target))
2405         return false;
2406 
2407     return true;
2408 }
2409 
2410 // This instruction adds an immediate value to a register value, and writes the result to the destination register.
2411 // It can optionally update the condition flags based on the result.
2412 bool
2413 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding)
2414 {
2415 #if 0
2416     if ConditionPassed() then
2417         EncodingSpecificOperations();
2418         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2419         R[d] = result;
2420         if setflags then
2421             APSR.N = result<31>;
2422             APSR.Z = IsZeroBit(result);
2423             APSR.C = carry;
2424             APSR.V = overflow;
2425 #endif
2426 
2427     bool success = false;
2428 
2429     if (ConditionPassed(opcode))
2430     {
2431         uint32_t d;
2432         uint32_t n;
2433         bool setflags;
2434         uint32_t imm32;
2435         uint32_t carry_out;
2436 
2437         //EncodingSpecificOperations();
2438         switch (encoding)
2439         {
2440             case eEncodingT1:
2441                 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32);
2442                 d = Bits32 (opcode, 2, 0);
2443                 n = Bits32 (opcode, 5, 3);
2444                 setflags = !InITBlock();
2445                 imm32 = Bits32 (opcode, 8,6);
2446 
2447                 break;
2448 
2449             case eEncodingT2:
2450                 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32);
2451                 d = Bits32 (opcode, 10, 8);
2452                 n = Bits32 (opcode, 10, 8);
2453                 setflags = !InITBlock();
2454                 imm32 = Bits32 (opcode, 7, 0);
2455 
2456                 break;
2457 
2458             case eEncodingT3:
2459                 // if Rd == '1111' && S == '1' then SEE CMN (immediate);
2460                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2461                 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8);
2462                 d = Bits32 (opcode, 11, 8);
2463                 n = Bits32 (opcode, 19, 16);
2464                 setflags = BitIsSet (opcode, 20);
2465                 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out);
2466 
2467                 // if BadReg(d) || n == 15 then UNPREDICTABLE;
2468                 if (BadReg (d) || (n == 15))
2469                     return false;
2470 
2471                 break;
2472 
2473             case eEncodingT4:
2474             {
2475                 // if Rn == '1111' then SEE ADR;
2476                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2477                 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
2478                 d = Bits32 (opcode, 11, 8);
2479                 n = Bits32 (opcode, 19, 16);
2480                 setflags = false;
2481                 uint32_t i = Bit32 (opcode, 26);
2482                 uint32_t imm3 = Bits32 (opcode, 14, 12);
2483                 uint32_t imm8 = Bits32 (opcode, 7, 0);
2484                 imm32 = (i << 11) | (imm3 << 8) | imm8;
2485 
2486                 // if BadReg(d) then UNPREDICTABLE;
2487                 if (BadReg (d))
2488                     return false;
2489 
2490                 break;
2491             }
2492             default:
2493                 return false;
2494         }
2495 
2496         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2497         if (!success)
2498             return false;
2499 
2500         //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2501         AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
2502 
2503         RegisterInfo reg_n;
2504         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
2505 
2506         EmulateInstruction::Context context;
2507         context.type = eContextArithmetic;
2508         context.SetRegisterPlusOffset (reg_n, imm32);
2509 
2510         //R[d] = result;
2511         //if setflags then
2512             //APSR.N = result<31>;
2513             //APSR.Z = IsZeroBit(result);
2514             //APSR.C = carry;
2515             //APSR.V = overflow;
2516         if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
2517             return false;
2518 
2519     }
2520     return true;
2521 }
2522 
2523 // This instruction adds an immediate value to a register value, and writes the result to the destination
2524 // register.  It can optionally update the condition flags based on the result.
2525 bool
2526 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding)
2527 {
2528 #if 0
2529     // ARM pseudo code...
2530     if ConditionPassed() then
2531         EncodingSpecificOperations();
2532         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2533         if d == 15 then
2534             ALUWritePC(result); // setflags is always FALSE here
2535         else
2536             R[d] = result;
2537             if setflags then
2538                 APSR.N = result<31>;
2539                 APSR.Z = IsZeroBit(result);
2540                 APSR.C = carry;
2541                 APSR.V = overflow;
2542 #endif
2543 
2544     bool success = false;
2545 
2546     if (ConditionPassed(opcode))
2547     {
2548         uint32_t Rd, Rn;
2549         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
2550         bool setflags;
2551         switch (encoding)
2552         {
2553         case eEncodingA1:
2554             Rd = Bits32(opcode, 15, 12);
2555             Rn = Bits32(opcode, 19, 16);
2556             setflags = BitIsSet(opcode, 20);
2557             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2558             break;
2559         default:
2560             return false;
2561         }
2562 
2563         // Read the first operand.
2564         uint32_t val1 = ReadCoreReg(Rn, &success);
2565         if (!success)
2566             return false;
2567 
2568         AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
2569 
2570         EmulateInstruction::Context context;
2571         context.type = eContextArithmetic;
2572         RegisterInfo dwarf_reg;
2573         GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
2574         context.SetRegisterPlusOffset (dwarf_reg, imm32);
2575 
2576         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2577             return false;
2578     }
2579     return true;
2580 }
2581 
2582 // This instruction adds a register value and an optionally-shifted register value, and writes the result
2583 // to the destination register. It can optionally update the condition flags based on the result.
2584 bool
2585 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding)
2586 {
2587 #if 0
2588     // ARM pseudo code...
2589     if ConditionPassed() then
2590         EncodingSpecificOperations();
2591         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2592         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2593         if d == 15 then
2594             ALUWritePC(result); // setflags is always FALSE here
2595         else
2596             R[d] = result;
2597             if setflags then
2598                 APSR.N = result<31>;
2599                 APSR.Z = IsZeroBit(result);
2600                 APSR.C = carry;
2601                 APSR.V = overflow;
2602 #endif
2603 
2604     bool success = false;
2605 
2606     if (ConditionPassed(opcode))
2607     {
2608         uint32_t Rd, Rn, Rm;
2609         ARM_ShifterType shift_t;
2610         uint32_t shift_n; // the shift applied to the value read from Rm
2611         bool setflags;
2612         switch (encoding)
2613         {
2614         case eEncodingT1:
2615             Rd = Bits32(opcode, 2, 0);
2616             Rn = Bits32(opcode, 5, 3);
2617             Rm = Bits32(opcode, 8, 6);
2618             setflags = !InITBlock();
2619             shift_t = SRType_LSL;
2620             shift_n = 0;
2621             break;
2622         case eEncodingT2:
2623             Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2624             Rm = Bits32(opcode, 6, 3);
2625             setflags = false;
2626             shift_t = SRType_LSL;
2627             shift_n = 0;
2628             if (Rn == 15 && Rm == 15)
2629                 return false;
2630             if (Rd == 15 && InITBlock() && !LastInITBlock())
2631                 return false;
2632             break;
2633         case eEncodingA1:
2634             Rd = Bits32(opcode, 15, 12);
2635             Rn = Bits32(opcode, 19, 16);
2636             Rm = Bits32(opcode, 3, 0);
2637             setflags = BitIsSet(opcode, 20);
2638             shift_n = DecodeImmShiftARM(opcode, shift_t);
2639             break;
2640         default:
2641             return false;
2642         }
2643 
2644         // Read the first operand.
2645         uint32_t val1 = ReadCoreReg(Rn, &success);
2646         if (!success)
2647             return false;
2648 
2649         // Read the second operand.
2650         uint32_t val2 = ReadCoreReg(Rm, &success);
2651         if (!success)
2652             return false;
2653 
2654         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2655         if (!success)
2656             return false;
2657         AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2658 
2659         EmulateInstruction::Context context;
2660         context.type = eContextArithmetic;
2661         RegisterInfo op1_reg;
2662         RegisterInfo op2_reg;
2663         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
2664         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
2665         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
2666 
2667         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2668             return false;
2669     }
2670     return true;
2671 }
2672 
2673 // Compare Negative (immediate) adds a register value and an immediate value.
2674 // It updates the condition flags based on the result, and discards the result.
2675 bool
2676 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding)
2677 {
2678 #if 0
2679     // ARM pseudo code...
2680     if ConditionPassed() then
2681         EncodingSpecificOperations();
2682         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2683         APSR.N = result<31>;
2684         APSR.Z = IsZeroBit(result);
2685         APSR.C = carry;
2686         APSR.V = overflow;
2687 #endif
2688 
2689     bool success = false;
2690 
2691     uint32_t Rn; // the first operand
2692     uint32_t imm32; // the immediate value to be compared with
2693     switch (encoding) {
2694     case eEncodingT1:
2695         Rn = Bits32(opcode, 19, 16);
2696         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2697         if (Rn == 15)
2698             return false;
2699         break;
2700     case eEncodingA1:
2701         Rn = Bits32(opcode, 19, 16);
2702         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2703         break;
2704     default:
2705         return false;
2706     }
2707     // Read the register value from the operand register Rn.
2708     uint32_t reg_val = ReadCoreReg(Rn, &success);
2709     if (!success)
2710         return false;
2711 
2712     AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
2713 
2714     EmulateInstruction::Context context;
2715     context.type = EmulateInstruction::eContextImmediate;
2716     context.SetNoArgs ();
2717     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2718         return false;
2719 
2720     return true;
2721 }
2722 
2723 // Compare Negative (register) adds a register value and an optionally-shifted register value.
2724 // It updates the condition flags based on the result, and discards the result.
2725 bool
2726 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding)
2727 {
2728 #if 0
2729     // ARM pseudo code...
2730     if ConditionPassed() then
2731         EncodingSpecificOperations();
2732         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2733         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2734         APSR.N = result<31>;
2735         APSR.Z = IsZeroBit(result);
2736         APSR.C = carry;
2737         APSR.V = overflow;
2738 #endif
2739 
2740     bool success = false;
2741 
2742     uint32_t Rn; // the first operand
2743     uint32_t Rm; // the second operand
2744     ARM_ShifterType shift_t;
2745     uint32_t shift_n; // the shift applied to the value read from Rm
2746     switch (encoding) {
2747     case eEncodingT1:
2748         Rn = Bits32(opcode, 2, 0);
2749         Rm = Bits32(opcode, 5, 3);
2750         shift_t = SRType_LSL;
2751         shift_n = 0;
2752         break;
2753     case eEncodingT2:
2754         Rn = Bits32(opcode, 19, 16);
2755         Rm = Bits32(opcode, 3, 0);
2756         shift_n = DecodeImmShiftThumb(opcode, shift_t);
2757         // if n == 15 || BadReg(m) then UNPREDICTABLE;
2758         if (Rn == 15 || BadReg(Rm))
2759             return false;
2760         break;
2761     case eEncodingA1:
2762         Rn = Bits32(opcode, 19, 16);
2763         Rm = Bits32(opcode, 3, 0);
2764         shift_n = DecodeImmShiftARM(opcode, shift_t);
2765         break;
2766     default:
2767         return false;
2768     }
2769     // Read the register value from register Rn.
2770     uint32_t val1 = ReadCoreReg(Rn, &success);
2771     if (!success)
2772         return false;
2773 
2774     // Read the register value from register Rm.
2775     uint32_t val2 = ReadCoreReg(Rm, &success);
2776     if (!success)
2777         return false;
2778 
2779     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2780     if (!success)
2781         return false;
2782     AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2783 
2784     EmulateInstruction::Context context;
2785     context.type = EmulateInstruction::eContextImmediate;
2786     context.SetNoArgs();
2787     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2788         return false;
2789 
2790     return true;
2791 }
2792 
2793 // Compare (immediate) subtracts an immediate value from a register value.
2794 // It updates the condition flags based on the result, and discards the result.
2795 bool
2796 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding)
2797 {
2798 #if 0
2799     // ARM pseudo code...
2800     if ConditionPassed() then
2801         EncodingSpecificOperations();
2802         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2803         APSR.N = result<31>;
2804         APSR.Z = IsZeroBit(result);
2805         APSR.C = carry;
2806         APSR.V = overflow;
2807 #endif
2808 
2809     bool success = false;
2810 
2811     uint32_t Rn; // the first operand
2812     uint32_t imm32; // the immediate value to be compared with
2813     switch (encoding) {
2814     case eEncodingT1:
2815         Rn = Bits32(opcode, 10, 8);
2816         imm32 = Bits32(opcode, 7, 0);
2817         break;
2818     case eEncodingT2:
2819         Rn = Bits32(opcode, 19, 16);
2820         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2821         if (Rn == 15)
2822             return false;
2823         break;
2824     case eEncodingA1:
2825         Rn = Bits32(opcode, 19, 16);
2826         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2827         break;
2828     default:
2829         return false;
2830     }
2831     // Read the register value from the operand register Rn.
2832     uint32_t reg_val = ReadCoreReg(Rn, &success);
2833     if (!success)
2834         return false;
2835 
2836     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
2837 
2838     EmulateInstruction::Context context;
2839     context.type = EmulateInstruction::eContextImmediate;
2840     context.SetNoArgs ();
2841     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2842         return false;
2843 
2844     return true;
2845 }
2846 
2847 // Compare (register) subtracts an optionally-shifted register value from a register value.
2848 // It updates the condition flags based on the result, and discards the result.
2849 bool
2850 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding)
2851 {
2852 #if 0
2853     // ARM pseudo code...
2854     if ConditionPassed() then
2855         EncodingSpecificOperations();
2856         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2857         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2858         APSR.N = result<31>;
2859         APSR.Z = IsZeroBit(result);
2860         APSR.C = carry;
2861         APSR.V = overflow;
2862 #endif
2863 
2864     bool success = false;
2865 
2866     uint32_t Rn; // the first operand
2867     uint32_t Rm; // the second operand
2868     ARM_ShifterType shift_t;
2869     uint32_t shift_n; // the shift applied to the value read from Rm
2870     switch (encoding) {
2871     case eEncodingT1:
2872         Rn = Bits32(opcode, 2, 0);
2873         Rm = Bits32(opcode, 5, 3);
2874         shift_t = SRType_LSL;
2875         shift_n = 0;
2876         break;
2877     case eEncodingT2:
2878         Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2879         Rm = Bits32(opcode, 6, 3);
2880         shift_t = SRType_LSL;
2881         shift_n = 0;
2882         if (Rn < 8 && Rm < 8)
2883             return false;
2884         if (Rn == 15 || Rm == 15)
2885             return false;
2886         break;
2887     case eEncodingA1:
2888         Rn = Bits32(opcode, 19, 16);
2889         Rm = Bits32(opcode, 3, 0);
2890         shift_n = DecodeImmShiftARM(opcode, shift_t);
2891         break;
2892     default:
2893         return false;
2894     }
2895     // Read the register value from register Rn.
2896     uint32_t val1 = ReadCoreReg(Rn, &success);
2897     if (!success)
2898         return false;
2899 
2900     // Read the register value from register Rm.
2901     uint32_t val2 = ReadCoreReg(Rm, &success);
2902     if (!success)
2903         return false;
2904 
2905     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2906     if (!success)
2907         return false;
2908     AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
2909 
2910     EmulateInstruction::Context context;
2911     context.type = EmulateInstruction::eContextImmediate;
2912     context.SetNoArgs();
2913     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2914         return false;
2915 
2916     return true;
2917 }
2918 
2919 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
2920 // shifting in copies of its sign bit, and writes the result to the destination register.  It can
2921 // optionally update the condition flags based on the result.
2922 bool
2923 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding)
2924 {
2925 #if 0
2926     // ARM pseudo code...
2927     if ConditionPassed() then
2928         EncodingSpecificOperations();
2929         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2930         if d == 15 then         // Can only occur for ARM encoding
2931             ALUWritePC(result); // setflags is always FALSE here
2932         else
2933             R[d] = result;
2934             if setflags then
2935                 APSR.N = result<31>;
2936                 APSR.Z = IsZeroBit(result);
2937                 APSR.C = carry;
2938                 // APSR.V unchanged
2939 #endif
2940 
2941     return EmulateShiftImm (opcode, encoding, SRType_ASR);
2942 }
2943 
2944 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
2945 // shifting in copies of its sign bit, and writes the result to the destination register.
2946 // The variable number of bits is read from the bottom byte of a register. It can optionally update
2947 // the condition flags based on the result.
2948 bool
2949 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding)
2950 {
2951 #if 0
2952     // ARM pseudo code...
2953     if ConditionPassed() then
2954         EncodingSpecificOperations();
2955         shift_n = UInt(R[m]<7:0>);
2956         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2957         R[d] = result;
2958         if setflags then
2959             APSR.N = result<31>;
2960             APSR.Z = IsZeroBit(result);
2961             APSR.C = carry;
2962             // APSR.V unchanged
2963 #endif
2964 
2965     return EmulateShiftReg (opcode, encoding, SRType_ASR);
2966 }
2967 
2968 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
2969 // shifting in zeros, and writes the result to the destination register.  It can optionally
2970 // update the condition flags based on the result.
2971 bool
2972 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding)
2973 {
2974 #if 0
2975     // ARM pseudo code...
2976     if ConditionPassed() then
2977         EncodingSpecificOperations();
2978         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
2979         if d == 15 then         // Can only occur for ARM encoding
2980             ALUWritePC(result); // setflags is always FALSE here
2981         else
2982             R[d] = result;
2983             if setflags then
2984                 APSR.N = result<31>;
2985                 APSR.Z = IsZeroBit(result);
2986                 APSR.C = carry;
2987                 // APSR.V unchanged
2988 #endif
2989 
2990     return EmulateShiftImm (opcode, encoding, SRType_LSL);
2991 }
2992 
2993 // Logical Shift Left (register) shifts a register value left by a variable number of bits,
2994 // shifting in zeros, and writes the result to the destination register.  The variable number
2995 // of bits is read from the bottom byte of a register. It can optionally update the condition
2996 // flags based on the result.
2997 bool
2998 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding)
2999 {
3000 #if 0
3001     // ARM pseudo code...
3002     if ConditionPassed() then
3003         EncodingSpecificOperations();
3004         shift_n = UInt(R[m]<7:0>);
3005         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3006         R[d] = result;
3007         if setflags then
3008             APSR.N = result<31>;
3009             APSR.Z = IsZeroBit(result);
3010             APSR.C = carry;
3011             // APSR.V unchanged
3012 #endif
3013 
3014     return EmulateShiftReg (opcode, encoding, SRType_LSL);
3015 }
3016 
3017 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
3018 // shifting in zeros, and writes the result to the destination register.  It can optionally
3019 // update the condition flags based on the result.
3020 bool
3021 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding)
3022 {
3023 #if 0
3024     // ARM pseudo code...
3025     if ConditionPassed() then
3026         EncodingSpecificOperations();
3027         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3028         if d == 15 then         // Can only occur for ARM encoding
3029             ALUWritePC(result); // setflags is always FALSE here
3030         else
3031             R[d] = result;
3032             if setflags then
3033                 APSR.N = result<31>;
3034                 APSR.Z = IsZeroBit(result);
3035                 APSR.C = carry;
3036                 // APSR.V unchanged
3037 #endif
3038 
3039     return EmulateShiftImm (opcode, encoding, SRType_LSR);
3040 }
3041 
3042 // Logical Shift Right (register) shifts a register value right by a variable number of bits,
3043 // shifting in zeros, and writes the result to the destination register.  The variable number
3044 // of bits is read from the bottom byte of a register. It can optionally update the condition
3045 // flags based on the result.
3046 bool
3047 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding)
3048 {
3049 #if 0
3050     // ARM pseudo code...
3051     if ConditionPassed() then
3052         EncodingSpecificOperations();
3053         shift_n = UInt(R[m]<7:0>);
3054         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3055         R[d] = result;
3056         if setflags then
3057             APSR.N = result<31>;
3058             APSR.Z = IsZeroBit(result);
3059             APSR.C = carry;
3060             // APSR.V unchanged
3061 #endif
3062 
3063     return EmulateShiftReg (opcode, encoding, SRType_LSR);
3064 }
3065 
3066 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
3067 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3068 // It can optionally update the condition flags based on the result.
3069 bool
3070 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding)
3071 {
3072 #if 0
3073     // ARM pseudo code...
3074     if ConditionPassed() then
3075         EncodingSpecificOperations();
3076         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3077         if d == 15 then         // Can only occur for ARM encoding
3078             ALUWritePC(result); // setflags is always FALSE here
3079         else
3080             R[d] = result;
3081             if setflags then
3082                 APSR.N = result<31>;
3083                 APSR.Z = IsZeroBit(result);
3084                 APSR.C = carry;
3085                 // APSR.V unchanged
3086 #endif
3087 
3088     return EmulateShiftImm (opcode, encoding, SRType_ROR);
3089 }
3090 
3091 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
3092 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3093 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
3094 // flags based on the result.
3095 bool
3096 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding)
3097 {
3098 #if 0
3099     // ARM pseudo code...
3100     if ConditionPassed() then
3101         EncodingSpecificOperations();
3102         shift_n = UInt(R[m]<7:0>);
3103         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3104         R[d] = result;
3105         if setflags then
3106             APSR.N = result<31>;
3107             APSR.Z = IsZeroBit(result);
3108             APSR.C = carry;
3109             // APSR.V unchanged
3110 #endif
3111 
3112     return EmulateShiftReg (opcode, encoding, SRType_ROR);
3113 }
3114 
3115 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
3116 // with the carry flag shifted into bit [31].
3117 //
3118 // RRX can optionally update the condition flags based on the result.
3119 // In that case, bit [0] is shifted into the carry flag.
3120 bool
3121 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding)
3122 {
3123 #if 0
3124     // ARM pseudo code...
3125     if ConditionPassed() then
3126         EncodingSpecificOperations();
3127         (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3128         if d == 15 then         // Can only occur for ARM encoding
3129             ALUWritePC(result); // setflags is always FALSE here
3130         else
3131             R[d] = result;
3132             if setflags then
3133                 APSR.N = result<31>;
3134                 APSR.Z = IsZeroBit(result);
3135                 APSR.C = carry;
3136                 // APSR.V unchanged
3137 #endif
3138 
3139     return EmulateShiftImm (opcode, encoding, SRType_RRX);
3140 }
3141 
3142 bool
3143 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3144 {
3145 //    assert(shift_type == SRType_ASR
3146 //           || shift_type == SRType_LSL
3147 //           || shift_type == SRType_LSR
3148 //           || shift_type == SRType_ROR
3149 //           || shift_type == SRType_RRX);
3150 
3151     bool success = false;
3152 
3153     if (ConditionPassed(opcode))
3154     {
3155         uint32_t Rd;    // the destination register
3156         uint32_t Rm;    // the first operand register
3157         uint32_t imm5;  // encoding for the shift amount
3158         uint32_t carry; // the carry bit after the shift operation
3159         bool setflags;
3160 
3161         // Special case handling!
3162         // A8.6.139 ROR (immediate) -- Encoding T1
3163         ARMEncoding use_encoding = encoding;
3164         if (shift_type == SRType_ROR && use_encoding == eEncodingT1)
3165         {
3166             // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
3167             // have the same decoding of bit fields as the other Thumb2 shift operations.
3168             use_encoding = eEncodingT2;
3169         }
3170 
3171         switch (use_encoding) {
3172         case eEncodingT1:
3173             // Due to the above special case handling!
3174             if (shift_type == SRType_ROR)
3175                 return false;
3176 
3177             Rd = Bits32(opcode, 2, 0);
3178             Rm = Bits32(opcode, 5, 3);
3179             setflags = !InITBlock();
3180             imm5 = Bits32(opcode, 10, 6);
3181             break;
3182         case eEncodingT2:
3183             // A8.6.141 RRX
3184             // There's no imm form of RRX instructions.
3185             if (shift_type == SRType_RRX)
3186                 return false;
3187 
3188             Rd = Bits32(opcode, 11, 8);
3189             Rm = Bits32(opcode, 3, 0);
3190             setflags = BitIsSet(opcode, 20);
3191             imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3192             if (BadReg(Rd) || BadReg(Rm))
3193                 return false;
3194             break;
3195         case eEncodingA1:
3196             Rd = Bits32(opcode, 15, 12);
3197             Rm = Bits32(opcode, 3, 0);
3198             setflags = BitIsSet(opcode, 20);
3199             imm5 = Bits32(opcode, 11, 7);
3200             break;
3201         default:
3202             return false;
3203         }
3204 
3205         // A8.6.139 ROR (immediate)
3206         if (shift_type == SRType_ROR && imm5 == 0)
3207             shift_type = SRType_RRX;
3208 
3209         // Get the first operand.
3210         uint32_t value = ReadCoreReg (Rm, &success);
3211         if (!success)
3212             return false;
3213 
3214         // Decode the shift amount if not RRX.
3215         uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3216 
3217         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3218         if (!success)
3219             return false;
3220 
3221         // The context specifies that an immediate is to be moved into Rd.
3222         EmulateInstruction::Context context;
3223         context.type = EmulateInstruction::eContextImmediate;
3224         context.SetNoArgs ();
3225 
3226         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3227             return false;
3228     }
3229     return true;
3230 }
3231 
3232 bool
3233 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3234 {
3235     // assert(shift_type == SRType_ASR
3236     //        || shift_type == SRType_LSL
3237     //        || shift_type == SRType_LSR
3238     //        || shift_type == SRType_ROR);
3239 
3240     bool success = false;
3241 
3242     if (ConditionPassed(opcode))
3243     {
3244         uint32_t Rd;    // the destination register
3245         uint32_t Rn;    // the first operand register
3246         uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
3247         uint32_t carry; // the carry bit after the shift operation
3248         bool setflags;
3249         switch (encoding) {
3250         case eEncodingT1:
3251             Rd = Bits32(opcode, 2, 0);
3252             Rn = Rd;
3253             Rm = Bits32(opcode, 5, 3);
3254             setflags = !InITBlock();
3255             break;
3256         case eEncodingT2:
3257             Rd = Bits32(opcode, 11, 8);
3258             Rn = Bits32(opcode, 19, 16);
3259             Rm = Bits32(opcode, 3, 0);
3260             setflags = BitIsSet(opcode, 20);
3261             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3262                 return false;
3263             break;
3264         case eEncodingA1:
3265             Rd = Bits32(opcode, 15, 12);
3266             Rn = Bits32(opcode, 3, 0);
3267             Rm = Bits32(opcode, 11, 8);
3268             setflags = BitIsSet(opcode, 20);
3269             if (Rd == 15 || Rn == 15 || Rm == 15)
3270                 return false;
3271             break;
3272         default:
3273             return false;
3274         }
3275 
3276         // Get the first operand.
3277         uint32_t value = ReadCoreReg (Rn, &success);
3278         if (!success)
3279             return false;
3280         // Get the Rm register content.
3281         uint32_t val = ReadCoreReg (Rm, &success);
3282         if (!success)
3283             return false;
3284 
3285         // Get the shift amount.
3286         uint32_t amt = Bits32(val, 7, 0);
3287 
3288         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3289         if (!success)
3290             return false;
3291 
3292         // The context specifies that an immediate is to be moved into Rd.
3293         EmulateInstruction::Context context;
3294         context.type = EmulateInstruction::eContextImmediate;
3295         context.SetNoArgs ();
3296 
3297         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3298             return false;
3299     }
3300     return true;
3301 }
3302 
3303 // LDM loads multiple registers from consecutive memory locations, using an
3304 // address from a base register.  Optionally the address just above the highest of those locations
3305 // can be written back to the base register.
3306 bool
3307 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding)
3308 {
3309 #if 0
3310     // ARM pseudo code...
3311     if ConditionPassed()
3312         EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3313         address = R[n];
3314 
3315         for i = 0 to 14
3316             if registers<i> == '1' then
3317                 R[i] = MemA[address, 4]; address = address + 4;
3318         if registers<15> == '1' then
3319             LoadWritePC (MemA[address, 4]);
3320 
3321         if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3322         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3323 
3324 #endif
3325 
3326     bool success = false;
3327     bool conditional = false;
3328     if (ConditionPassed(opcode, &conditional))
3329     {
3330         uint32_t n;
3331         uint32_t registers = 0;
3332         bool wback;
3333         const uint32_t addr_byte_size = GetAddressByteSize();
3334         switch (encoding)
3335         {
3336             case eEncodingT1:
3337                 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0');
3338                 n = Bits32 (opcode, 10, 8);
3339                 registers = Bits32 (opcode, 7, 0);
3340                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3341                 wback = BitIsClear (registers, n);
3342                 // if BitCount(registers) < 1 then UNPREDICTABLE;
3343                 if (BitCount(registers) < 1)
3344                     return false;
3345                 break;
3346             case eEncodingT2:
3347                 // if W == '1' && Rn == '1101' then SEE POP;
3348                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3349                 n = Bits32 (opcode, 19, 16);
3350                 registers = Bits32 (opcode, 15, 0);
3351                 registers = registers & 0xdfff; // Make sure bit 13 is zero.
3352                 wback = BitIsSet (opcode, 21);
3353 
3354                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3355                 if ((n == 15)
3356                     || (BitCount (registers) < 2)
3357                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3358                     return false;
3359 
3360                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3361                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3362                     return false;
3363 
3364                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3365                 if (wback
3366                     && BitIsSet (registers, n))
3367                     return false;
3368                 break;
3369 
3370             case eEncodingA1:
3371                 n = Bits32 (opcode, 19, 16);
3372                 registers = Bits32 (opcode, 15, 0);
3373                 wback = BitIsSet (opcode, 21);
3374                 if ((n == 15)
3375                     || (BitCount (registers) < 1))
3376                     return false;
3377                 break;
3378             default:
3379                 return false;
3380         }
3381 
3382         int32_t offset = 0;
3383         const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3384         if (!success)
3385             return false;
3386 
3387         EmulateInstruction::Context context;
3388         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3389         RegisterInfo dwarf_reg;
3390         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3391         context.SetRegisterPlusOffset (dwarf_reg, offset);
3392 
3393         for (int i = 0; i < 14; ++i)
3394         {
3395             if (BitIsSet (registers, i))
3396             {
3397                 context.type = EmulateInstruction::eContextRegisterPlusOffset;
3398                 context.SetRegisterPlusOffset (dwarf_reg, offset);
3399                 if (wback && (n == 13)) // Pop Instruction
3400                 {
3401                     if (conditional)
3402                         context.type = EmulateInstruction::eContextRegisterLoad;
3403                     else
3404                         context.type = EmulateInstruction::eContextPopRegisterOffStack;
3405                 }
3406 
3407                 // R[i] = MemA [address, 4]; address = address + 4;
3408                 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3409                 if (!success)
3410                     return false;
3411 
3412                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3413                     return false;
3414 
3415                 offset += addr_byte_size;
3416             }
3417         }
3418 
3419         if (BitIsSet (registers, 15))
3420         {
3421             //LoadWritePC (MemA [address, 4]);
3422             context.type = EmulateInstruction::eContextRegisterPlusOffset;
3423             context.SetRegisterPlusOffset (dwarf_reg, offset);
3424             uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3425             if (!success)
3426                 return false;
3427             // In ARMv5T and above, this is an interworking branch.
3428             if (!LoadWritePC(context, data))
3429                 return false;
3430         }
3431 
3432         if (wback && BitIsClear (registers, n))
3433         {
3434             // R[n] = R[n] + 4 * BitCount (registers)
3435             int32_t offset = addr_byte_size * BitCount (registers);
3436             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3437             context.SetRegisterPlusOffset (dwarf_reg, offset);
3438 
3439             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
3440                 return false;
3441         }
3442         if (wback && BitIsSet (registers, n))
3443             // R[n] bits(32) UNKNOWN;
3444             return WriteBits32Unknown (n);
3445     }
3446     return true;
3447 }
3448 
3449 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register.
3450 // The consecutive memory locations end at this address and the address just below the lowest of those locations
3451 // can optionally be written back to the base register.
3452 bool
3453 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding)
3454 {
3455 #if 0
3456     // ARM pseudo code...
3457     if ConditionPassed() then
3458         EncodingSpecificOperations();
3459         address = R[n] - 4*BitCount(registers) + 4;
3460 
3461         for i = 0 to 14
3462             if registers<i> == '1' then
3463                   R[i] = MemA[address,4]; address = address + 4;
3464 
3465         if registers<15> == '1' then
3466             LoadWritePC(MemA[address,4]);
3467 
3468         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3469         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3470 #endif
3471 
3472     bool success = false;
3473 
3474     if (ConditionPassed(opcode))
3475     {
3476         uint32_t n;
3477         uint32_t registers = 0;
3478         bool wback;
3479         const uint32_t addr_byte_size = GetAddressByteSize();
3480 
3481         // EncodingSpecificOperations();
3482         switch (encoding)
3483         {
3484             case eEncodingA1:
3485                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3486                 n = Bits32 (opcode, 19, 16);
3487                 registers = Bits32 (opcode, 15, 0);
3488                 wback = BitIsSet (opcode, 21);
3489 
3490                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3491                 if ((n == 15) || (BitCount (registers) < 1))
3492                     return false;
3493 
3494                 break;
3495 
3496             default:
3497                 return false;
3498         }
3499         // address = R[n] - 4*BitCount(registers) + 4;
3500 
3501         int32_t offset = 0;
3502         addr_t Rn = ReadCoreReg (n, &success);
3503 
3504         if (!success)
3505             return false;
3506 
3507         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size;
3508 
3509         EmulateInstruction::Context context;
3510         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3511         RegisterInfo dwarf_reg;
3512         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3513         context.SetRegisterPlusOffset (dwarf_reg, offset);
3514 
3515         // for i = 0 to 14
3516         for (int i = 0; i < 14; ++i)
3517         {
3518             // if registers<i> == '1' then
3519             if (BitIsSet (registers, i))
3520             {
3521                   // R[i] = MemA[address,4]; address = address + 4;
3522                   context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3523                   uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3524                   if (!success)
3525                       return false;
3526                   if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3527                       return false;
3528                   offset += addr_byte_size;
3529             }
3530         }
3531 
3532         // if registers<15> == '1' then
3533         //     LoadWritePC(MemA[address,4]);
3534         if (BitIsSet (registers, 15))
3535         {
3536             context.SetRegisterPlusOffset (dwarf_reg, offset);
3537             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3538             if (!success)
3539                 return false;
3540             // In ARMv5T and above, this is an interworking branch.
3541             if (!LoadWritePC(context, data))
3542                 return false;
3543         }
3544 
3545         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3546         if (wback && BitIsClear (registers, n))
3547         {
3548             if (!success)
3549                 return false;
3550 
3551             offset = (addr_byte_size * BitCount (registers)) * -1;
3552             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3553             context.SetImmediateSigned (offset);
3554             addr_t addr = Rn + offset;
3555             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3556                 return false;
3557         }
3558 
3559         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3560         if (wback && BitIsSet (registers, n))
3561             return WriteBits32Unknown (n);
3562     }
3563     return true;
3564 }
3565 
3566 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
3567 // consecutive memory lcoations end just below this address, and the address of the lowest of those locations can
3568 // be optionally written back to the base register.
3569 bool
3570 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding)
3571 {
3572 #if 0
3573     // ARM pseudo code...
3574     if ConditionPassed() then
3575         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3576         address = R[n] - 4*BitCount(registers);
3577 
3578         for i = 0 to 14
3579             if registers<i> == '1' then
3580                   R[i] = MemA[address,4]; address = address + 4;
3581         if registers<15> == '1' then
3582                   LoadWritePC(MemA[address,4]);
3583 
3584         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3585         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3586 #endif
3587 
3588     bool success = false;
3589 
3590     if (ConditionPassed(opcode))
3591     {
3592         uint32_t n;
3593         uint32_t registers = 0;
3594         bool wback;
3595         const uint32_t addr_byte_size = GetAddressByteSize();
3596         switch (encoding)
3597         {
3598             case eEncodingT1:
3599                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3600                 n = Bits32 (opcode, 19, 16);
3601                 registers = Bits32 (opcode, 15, 0);
3602                 registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
3603                 wback = BitIsSet (opcode, 21);
3604 
3605                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3606                 if ((n == 15)
3607                     || (BitCount (registers) < 2)
3608                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3609                     return false;
3610 
3611                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3612                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3613                     return false;
3614 
3615                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3616                 if (wback && BitIsSet (registers, n))
3617                     return false;
3618 
3619                 break;
3620 
3621             case eEncodingA1:
3622                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3623                 n = Bits32 (opcode, 19, 16);
3624                 registers = Bits32 (opcode, 15, 0);
3625                 wback = BitIsSet (opcode, 21);
3626 
3627                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3628                 if ((n == 15) || (BitCount (registers) < 1))
3629                     return false;
3630 
3631                 break;
3632 
3633             default:
3634                 return false;
3635         }
3636 
3637         // address = R[n] - 4*BitCount(registers);
3638 
3639         int32_t offset = 0;
3640         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3641 
3642         if (!success)
3643             return false;
3644 
3645         addr_t address = Rn - (addr_byte_size * BitCount (registers));
3646         EmulateInstruction::Context context;
3647         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3648         RegisterInfo dwarf_reg;
3649         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3650         context.SetRegisterPlusOffset (dwarf_reg, Rn - address);
3651 
3652         for (int i = 0; i < 14; ++i)
3653         {
3654             if (BitIsSet (registers, i))
3655             {
3656                 // R[i] = MemA[address,4]; address = address + 4;
3657                 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3658                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3659                 if (!success)
3660                     return false;
3661 
3662                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3663                     return false;
3664 
3665                 offset += addr_byte_size;
3666             }
3667         }
3668 
3669         // if registers<15> == '1' then
3670         //     LoadWritePC(MemA[address,4]);
3671         if (BitIsSet (registers, 15))
3672         {
3673             context.SetRegisterPlusOffset (dwarf_reg, offset);
3674             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3675             if (!success)
3676                 return false;
3677             // In ARMv5T and above, this is an interworking branch.
3678             if (!LoadWritePC(context, data))
3679                 return false;
3680         }
3681 
3682         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3683         if (wback && BitIsClear (registers, n))
3684         {
3685             if (!success)
3686                 return false;
3687 
3688             offset = (addr_byte_size * BitCount (registers)) * -1;
3689             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3690             context.SetImmediateSigned (offset);
3691             addr_t addr = Rn + offset;
3692             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3693                 return false;
3694         }
3695 
3696         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3697         if (wback && BitIsSet (registers, n))
3698             return WriteBits32Unknown (n);
3699     }
3700     return true;
3701 }
3702 
3703 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
3704 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can
3705 // optinoally be written back to the base register.
3706 bool
3707 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding)
3708 {
3709 #if 0
3710     if ConditionPassed() then
3711         EncodingSpecificOperations();
3712         address = R[n] + 4;
3713 
3714         for i = 0 to 14
3715             if registers<i> == '1' then
3716                   R[i] = MemA[address,4]; address = address + 4;
3717         if registers<15> == '1' then
3718             LoadWritePC(MemA[address,4]);
3719 
3720         if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3721         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3722 #endif
3723 
3724     bool success = false;
3725 
3726     if (ConditionPassed(opcode))
3727     {
3728         uint32_t n;
3729         uint32_t registers = 0;
3730         bool wback;
3731         const uint32_t addr_byte_size = GetAddressByteSize();
3732         switch (encoding)
3733         {
3734             case eEncodingA1:
3735                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3736                 n = Bits32 (opcode, 19, 16);
3737                 registers = Bits32 (opcode, 15, 0);
3738                 wback = BitIsSet (opcode, 21);
3739 
3740                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3741                 if ((n == 15) || (BitCount (registers) < 1))
3742                     return false;
3743 
3744                 break;
3745             default:
3746                 return false;
3747         }
3748         // address = R[n] + 4;
3749 
3750         int32_t offset = 0;
3751         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3752 
3753         if (!success)
3754             return false;
3755 
3756         addr_t address = Rn + addr_byte_size;
3757 
3758         EmulateInstruction::Context context;
3759         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3760         RegisterInfo dwarf_reg;
3761         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3762         context.SetRegisterPlusOffset (dwarf_reg, offset);
3763 
3764         for (int i = 0; i < 14; ++i)
3765         {
3766             if (BitIsSet (registers, i))
3767             {
3768                 // R[i] = MemA[address,4]; address = address + 4;
3769 
3770                 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size);
3771                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3772                 if (!success)
3773                     return false;
3774 
3775                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3776                     return false;
3777 
3778                 offset += addr_byte_size;
3779             }
3780         }
3781 
3782         // if registers<15> == '1' then
3783         //     LoadWritePC(MemA[address,4]);
3784         if (BitIsSet (registers, 15))
3785         {
3786             context.SetRegisterPlusOffset (dwarf_reg, offset);
3787             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3788             if (!success)
3789                 return false;
3790             // In ARMv5T and above, this is an interworking branch.
3791             if (!LoadWritePC(context, data))
3792                 return false;
3793         }
3794 
3795         // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3796         if (wback && BitIsClear (registers, n))
3797         {
3798             if (!success)
3799                 return false;
3800 
3801             offset = addr_byte_size * BitCount (registers);
3802             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3803             context.SetImmediateSigned (offset);
3804             addr_t addr = Rn + offset;
3805             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3806                 return false;
3807         }
3808 
3809         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3810         if (wback && BitIsSet (registers, n))
3811             return WriteBits32Unknown (n);
3812     }
3813     return true;
3814 }
3815 
3816 // Load Register (immediate) calculates an address from a base register value and
3817 // an immediate offset, loads a word from memory, and writes to a register.
3818 // LDR (immediate, Thumb)
3819 bool
3820 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding)
3821 {
3822 #if 0
3823     // ARM pseudo code...
3824     if (ConditionPassed())
3825     {
3826         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3827         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3828         address = if index then offset_addr else R[n];
3829         data = MemU[address,4];
3830         if wback then R[n] = offset_addr;
3831         if t == 15 then
3832             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3833         elsif UnalignedSupport() || address<1:0> = '00' then
3834             R[t] = data;
3835         else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3836     }
3837 #endif
3838 
3839     bool success = false;
3840 
3841     if (ConditionPassed(opcode))
3842     {
3843         uint32_t Rt; // the destination register
3844         uint32_t Rn; // the base register
3845         uint32_t imm32; // the immediate offset used to form the address
3846         addr_t offset_addr; // the offset address
3847         addr_t address; // the calculated address
3848         uint32_t data; // the literal data value from memory load
3849         bool add, index, wback;
3850         switch (encoding) {
3851             case eEncodingT1:
3852                 Rt = Bits32(opcode, 2, 0);
3853                 Rn = Bits32(opcode, 5, 3);
3854                 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3855                 // index = TRUE; add = TRUE; wback = FALSE
3856                 add = true;
3857                 index = true;
3858                 wback = false;
3859 
3860                 break;
3861 
3862             case eEncodingT2:
3863                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
3864                 Rt = Bits32 (opcode, 10, 8);
3865                 Rn = 13;
3866                 imm32 = Bits32 (opcode, 7, 0) << 2;
3867 
3868                 // index = TRUE; add = TRUE; wback = FALSE;
3869                 index = true;
3870                 add = true;
3871                 wback = false;
3872 
3873                 break;
3874 
3875             case eEncodingT3:
3876                 // if Rn == '1111' then SEE LDR (literal);
3877                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
3878                 Rt = Bits32 (opcode, 15, 12);
3879                 Rn = Bits32 (opcode, 19, 16);
3880                 imm32 = Bits32 (opcode, 11, 0);
3881 
3882                 // index = TRUE; add = TRUE; wback = FALSE;
3883                 index = true;
3884                 add = true;
3885                 wback = false;
3886 
3887                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3888                 if ((Rt == 15) && InITBlock() && !LastInITBlock())
3889                     return false;
3890 
3891                 break;
3892 
3893             case eEncodingT4:
3894                 // if Rn == '1111' then SEE LDR (literal);
3895                 // if P == '1' && U == '1' && W == '0' then SEE LDRT;
3896                 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
3897                 // if P == '0' && W == '0' then UNDEFINED;
3898                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
3899                     return false;
3900 
3901                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
3902                 Rt = Bits32 (opcode, 15, 12);
3903                 Rn = Bits32 (opcode, 19, 16);
3904                 imm32 = Bits32 (opcode, 7, 0);
3905 
3906                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
3907                 index = BitIsSet (opcode, 10);
3908                 add = BitIsSet (opcode, 9);
3909                 wback = BitIsSet (opcode, 8);
3910 
3911                 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
3912                 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock()))
3913                     return false;
3914 
3915                 break;
3916 
3917             default:
3918                 return false;
3919         }
3920         uint32_t base = ReadCoreReg (Rn, &success);
3921         if (!success)
3922             return false;
3923         if (add)
3924             offset_addr = base + imm32;
3925         else
3926             offset_addr = base - imm32;
3927 
3928         address = (index ? offset_addr : base);
3929 
3930         RegisterInfo base_reg;
3931         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
3932         if (wback)
3933         {
3934             EmulateInstruction::Context ctx;
3935             ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
3936             ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3937 
3938             if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
3939                 return false;
3940         }
3941 
3942         // Prepare to write to the Rt register.
3943         EmulateInstruction::Context context;
3944         context.type = EmulateInstruction::eContextRegisterLoad;
3945         context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3946 
3947         // Read memory from the address.
3948         data = MemURead(context, address, 4, 0, &success);
3949         if (!success)
3950             return false;
3951 
3952         if (Rt == 15)
3953         {
3954             if (Bits32(address, 1, 0) == 0)
3955             {
3956                 if (!LoadWritePC(context, data))
3957                     return false;
3958             }
3959             else
3960                 return false;
3961         }
3962         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
3963         {
3964             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
3965                 return false;
3966         }
3967         else
3968             WriteBits32Unknown (Rt);
3969     }
3970     return true;
3971 }
3972 
3973 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
3974 // from a base register.  The consecutive memory locations start at this address, and teh address just above the last
3975 // of those locations can optionally be written back to the base register.
3976 bool
3977 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding)
3978 {
3979 #if 0
3980     if ConditionPassed() then
3981         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3982         address = R[n];
3983 
3984         for i = 0 to 14
3985             if registers<i> == '1' then
3986                 if i == n && wback && i != LowestSetBit(registers) then
3987                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
3988                 else
3989                     MemA[address,4] = R[i];
3990                 address = address + 4;
3991 
3992         if registers<15> == '1' then // Only possible for encoding A1
3993             MemA[address,4] = PCStoreValue();
3994         if wback then R[n] = R[n] + 4*BitCount(registers);
3995 #endif
3996 
3997     bool success = false;
3998 
3999     if (ConditionPassed(opcode))
4000     {
4001         uint32_t n;
4002         uint32_t registers = 0;
4003         bool wback;
4004         const uint32_t addr_byte_size = GetAddressByteSize();
4005 
4006         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4007         switch (encoding)
4008         {
4009             case eEncodingT1:
4010                 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4011                 n = Bits32 (opcode, 10, 8);
4012                 registers = Bits32 (opcode, 7, 0);
4013                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
4014                 wback = true;
4015 
4016                 // if BitCount(registers) < 1 then UNPREDICTABLE;
4017                 if (BitCount (registers) < 1)
4018                     return false;
4019 
4020                 break;
4021 
4022             case eEncodingT2:
4023                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4024                 n = Bits32 (opcode, 19, 16);
4025                 registers = Bits32 (opcode, 15, 0);
4026                 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4027                 wback = BitIsSet (opcode, 21);
4028 
4029                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4030                 if ((n == 15) || (BitCount (registers) < 2))
4031                     return false;
4032 
4033                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4034                 if (wback && BitIsSet (registers, n))
4035                     return false;
4036 
4037                 break;
4038 
4039             case eEncodingA1:
4040                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4041                 n = Bits32 (opcode, 19, 16);
4042                 registers = Bits32 (opcode, 15, 0);
4043                 wback = BitIsSet (opcode, 21);
4044 
4045                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4046                 if ((n == 15) || (BitCount (registers) < 1))
4047                     return false;
4048 
4049                 break;
4050 
4051             default:
4052                 return false;
4053         }
4054 
4055         // address = R[n];
4056         int32_t offset = 0;
4057         const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4058         if (!success)
4059             return false;
4060 
4061         EmulateInstruction::Context context;
4062         context.type = EmulateInstruction::eContextRegisterStore;
4063         RegisterInfo base_reg;
4064         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4065 
4066         // for i = 0 to 14
4067         int lowest_set_bit = 14;
4068         for (int i = 0; i < 14; ++i)
4069         {
4070             // if registers<i> == '1' then
4071             if (BitIsSet (registers, i))
4072             {
4073                   if (i < lowest_set_bit)
4074                       lowest_set_bit = i;
4075                   // if i == n && wback && i != LowestSetBit(registers) then
4076                   if ((i == n) && wback && (i != lowest_set_bit))
4077                       // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4078                       WriteBits32UnknownToMemory (address + offset);
4079                   else
4080                   {
4081                      // MemA[address,4] = R[i];
4082                       uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4083                       if (!success)
4084                           return false;
4085 
4086                       RegisterInfo data_reg;
4087                       GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4088                       context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4089                       if (!MemAWrite (context, address + offset, data, addr_byte_size))
4090                           return false;
4091                   }
4092 
4093                   // address = address + 4;
4094                   offset += addr_byte_size;
4095             }
4096         }
4097 
4098         // if registers<15> == '1' then // Only possible for encoding A1
4099         //     MemA[address,4] = PCStoreValue();
4100         if (BitIsSet (registers, 15))
4101         {
4102             RegisterInfo pc_reg;
4103             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4104             context.SetRegisterPlusOffset (pc_reg, 8);
4105             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4106             if (!success)
4107                 return false;
4108 
4109             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4110                 return false;
4111         }
4112 
4113         // if wback then R[n] = R[n] + 4*BitCount(registers);
4114         if (wback)
4115         {
4116             offset = addr_byte_size * BitCount (registers);
4117             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4118             context.SetImmediateSigned (offset);
4119             addr_t data = address + offset;
4120             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4121                 return false;
4122         }
4123     }
4124     return true;
4125 }
4126 
4127 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
4128 // from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
4129 // of those locations can optionally be written back to the base register.
4130 bool
4131 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding)
4132 {
4133 #if 0
4134     if ConditionPassed() then
4135         EncodingSpecificOperations();
4136         address = R[n] - 4*BitCount(registers) + 4;
4137 
4138         for i = 0 to 14
4139             if registers<i> == '1' then
4140                 if i == n && wback && i != LowestSetBit(registers) then
4141                     MemA[address,4] = bits(32) UNKNOWN;
4142                 else
4143                     MemA[address,4] = R[i];
4144                 address = address + 4;
4145 
4146         if registers<15> == '1' then
4147             MemA[address,4] = PCStoreValue();
4148 
4149         if wback then R[n] = R[n] - 4*BitCount(registers);
4150 #endif
4151 
4152     bool success = false;
4153 
4154     if (ConditionPassed(opcode))
4155     {
4156         uint32_t n;
4157         uint32_t registers = 0;
4158         bool wback;
4159         const uint32_t addr_byte_size = GetAddressByteSize();
4160 
4161         // EncodingSpecificOperations();
4162         switch (encoding)
4163         {
4164             case eEncodingA1:
4165                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4166                 n = Bits32 (opcode, 19, 16);
4167                 registers = Bits32 (opcode, 15, 0);
4168                 wback = BitIsSet (opcode, 21);
4169 
4170                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4171                 if ((n == 15) || (BitCount (registers) < 1))
4172                     return false;
4173                 break;
4174             default:
4175                 return false;
4176         }
4177 
4178         // address = R[n] - 4*BitCount(registers) + 4;
4179         int32_t offset = 0;
4180         addr_t Rn = ReadCoreReg (n, &success);
4181         if (!success)
4182             return false;
4183 
4184         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4;
4185 
4186         EmulateInstruction::Context context;
4187         context.type = EmulateInstruction::eContextRegisterStore;
4188         RegisterInfo base_reg;
4189         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4190 
4191         // for i = 0 to 14
4192         int lowest_bit_set = 14;
4193         for (int i = 0; i < 14; ++i)
4194         {
4195             // if registers<i> == '1' then
4196             if (BitIsSet (registers, i))
4197             {
4198                 if (i < lowest_bit_set)
4199                     lowest_bit_set = i;
4200                 //if i == n && wback && i != LowestSetBit(registers) then
4201                 if ((i == n) && wback && (i != lowest_bit_set))
4202                     // MemA[address,4] = bits(32) UNKNOWN;
4203                     WriteBits32UnknownToMemory (address + offset);
4204                 else
4205                 {
4206                     // MemA[address,4] = R[i];
4207                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4208                     if (!success)
4209                         return false;
4210 
4211                     RegisterInfo data_reg;
4212                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4213                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4214                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4215                         return false;
4216                 }
4217 
4218                 // address = address + 4;
4219                 offset += addr_byte_size;
4220             }
4221         }
4222 
4223         // if registers<15> == '1' then
4224         //    MemA[address,4] = PCStoreValue();
4225         if (BitIsSet (registers, 15))
4226         {
4227             RegisterInfo pc_reg;
4228             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4229             context.SetRegisterPlusOffset (pc_reg, 8);
4230             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4231             if (!success)
4232                 return false;
4233 
4234             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4235                 return false;
4236         }
4237 
4238         // if wback then R[n] = R[n] - 4*BitCount(registers);
4239         if (wback)
4240         {
4241             offset = (addr_byte_size * BitCount (registers)) * -1;
4242             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4243             context.SetImmediateSigned (offset);
4244             addr_t data = Rn + offset;
4245             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4246                 return false;
4247         }
4248     }
4249     return true;
4250 }
4251 
4252 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
4253 // from a base register.  The consecutive memory locations end just below this address, and the address of the first of
4254 // those locations can optionally be written back to the base register.
4255 bool
4256 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding)
4257 {
4258 #if 0
4259     if ConditionPassed() then
4260         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4261         address = R[n] - 4*BitCount(registers);
4262 
4263         for i = 0 to 14
4264             if registers<i> == '1' then
4265                 if i == n && wback && i != LowestSetBit(registers) then
4266                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4267                 else
4268                     MemA[address,4] = R[i];
4269                 address = address + 4;
4270 
4271         if registers<15> == '1' then // Only possible for encoding A1
4272             MemA[address,4] = PCStoreValue();
4273 
4274         if wback then R[n] = R[n] - 4*BitCount(registers);
4275 #endif
4276 
4277 
4278     bool success = false;
4279 
4280     if (ConditionPassed(opcode))
4281     {
4282         uint32_t n;
4283         uint32_t registers = 0;
4284         bool wback;
4285         const uint32_t addr_byte_size = GetAddressByteSize();
4286 
4287         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4288         switch (encoding)
4289         {
4290             case eEncodingT1:
4291                 // if W == '1' && Rn == '1101' then SEE PUSH;
4292                 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
4293                 {
4294                     // See PUSH
4295                 }
4296                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4297                 n = Bits32 (opcode, 19, 16);
4298                 registers = Bits32 (opcode, 15, 0);
4299                 registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
4300                 wback = BitIsSet (opcode, 21);
4301                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4302                 if ((n == 15) || BitCount (registers) < 2)
4303                     return false;
4304                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4305                 if (wback && BitIsSet (registers, n))
4306                     return false;
4307                 break;
4308 
4309             case eEncodingA1:
4310                 // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH;
4311                 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
4312                 {
4313                     // See Push
4314                 }
4315                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4316                 n = Bits32 (opcode, 19, 16);
4317                 registers = Bits32 (opcode, 15, 0);
4318                 wback = BitIsSet (opcode, 21);
4319                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4320                 if ((n == 15) || BitCount (registers) < 1)
4321                     return false;
4322                 break;
4323 
4324             default:
4325                 return false;
4326         }
4327 
4328         // address = R[n] - 4*BitCount(registers);
4329 
4330         int32_t offset = 0;
4331         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4332         if (!success)
4333         return false;
4334 
4335         addr_t address = Rn - (addr_byte_size * BitCount (registers));
4336 
4337         EmulateInstruction::Context context;
4338         context.type = EmulateInstruction::eContextRegisterStore;
4339         RegisterInfo base_reg;
4340         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4341 
4342         // for i = 0 to 14
4343         uint32_t lowest_set_bit = 14;
4344         for (int i = 0; i < 14; ++i)
4345         {
4346             // if registers<i> == '1' then
4347             if (BitIsSet (registers, i))
4348             {
4349                 if (i < lowest_set_bit)
4350                     lowest_set_bit = i;
4351                 // if i == n && wback && i != LowestSetBit(registers) then
4352                 if ((i == n) && wback && (i != lowest_set_bit))
4353                     // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4354                     WriteBits32UnknownToMemory (address + offset);
4355                 else
4356                 {
4357                     // MemA[address,4] = R[i];
4358                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4359                     if (!success)
4360                         return false;
4361 
4362                     RegisterInfo data_reg;
4363                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4364                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4365                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4366                         return false;
4367                 }
4368 
4369                 // address = address + 4;
4370                 offset += addr_byte_size;
4371             }
4372         }
4373 
4374         // if registers<15> == '1' then // Only possible for encoding A1
4375         //     MemA[address,4] = PCStoreValue();
4376         if (BitIsSet (registers, 15))
4377         {
4378             RegisterInfo pc_reg;
4379             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4380             context.SetRegisterPlusOffset (pc_reg, 8);
4381             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4382             if (!success)
4383                 return false;
4384 
4385             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4386                 return false;
4387         }
4388 
4389         // if wback then R[n] = R[n] - 4*BitCount(registers);
4390         if (wback)
4391         {
4392             offset = (addr_byte_size * BitCount (registers)) * -1;
4393             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4394             context.SetImmediateSigned (offset);
4395             addr_t data = Rn + offset;
4396             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4397                 return false;
4398         }
4399     }
4400     return true;
4401 }
4402 
4403 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
4404 // from a base register.  The consecutive memory locations start just above this address, and the address of the last
4405 // of those locations can optionally be written back to the base register.
4406 bool
4407 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding)
4408 {
4409 #if 0
4410     if ConditionPassed() then
4411         EncodingSpecificOperations();
4412         address = R[n] + 4;
4413 
4414         for i = 0 to 14
4415             if registers<i> == '1' then
4416                 if i == n && wback && i != LowestSetBit(registers) then
4417                     MemA[address,4] = bits(32) UNKNOWN;
4418                 else
4419                     MemA[address,4] = R[i];
4420                 address = address + 4;
4421 
4422         if registers<15> == '1' then
4423             MemA[address,4] = PCStoreValue();
4424 
4425         if wback then R[n] = R[n] + 4*BitCount(registers);
4426 #endif
4427 
4428     bool success = false;
4429 
4430     if (ConditionPassed(opcode))
4431     {
4432         uint32_t n;
4433         uint32_t registers = 0;
4434         bool wback;
4435         const uint32_t addr_byte_size = GetAddressByteSize();
4436 
4437         // EncodingSpecificOperations();
4438         switch (encoding)
4439         {
4440             case eEncodingA1:
4441                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4442                 n = Bits32 (opcode, 19, 16);
4443                 registers = Bits32 (opcode, 15, 0);
4444                 wback = BitIsSet (opcode, 21);
4445 
4446                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4447                 if ((n == 15) && (BitCount (registers) < 1))
4448                     return false;
4449                 break;
4450             default:
4451                 return false;
4452         }
4453         // address = R[n] + 4;
4454 
4455         int32_t offset = 0;
4456         addr_t Rn = ReadCoreReg (n, &success);
4457         if (!success)
4458             return false;
4459 
4460         addr_t address = Rn + addr_byte_size;
4461 
4462         EmulateInstruction::Context context;
4463         context.type = EmulateInstruction::eContextRegisterStore;
4464         RegisterInfo base_reg;
4465         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4466 
4467         uint32_t lowest_set_bit = 14;
4468         // for i = 0 to 14
4469         for (int i = 0; i < 14; ++i)
4470         {
4471             // if registers<i> == '1' then
4472             if (BitIsSet (registers, i))
4473             {
4474                 if (i < lowest_set_bit)
4475                     lowest_set_bit = i;
4476                 // if i == n && wback && i != LowestSetBit(registers) then
4477                 if ((i == n) && wback && (i != lowest_set_bit))
4478                     // MemA[address,4] = bits(32) UNKNOWN;
4479                     WriteBits32UnknownToMemory (address + offset);
4480                 // else
4481                 else
4482                 {
4483                     // MemA[address,4] = R[i];
4484                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4485                     if (!success)
4486                         return false;
4487 
4488                     RegisterInfo data_reg;
4489                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4490                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size);
4491                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4492                         return false;
4493                 }
4494 
4495                 // address = address + 4;
4496                 offset += addr_byte_size;
4497             }
4498         }
4499 
4500         // if registers<15> == '1' then
4501             // MemA[address,4] = PCStoreValue();
4502         if (BitIsSet (registers, 15))
4503         {
4504             RegisterInfo pc_reg;
4505             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4506             context.SetRegisterPlusOffset (pc_reg, 8);
4507             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4508             if (!success)
4509             return false;
4510 
4511             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4512                 return false;
4513         }
4514 
4515         // if wback then R[n] = R[n] + 4*BitCount(registers);
4516         if (wback)
4517         {
4518             offset = addr_byte_size * BitCount (registers);
4519             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4520             context.SetImmediateSigned (offset);
4521             addr_t data = Rn + offset;
4522             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4523                 return false;
4524         }
4525     }
4526     return true;
4527 }
4528 
4529 // STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word
4530 // from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
4531 bool
4532 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding)
4533 {
4534 #if 0
4535     if ConditionPassed() then
4536         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4537         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4538         address = if index then offset_addr else R[n];
4539         if UnalignedSupport() || address<1:0> == '00' then
4540             MemU[address,4] = R[t];
4541         else // Can only occur before ARMv7
4542             MemU[address,4] = bits(32) UNKNOWN;
4543         if wback then R[n] = offset_addr;
4544 #endif
4545 
4546     bool success = false;
4547 
4548     if (ConditionPassed(opcode))
4549     {
4550         const uint32_t addr_byte_size = GetAddressByteSize();
4551 
4552         uint32_t t;
4553         uint32_t n;
4554         uint32_t imm32;
4555         bool index;
4556         bool add;
4557         bool wback;
4558         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4559         switch (encoding)
4560         {
4561             case eEncodingT1:
4562                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
4563                 t = Bits32 (opcode, 2, 0);
4564                 n = Bits32 (opcode, 5, 3);
4565                 imm32 = Bits32 (opcode, 10, 6) << 2;
4566 
4567                 // index = TRUE; add = TRUE; wback = FALSE;
4568                 index = true;
4569                 add = false;
4570                 wback = false;
4571                 break;
4572 
4573             case eEncodingT2:
4574                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4575                 t = Bits32 (opcode, 10, 8);
4576                 n = 13;
4577                 imm32 = Bits32 (opcode, 7, 0) << 2;
4578 
4579                 // index = TRUE; add = TRUE; wback = FALSE;
4580                 index = true;
4581                 add = true;
4582                 wback = false;
4583                 break;
4584 
4585             case eEncodingT3:
4586                 // if Rn == '1111' then UNDEFINED;
4587                 if (Bits32 (opcode, 19, 16) == 15)
4588                     return false;
4589 
4590                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4591                 t = Bits32 (opcode, 15, 12);
4592                 n = Bits32 (opcode, 19, 16);
4593                 imm32 = Bits32 (opcode, 11, 0);
4594 
4595                 // index = TRUE; add = TRUE; wback = FALSE;
4596                 index = true;
4597                 add = true;
4598                 wback = false;
4599 
4600                 // if t == 15 then UNPREDICTABLE;
4601                 if (t == 15)
4602                     return false;
4603                 break;
4604 
4605             case eEncodingT4:
4606                 // if P == '1' && U == '1' && W == '0' then SEE STRT;
4607                 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH;
4608                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4609                 if ((Bits32 (opcode, 19, 16) == 15)
4610                       || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
4611                     return false;
4612 
4613                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4614                 t = Bits32 (opcode, 15, 12);
4615                 n = Bits32 (opcode, 19, 16);
4616                 imm32 = Bits32 (opcode, 7, 0);
4617 
4618                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4619                 index = BitIsSet (opcode, 10);
4620                 add = BitIsSet (opcode, 9);
4621                 wback = BitIsSet (opcode, 8);
4622 
4623                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
4624                 if ((t == 15) || (wback && (n == t)))
4625                     return false;
4626                 break;
4627 
4628             default:
4629                 return false;
4630         }
4631 
4632         addr_t offset_addr;
4633         addr_t address;
4634 
4635         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4636         uint32_t base_address = ReadCoreReg (n, &success);
4637         if (!success)
4638             return false;
4639 
4640         if (add)
4641             offset_addr = base_address + imm32;
4642         else
4643             offset_addr = base_address - imm32;
4644 
4645         // address = if index then offset_addr else R[n];
4646         if (index)
4647             address = offset_addr;
4648         else
4649             address = base_address;
4650 
4651         EmulateInstruction::Context context;
4652         context.type = eContextRegisterStore;
4653         RegisterInfo base_reg;
4654         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4655 
4656         // if UnalignedSupport() || address<1:0> == '00' then
4657         if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
4658         {
4659             // MemU[address,4] = R[t];
4660             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4661             if (!success)
4662                 return false;
4663 
4664             RegisterInfo data_reg;
4665             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4666             int32_t offset = address - base_address;
4667             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4668             if (!MemUWrite (context, address, data, addr_byte_size))
4669                 return false;
4670         }
4671         else
4672         {
4673             // MemU[address,4] = bits(32) UNKNOWN;
4674             WriteBits32UnknownToMemory (address);
4675         }
4676 
4677         // if wback then R[n] = offset_addr;
4678         if (wback)
4679         {
4680             context.type = eContextRegisterLoad;
4681             context.SetAddress (offset_addr);
4682             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4683                 return false;
4684         }
4685     }
4686     return true;
4687 }
4688 
4689 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a
4690 // word from a register to memory.   The offset register value can optionally be shifted.
4691 bool
4692 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding)
4693 {
4694 #if 0
4695     if ConditionPassed() then
4696         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4697         offset = Shift(R[m], shift_t, shift_n, APSR.C);
4698         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4699         address = if index then offset_addr else R[n];
4700         if t == 15 then // Only possible for encoding A1
4701             data = PCStoreValue();
4702         else
4703             data = R[t];
4704         if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4705             MemU[address,4] = data;
4706         else // Can only occur before ARMv7
4707             MemU[address,4] = bits(32) UNKNOWN;
4708         if wback then R[n] = offset_addr;
4709 #endif
4710 
4711     bool success = false;
4712 
4713     if (ConditionPassed(opcode))
4714     {
4715         const uint32_t addr_byte_size = GetAddressByteSize();
4716 
4717         uint32_t t;
4718         uint32_t n;
4719         uint32_t m;
4720         ARM_ShifterType shift_t;
4721         uint32_t shift_n;
4722         bool index;
4723         bool add;
4724         bool wback;
4725 
4726         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4727         switch (encoding)
4728         {
4729             case eEncodingT1:
4730                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4731                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4732                 t = Bits32 (opcode, 2, 0);
4733                 n = Bits32 (opcode, 5, 3);
4734                 m = Bits32 (opcode, 8, 6);
4735 
4736                 // index = TRUE; add = TRUE; wback = FALSE;
4737                 index = true;
4738                 add = true;
4739                 wback = false;
4740 
4741                 // (shift_t, shift_n) = (SRType_LSL, 0);
4742                 shift_t = SRType_LSL;
4743                 shift_n = 0;
4744                 break;
4745 
4746             case eEncodingT2:
4747                 // if Rn == '1111' then UNDEFINED;
4748                 if (Bits32 (opcode, 19, 16) == 15)
4749                     return false;
4750 
4751                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4752                 t = Bits32 (opcode, 15, 12);
4753                 n = Bits32 (opcode, 19, 16);
4754                 m = Bits32 (opcode, 3, 0);
4755 
4756                 // index = TRUE; add = TRUE; wback = FALSE;
4757                 index = true;
4758                 add = true;
4759                 wback = false;
4760 
4761                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4762                 shift_t = SRType_LSL;
4763                 shift_n = Bits32 (opcode, 5, 4);
4764 
4765                 // if t == 15 || BadReg(m) then UNPREDICTABLE;
4766                 if ((t == 15) || (BadReg (m)))
4767                     return false;
4768                 break;
4769 
4770             case eEncodingA1:
4771             {
4772                 // if P == '0' && W == '1' then SEE STRT;
4773                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4774                 t = Bits32 (opcode, 15, 12);
4775                 n = Bits32 (opcode, 19, 16);
4776                 m = Bits32 (opcode, 3, 0);
4777 
4778                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
4779                 index = BitIsSet (opcode, 24);
4780                 add = BitIsSet (opcode, 23);
4781                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
4782 
4783                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
4784                 uint32_t typ = Bits32 (opcode, 6, 5);
4785                 uint32_t imm5 = Bits32 (opcode, 11, 7);
4786                 shift_n = DecodeImmShift(typ, imm5, shift_t);
4787 
4788                 // if m == 15 then UNPREDICTABLE;
4789                 if (m == 15)
4790                     return false;
4791 
4792                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
4793                 if (wback && ((n == 15) || (n == t)))
4794                     return false;
4795 
4796                 break;
4797             }
4798             default:
4799                 return false;
4800         }
4801 
4802         addr_t offset_addr;
4803         addr_t address;
4804         int32_t offset = 0;
4805 
4806         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4807         if (!success)
4808             return false;
4809 
4810         uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
4811         if (!success)
4812             return false;
4813 
4814         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4815         offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success);
4816         if (!success)
4817             return false;
4818 
4819         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4820         if (add)
4821             offset_addr = base_address + offset;
4822         else
4823             offset_addr = base_address - offset;
4824 
4825         // address = if index then offset_addr else R[n];
4826         if (index)
4827             address = offset_addr;
4828         else
4829             address = base_address;
4830 
4831         uint32_t data;
4832         // if t == 15 then // Only possible for encoding A1
4833         if (t == 15)
4834             // data = PCStoreValue();
4835             data = ReadCoreReg (PC_REG, &success);
4836         else
4837             // data = R[t];
4838             data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4839 
4840         if (!success)
4841             return false;
4842 
4843         EmulateInstruction::Context context;
4844         context.type = eContextRegisterStore;
4845 
4846         // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4847         if (UnalignedSupport ()
4848             || (BitIsClear (address, 1) && BitIsClear (address, 0))
4849             || CurrentInstrSet() == eModeARM)
4850         {
4851             // MemU[address,4] = data;
4852 
4853             RegisterInfo base_reg;
4854             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 +  n, base_reg);
4855 
4856             RegisterInfo data_reg;
4857             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4858 
4859             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4860             if (!MemUWrite (context, address, data, addr_byte_size))
4861                 return false;
4862 
4863         }
4864         else
4865             // MemU[address,4] = bits(32) UNKNOWN;
4866             WriteBits32UnknownToMemory (address);
4867 
4868         // if wback then R[n] = offset_addr;
4869         if (wback)
4870         {
4871             context.type = eContextRegisterLoad;
4872             context.SetAddress (offset_addr);
4873             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4874                 return false;
4875         }
4876 
4877     }
4878     return true;
4879 }
4880 
4881 bool
4882 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding)
4883 {
4884 #if 0
4885     if ConditionPassed() then
4886         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4887         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4888         address = if index then offset_addr else R[n];
4889         MemU[address,1] = R[t]<7:0>;
4890         if wback then R[n] = offset_addr;
4891 #endif
4892 
4893 
4894     bool success = false;
4895 
4896     if (ConditionPassed(opcode))
4897     {
4898         uint32_t t;
4899         uint32_t n;
4900         uint32_t imm32;
4901         bool index;
4902         bool add;
4903         bool wback;
4904         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4905         switch (encoding)
4906         {
4907             case eEncodingT1:
4908                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
4909                 t = Bits32 (opcode, 2, 0);
4910                 n = Bits32 (opcode, 5, 3);
4911                 imm32 = Bits32 (opcode, 10, 6);
4912 
4913                 // index = TRUE; add = TRUE; wback = FALSE;
4914                 index = true;
4915                 add = true;
4916                 wback = false;
4917                 break;
4918 
4919             case eEncodingT2:
4920                 // if Rn == '1111' then UNDEFINED;
4921                 if (Bits32 (opcode, 19, 16) == 15)
4922                     return false;
4923 
4924                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4925                 t = Bits32 (opcode, 15, 12);
4926                 n = Bits32 (opcode, 19, 16);
4927                 imm32 = Bits32 (opcode, 11, 0);
4928 
4929                 // index = TRUE; add = TRUE; wback = FALSE;
4930                 index = true;
4931                 add = true;
4932                 wback = false;
4933 
4934                 // if BadReg(t) then UNPREDICTABLE;
4935                 if (BadReg (t))
4936                     return false;
4937                 break;
4938 
4939             case eEncodingT3:
4940                 // if P == '1' && U == '1' && W == '0' then SEE STRBT;
4941                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4942                 if (Bits32 (opcode, 19, 16) == 15)
4943                     return false;
4944 
4945                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4946                 t = Bits32 (opcode, 15, 12);
4947                 n = Bits32 (opcode, 19, 16);
4948                 imm32 = Bits32 (opcode, 7, 0);
4949 
4950                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4951                 index = BitIsSet (opcode, 10);
4952                 add = BitIsSet (opcode, 9);
4953                 wback = BitIsSet (opcode, 8);
4954 
4955                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
4956                 if ((BadReg (t)) || (wback && (n == t)))
4957                     return false;
4958                 break;
4959 
4960             default:
4961                 return false;
4962         }
4963 
4964         addr_t offset_addr;
4965         addr_t address;
4966         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4967         if (!success)
4968             return false;
4969 
4970         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4971         if (add)
4972             offset_addr = base_address + imm32;
4973         else
4974             offset_addr = base_address - imm32;
4975 
4976         // address = if index then offset_addr else R[n];
4977         if (index)
4978             address = offset_addr;
4979         else
4980             address = base_address;
4981 
4982         // MemU[address,1] = R[t]<7:0>
4983         RegisterInfo base_reg;
4984         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4985 
4986         RegisterInfo data_reg;
4987         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4988 
4989         EmulateInstruction::Context context;
4990         context.type = eContextRegisterStore;
4991         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4992 
4993         uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4994         if (!success)
4995             return false;
4996 
4997         data = Bits32 (data, 7, 0);
4998 
4999         if (!MemUWrite (context, address, data, 1))
5000             return false;
5001 
5002         // if wback then R[n] = offset_addr;
5003         if (wback)
5004         {
5005             context.type = eContextRegisterLoad;
5006             context.SetAddress (offset_addr);
5007             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5008                 return false;
5009         }
5010 
5011     }
5012 
5013     return true;
5014 }
5015 
5016 // STRH (register) calculates an address from a base register value and an offset register value, and stores a
5017 // halfword from a register to memory.  The offset register alue can be shifted left by 0, 1, 2, or 3 bits.
5018 bool
5019 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding)
5020 {
5021 #if 0
5022     if ConditionPassed() then
5023         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5024         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5025         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5026         address = if index then offset_addr else R[n];
5027         if UnalignedSupport() || address<0> == '0' then
5028             MemU[address,2] = R[t]<15:0>;
5029         else // Can only occur before ARMv7
5030             MemU[address,2] = bits(16) UNKNOWN;
5031         if wback then R[n] = offset_addr;
5032 #endif
5033 
5034     bool success = false;
5035 
5036     if (ConditionPassed(opcode))
5037     {
5038         uint32_t t;
5039         uint32_t n;
5040         uint32_t m;
5041         bool index;
5042         bool add;
5043         bool wback;
5044         ARM_ShifterType shift_t;
5045         uint32_t shift_n;
5046 
5047         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5048         switch (encoding)
5049         {
5050             case eEncodingT1:
5051                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5052                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5053                 t = Bits32 (opcode, 2, 0);
5054                 n = Bits32 (opcode, 5, 3);
5055                 m = Bits32 (opcode, 8, 6);
5056 
5057                 // index = TRUE; add = TRUE; wback = FALSE;
5058                 index = true;
5059                 add = true;
5060                 wback = false;
5061 
5062                 // (shift_t, shift_n) = (SRType_LSL, 0);
5063                 shift_t = SRType_LSL;
5064                 shift_n = 0;
5065 
5066                 break;
5067 
5068             case eEncodingT2:
5069                 // if Rn == '1111' then UNDEFINED;
5070                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5071                 t = Bits32 (opcode, 15, 12);
5072                 n = Bits32 (opcode, 19, 16);
5073                 m = Bits32 (opcode, 3, 0);
5074                 if (n == 15)
5075                     return false;
5076 
5077                 // index = TRUE; add = TRUE; wback = FALSE;
5078                 index = true;
5079                 add = true;
5080                 wback = false;
5081 
5082                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5083                 shift_t = SRType_LSL;
5084                 shift_n = Bits32 (opcode, 5, 4);
5085 
5086                 // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5087                 if (BadReg (t) || BadReg (m))
5088                     return false;
5089 
5090                 break;
5091 
5092             case eEncodingA1:
5093                 // if P == '0' && W == '1' then SEE STRHT;
5094                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5095                 t = Bits32 (opcode, 15, 12);
5096                 n = Bits32 (opcode, 19, 16);
5097                 m = Bits32 (opcode, 3, 0);
5098 
5099                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5100                 index = BitIsSet (opcode, 24);
5101                 add = BitIsSet (opcode, 23);
5102                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5103 
5104                 // (shift_t, shift_n) = (SRType_LSL, 0);
5105                 shift_t = SRType_LSL;
5106                 shift_n = 0;
5107 
5108                 // if t == 15 || m == 15 then UNPREDICTABLE;
5109                 if ((t == 15) || (m == 15))
5110                     return false;
5111 
5112                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5113                 if (wback && ((n == 15) || (n == t)))
5114                     return false;
5115 
5116                 break;
5117 
5118             default:
5119                 return false;
5120         }
5121 
5122         uint32_t Rm = ReadCoreReg (m, &success);
5123         if (!success)
5124             return false;
5125 
5126         uint32_t Rn = ReadCoreReg (n, &success);
5127         if (!success)
5128             return false;
5129 
5130         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5131         uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
5132         if (!success)
5133             return false;
5134 
5135         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5136         addr_t offset_addr;
5137         if (add)
5138             offset_addr = Rn + offset;
5139         else
5140             offset_addr = Rn - offset;
5141 
5142         // address = if index then offset_addr else R[n];
5143         addr_t address;
5144         if (index)
5145             address = offset_addr;
5146         else
5147             address = Rn;
5148 
5149         EmulateInstruction::Context context;
5150         context.type = eContextRegisterStore;
5151         RegisterInfo base_reg;
5152         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5153         RegisterInfo offset_reg;
5154         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5155 
5156         // if UnalignedSupport() || address<0> == '0' then
5157         if (UnalignedSupport() || BitIsClear (address, 0))
5158         {
5159             // MemU[address,2] = R[t]<15:0>;
5160             uint32_t Rt = ReadCoreReg (t, &success);
5161             if (!success)
5162                 return false;
5163 
5164             EmulateInstruction::Context context;
5165             context.type = eContextRegisterStore;
5166             RegisterInfo base_reg;
5167             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5168             RegisterInfo offset_reg;
5169             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5170             RegisterInfo data_reg;
5171             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5172             context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
5173 
5174             if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2))
5175                 return false;
5176         }
5177         else // Can only occur before ARMv7
5178         {
5179             // MemU[address,2] = bits(16) UNKNOWN;
5180         }
5181 
5182         // if wback then R[n] = offset_addr;
5183         if (wback)
5184         {
5185             context.type = eContextAdjustBaseRegister;
5186             context.SetAddress (offset_addr);
5187             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5188                 return false;
5189         }
5190     }
5191 
5192     return true;
5193 }
5194 
5195 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value,
5196 // and writes the result to the destination register.  It can optionally update the condition flags
5197 // based on the result.
5198 bool
5199 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding)
5200 {
5201 #if 0
5202     // ARM pseudo code...
5203     if ConditionPassed() then
5204         EncodingSpecificOperations();
5205         (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5206         if d == 15 then         // Can only occur for ARM encoding
5207             ALUWritePC(result); // setflags is always FALSE here
5208         else
5209             R[d] = result;
5210             if setflags then
5211                 APSR.N = result<31>;
5212                 APSR.Z = IsZeroBit(result);
5213                 APSR.C = carry;
5214                 APSR.V = overflow;
5215 #endif
5216 
5217     bool success = false;
5218 
5219     if (ConditionPassed(opcode))
5220     {
5221         uint32_t Rd, Rn;
5222         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
5223         bool setflags;
5224         switch (encoding)
5225         {
5226         case eEncodingT1:
5227             Rd = Bits32(opcode, 11, 8);
5228             Rn = Bits32(opcode, 19, 16);
5229             setflags = BitIsSet(opcode, 20);
5230             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5231             if (BadReg(Rd) || BadReg(Rn))
5232                 return false;
5233             break;
5234         case eEncodingA1:
5235             Rd = Bits32(opcode, 15, 12);
5236             Rn = Bits32(opcode, 19, 16);
5237             setflags = BitIsSet(opcode, 20);
5238             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5239 
5240             if (Rd == 15 && setflags)
5241                 return EmulateSUBSPcLrEtc (opcode, encoding);
5242             break;
5243         default:
5244             return false;
5245         }
5246 
5247         // Read the first operand.
5248         int32_t val1 = ReadCoreReg(Rn, &success);
5249         if (!success)
5250             return false;
5251 
5252         AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5253 
5254         EmulateInstruction::Context context;
5255         context.type = EmulateInstruction::eContextImmediate;
5256         context.SetNoArgs ();
5257 
5258         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5259             return false;
5260     }
5261     return true;
5262 }
5263 
5264 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted
5265 // register value, and writes the result to the destination register.  It can optionally update the
5266 // condition flags based on the result.
5267 bool
5268 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding)
5269 {
5270 #if 0
5271     // ARM pseudo code...
5272     if ConditionPassed() then
5273         EncodingSpecificOperations();
5274         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5275         (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5276         if d == 15 then         // Can only occur for ARM encoding
5277             ALUWritePC(result); // setflags is always FALSE here
5278         else
5279             R[d] = result;
5280             if setflags then
5281                 APSR.N = result<31>;
5282                 APSR.Z = IsZeroBit(result);
5283                 APSR.C = carry;
5284                 APSR.V = overflow;
5285 #endif
5286 
5287     bool success = false;
5288 
5289     if (ConditionPassed(opcode))
5290     {
5291         uint32_t Rd, Rn, Rm;
5292         ARM_ShifterType shift_t;
5293         uint32_t shift_n; // the shift applied to the value read from Rm
5294         bool setflags;
5295         switch (encoding)
5296         {
5297         case eEncodingT1:
5298             Rd = Rn = Bits32(opcode, 2, 0);
5299             Rm = Bits32(opcode, 5, 3);
5300             setflags = !InITBlock();
5301             shift_t = SRType_LSL;
5302             shift_n = 0;
5303             break;
5304         case eEncodingT2:
5305             Rd = Bits32(opcode, 11, 8);
5306             Rn = Bits32(opcode, 19, 16);
5307             Rm = Bits32(opcode, 3, 0);
5308             setflags = BitIsSet(opcode, 20);
5309             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5310             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5311                 return false;
5312             break;
5313         case eEncodingA1:
5314             Rd = Bits32(opcode, 15, 12);
5315             Rn = Bits32(opcode, 19, 16);
5316             Rm = Bits32(opcode, 3, 0);
5317             setflags = BitIsSet(opcode, 20);
5318             shift_n = DecodeImmShiftARM(opcode, shift_t);
5319 
5320             if (Rd == 15 && setflags)
5321                 return EmulateSUBSPcLrEtc (opcode, encoding);
5322             break;
5323         default:
5324             return false;
5325         }
5326 
5327         // Read the first operand.
5328         int32_t val1 = ReadCoreReg(Rn, &success);
5329         if (!success)
5330             return false;
5331 
5332         // Read the second operand.
5333         int32_t val2 = ReadCoreReg(Rm, &success);
5334         if (!success)
5335             return false;
5336 
5337         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5338         if (!success)
5339             return false;
5340         AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5341 
5342         EmulateInstruction::Context context;
5343         context.type = EmulateInstruction::eContextImmediate;
5344         context.SetNoArgs ();
5345 
5346         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5347             return false;
5348     }
5349     return true;
5350 }
5351 
5352 // This instruction adds an immediate value to the PC value to form a PC-relative address,
5353 // and writes the result to the destination register.
5354 bool
5355 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding)
5356 {
5357 #if 0
5358     // ARM pseudo code...
5359     if ConditionPassed() then
5360         EncodingSpecificOperations();
5361         result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5362         if d == 15 then         // Can only occur for ARM encodings
5363             ALUWritePC(result);
5364         else
5365             R[d] = result;
5366 #endif
5367 
5368     bool success = false;
5369 
5370     if (ConditionPassed(opcode))
5371     {
5372         uint32_t Rd;
5373         uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5374         bool add;
5375         switch (encoding)
5376         {
5377         case eEncodingT1:
5378             Rd = Bits32(opcode, 10, 8);
5379             imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5380             break;
5381         case eEncodingT2:
5382         case eEncodingT3:
5383             Rd = Bits32(opcode, 11, 8);
5384             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5385             add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5386             if (BadReg(Rd))
5387                 return false;
5388             break;
5389         case eEncodingA1:
5390         case eEncodingA2:
5391             Rd = Bits32(opcode, 15, 12);
5392             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5393             add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5394             break;
5395         default:
5396             return false;
5397         }
5398 
5399         // Read the PC value.
5400         uint32_t pc = ReadCoreReg(PC_REG, &success);
5401         if (!success)
5402             return false;
5403 
5404         uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5405 
5406         EmulateInstruction::Context context;
5407         context.type = EmulateInstruction::eContextImmediate;
5408         context.SetNoArgs ();
5409 
5410         if (!WriteCoreReg(context, result, Rd))
5411             return false;
5412     }
5413     return true;
5414 }
5415 
5416 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result
5417 // to the destination register.  It can optionally update the condition flags based on the result.
5418 bool
5419 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding)
5420 {
5421 #if 0
5422     // ARM pseudo code...
5423     if ConditionPassed() then
5424         EncodingSpecificOperations();
5425         result = R[n] AND imm32;
5426         if d == 15 then         // Can only occur for ARM encoding
5427             ALUWritePC(result); // setflags is always FALSE here
5428         else
5429             R[d] = result;
5430             if setflags then
5431                 APSR.N = result<31>;
5432                 APSR.Z = IsZeroBit(result);
5433                 APSR.C = carry;
5434                 // APSR.V unchanged
5435 #endif
5436 
5437     bool success = false;
5438 
5439     if (ConditionPassed(opcode))
5440     {
5441         uint32_t Rd, Rn;
5442         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
5443         bool setflags;
5444         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5445         switch (encoding)
5446         {
5447         case eEncodingT1:
5448             Rd = Bits32(opcode, 11, 8);
5449             Rn = Bits32(opcode, 19, 16);
5450             setflags = BitIsSet(opcode, 20);
5451             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5452             // if Rd == '1111' && S == '1' then SEE TST (immediate);
5453             if (Rd == 15 && setflags)
5454                 return EmulateTSTImm(opcode, eEncodingT1);
5455             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
5456                 return false;
5457             break;
5458         case eEncodingA1:
5459             Rd = Bits32(opcode, 15, 12);
5460             Rn = Bits32(opcode, 19, 16);
5461             setflags = BitIsSet(opcode, 20);
5462             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5463 
5464             if (Rd == 15 && setflags)
5465                 return EmulateSUBSPcLrEtc (opcode, encoding);
5466             break;
5467         default:
5468             return false;
5469         }
5470 
5471         // Read the first operand.
5472         uint32_t val1 = ReadCoreReg(Rn, &success);
5473         if (!success)
5474             return false;
5475 
5476         uint32_t result = val1 & imm32;
5477 
5478         EmulateInstruction::Context context;
5479         context.type = EmulateInstruction::eContextImmediate;
5480         context.SetNoArgs ();
5481 
5482         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5483             return false;
5484     }
5485     return true;
5486 }
5487 
5488 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value,
5489 // and writes the result to the destination register.  It can optionally update the condition flags
5490 // based on the result.
5491 bool
5492 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding)
5493 {
5494 #if 0
5495     // ARM pseudo code...
5496     if ConditionPassed() then
5497         EncodingSpecificOperations();
5498         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5499         result = R[n] AND shifted;
5500         if d == 15 then         // Can only occur for ARM encoding
5501             ALUWritePC(result); // setflags is always FALSE here
5502         else
5503             R[d] = result;
5504             if setflags then
5505                 APSR.N = result<31>;
5506                 APSR.Z = IsZeroBit(result);
5507                 APSR.C = carry;
5508                 // APSR.V unchanged
5509 #endif
5510 
5511     bool success = false;
5512 
5513     if (ConditionPassed(opcode))
5514     {
5515         uint32_t Rd, Rn, Rm;
5516         ARM_ShifterType shift_t;
5517         uint32_t shift_n; // the shift applied to the value read from Rm
5518         bool setflags;
5519         uint32_t carry;
5520         switch (encoding)
5521         {
5522         case eEncodingT1:
5523             Rd = Rn = Bits32(opcode, 2, 0);
5524             Rm = Bits32(opcode, 5, 3);
5525             setflags = !InITBlock();
5526             shift_t = SRType_LSL;
5527             shift_n = 0;
5528             break;
5529         case eEncodingT2:
5530             Rd = Bits32(opcode, 11, 8);
5531             Rn = Bits32(opcode, 19, 16);
5532             Rm = Bits32(opcode, 3, 0);
5533             setflags = BitIsSet(opcode, 20);
5534             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5535             // if Rd == '1111' && S == '1' then SEE TST (register);
5536             if (Rd == 15 && setflags)
5537                 return EmulateTSTReg(opcode, eEncodingT2);
5538             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
5539                 return false;
5540             break;
5541         case eEncodingA1:
5542             Rd = Bits32(opcode, 15, 12);
5543             Rn = Bits32(opcode, 19, 16);
5544             Rm = Bits32(opcode, 3, 0);
5545             setflags = BitIsSet(opcode, 20);
5546             shift_n = DecodeImmShiftARM(opcode, shift_t);
5547 
5548             if (Rd == 15 && setflags)
5549                 return EmulateSUBSPcLrEtc (opcode, encoding);
5550             break;
5551         default:
5552             return false;
5553         }
5554 
5555         // Read the first operand.
5556         uint32_t val1 = ReadCoreReg(Rn, &success);
5557         if (!success)
5558             return false;
5559 
5560         // Read the second operand.
5561         uint32_t val2 = ReadCoreReg(Rm, &success);
5562         if (!success)
5563             return false;
5564 
5565         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5566         if (!success)
5567             return false;
5568         uint32_t result = val1 & shifted;
5569 
5570         EmulateInstruction::Context context;
5571         context.type = EmulateInstruction::eContextImmediate;
5572         context.SetNoArgs ();
5573 
5574         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5575             return false;
5576     }
5577     return true;
5578 }
5579 
5580 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an
5581 // immediate value, and writes the result to the destination register.  It can optionally update the
5582 // condition flags based on the result.
5583 bool
5584 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding)
5585 {
5586 #if 0
5587     // ARM pseudo code...
5588     if ConditionPassed() then
5589         EncodingSpecificOperations();
5590         result = R[n] AND NOT(imm32);
5591         if d == 15 then         // Can only occur for ARM encoding
5592             ALUWritePC(result); // setflags is always FALSE here
5593         else
5594             R[d] = result;
5595             if setflags then
5596                 APSR.N = result<31>;
5597                 APSR.Z = IsZeroBit(result);
5598                 APSR.C = carry;
5599                 // APSR.V unchanged
5600 #endif
5601 
5602     bool success = false;
5603 
5604     if (ConditionPassed(opcode))
5605     {
5606         uint32_t Rd, Rn;
5607         uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn
5608         bool setflags;
5609         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5610         switch (encoding)
5611         {
5612         case eEncodingT1:
5613             Rd = Bits32(opcode, 11, 8);
5614             Rn = Bits32(opcode, 19, 16);
5615             setflags = BitIsSet(opcode, 20);
5616             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5617             if (BadReg(Rd) || BadReg(Rn))
5618                 return false;
5619             break;
5620         case eEncodingA1:
5621             Rd = Bits32(opcode, 15, 12);
5622             Rn = Bits32(opcode, 19, 16);
5623             setflags = BitIsSet(opcode, 20);
5624             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5625 
5626             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5627             if (Rd == 15 && setflags)
5628                 return EmulateSUBSPcLrEtc (opcode, encoding);
5629             break;
5630         default:
5631             return false;
5632         }
5633 
5634         // Read the first operand.
5635         uint32_t val1 = ReadCoreReg(Rn, &success);
5636         if (!success)
5637             return false;
5638 
5639         uint32_t result = val1 & ~imm32;
5640 
5641         EmulateInstruction::Context context;
5642         context.type = EmulateInstruction::eContextImmediate;
5643         context.SetNoArgs ();
5644 
5645         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5646             return false;
5647     }
5648     return true;
5649 }
5650 
5651 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an
5652 // optionally-shifted register value, and writes the result to the destination register.
5653 // It can optionally update the condition flags based on the result.
5654 bool
5655 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding)
5656 {
5657 #if 0
5658     // ARM pseudo code...
5659     if ConditionPassed() then
5660         EncodingSpecificOperations();
5661         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5662         result = R[n] AND NOT(shifted);
5663         if d == 15 then         // Can only occur for ARM encoding
5664             ALUWritePC(result); // setflags is always FALSE here
5665         else
5666             R[d] = result;
5667             if setflags then
5668                 APSR.N = result<31>;
5669                 APSR.Z = IsZeroBit(result);
5670                 APSR.C = carry;
5671                 // APSR.V unchanged
5672 #endif
5673 
5674     bool success = false;
5675 
5676     if (ConditionPassed(opcode))
5677     {
5678         uint32_t Rd, Rn, Rm;
5679         ARM_ShifterType shift_t;
5680         uint32_t shift_n; // the shift applied to the value read from Rm
5681         bool setflags;
5682         uint32_t carry;
5683         switch (encoding)
5684         {
5685         case eEncodingT1:
5686             Rd = Rn = Bits32(opcode, 2, 0);
5687             Rm = Bits32(opcode, 5, 3);
5688             setflags = !InITBlock();
5689             shift_t = SRType_LSL;
5690             shift_n = 0;
5691             break;
5692         case eEncodingT2:
5693             Rd = Bits32(opcode, 11, 8);
5694             Rn = Bits32(opcode, 19, 16);
5695             Rm = Bits32(opcode, 3, 0);
5696             setflags = BitIsSet(opcode, 20);
5697             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5698             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5699                 return false;
5700             break;
5701         case eEncodingA1:
5702             Rd = Bits32(opcode, 15, 12);
5703             Rn = Bits32(opcode, 19, 16);
5704             Rm = Bits32(opcode, 3, 0);
5705             setflags = BitIsSet(opcode, 20);
5706             shift_n = DecodeImmShiftARM(opcode, shift_t);
5707 
5708             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5709             if (Rd == 15 && setflags)
5710                 return EmulateSUBSPcLrEtc (opcode, encoding);
5711             break;
5712         default:
5713             return false;
5714         }
5715 
5716         // Read the first operand.
5717         uint32_t val1 = ReadCoreReg(Rn, &success);
5718         if (!success)
5719             return false;
5720 
5721         // Read the second operand.
5722         uint32_t val2 = ReadCoreReg(Rm, &success);
5723         if (!success)
5724             return false;
5725 
5726         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5727         if (!success)
5728             return false;
5729         uint32_t result = val1 & ~shifted;
5730 
5731         EmulateInstruction::Context context;
5732         context.type = EmulateInstruction::eContextImmediate;
5733         context.SetNoArgs ();
5734 
5735         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5736             return false;
5737     }
5738     return true;
5739 }
5740 
5741 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
5742 // from memory, and writes it to a register.  It can use offset, post-indexed, or pre-indexed addressing.
5743 bool
5744 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding)
5745 {
5746 #if 0
5747     if ConditionPassed() then
5748         EncodingSpecificOperations();
5749         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5750         address = if index then offset_addr else R[n];
5751         data = MemU[address,4];
5752         if wback then R[n] = offset_addr;
5753         if t == 15 then
5754             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5755         elsif UnalignedSupport() || address<1:0> = '00' then
5756             R[t] = data;
5757         else // Can only apply before ARMv7
5758             R[t] = ROR(data, 8*UInt(address<1:0>));
5759 #endif
5760 
5761     bool success = false;
5762 
5763     if (ConditionPassed(opcode))
5764     {
5765         const uint32_t addr_byte_size = GetAddressByteSize();
5766 
5767         uint32_t t;
5768         uint32_t n;
5769         uint32_t imm32;
5770         bool index;
5771         bool add;
5772         bool wback;
5773 
5774         switch (encoding)
5775         {
5776             case eEncodingA1:
5777                 // if Rn == '1111' then SEE LDR (literal);
5778                 // if P == '0' && W == '1' then SEE LDRT;
5779                 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP;
5780                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5781                 t = Bits32 (opcode, 15, 12);
5782                 n = Bits32 (opcode, 19, 16);
5783                 imm32 = Bits32 (opcode, 11, 0);
5784 
5785                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5786                 index = BitIsSet (opcode, 24);
5787                 add = BitIsSet (opcode, 23);
5788                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5789 
5790                 // if wback && n == t then UNPREDICTABLE;
5791                 if (wback && (n == t))
5792                     return false;
5793 
5794                 break;
5795 
5796             default:
5797                 return false;
5798         }
5799 
5800         addr_t address;
5801         addr_t offset_addr;
5802         addr_t base_address = ReadCoreReg (n, &success);
5803         if (!success)
5804             return false;
5805 
5806         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5807         if (add)
5808             offset_addr = base_address + imm32;
5809         else
5810             offset_addr = base_address - imm32;
5811 
5812         // address = if index then offset_addr else R[n];
5813         if (index)
5814             address = offset_addr;
5815         else
5816             address = base_address;
5817 
5818         // data = MemU[address,4];
5819 
5820         RegisterInfo base_reg;
5821         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5822 
5823         EmulateInstruction::Context context;
5824         context.type = eContextRegisterLoad;
5825         context.SetRegisterPlusOffset (base_reg, address - base_address);
5826 
5827         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5828         if (!success)
5829             return false;
5830 
5831         // if wback then R[n] = offset_addr;
5832         if (wback)
5833         {
5834             context.type = eContextAdjustBaseRegister;
5835             context.SetAddress (offset_addr);
5836             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5837                 return false;
5838         }
5839 
5840         // if t == 15 then
5841         if (t == 15)
5842         {
5843             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5844             if (BitIsClear (address, 1) && BitIsClear (address, 0))
5845             {
5846                 // LoadWritePC (data);
5847                 context.type = eContextRegisterLoad;
5848                 context.SetRegisterPlusOffset (base_reg, address - base_address);
5849                 LoadWritePC (context, data);
5850             }
5851             else
5852                   return false;
5853         }
5854         // elsif UnalignedSupport() || address<1:0> = '00' then
5855         else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5856         {
5857             // R[t] = data;
5858             context.type = eContextRegisterLoad;
5859             context.SetRegisterPlusOffset (base_reg, address - base_address);
5860             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5861                 return false;
5862         }
5863         // else // Can only apply before ARMv7
5864         else
5865         {
5866             // R[t] = ROR(data, 8*UInt(address<1:0>));
5867             data = ROR (data, Bits32 (address, 1, 0), &success);
5868             if (!success)
5869                 return false;
5870             context.type = eContextRegisterLoad;
5871             context.SetImmediate (data);
5872             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5873                 return false;
5874         }
5875 
5876     }
5877     return true;
5878 }
5879 
5880 // LDR (register) calculates an address from a base register value and an offset register value, loads a word
5881 // from memory, and writes it to a resgister.  The offset register value can optionally be shifted.
5882 bool
5883 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding)
5884 {
5885 #if 0
5886     if ConditionPassed() then
5887         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5888         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5889         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5890         address = if index then offset_addr else R[n];
5891         data = MemU[address,4];
5892         if wback then R[n] = offset_addr;
5893         if t == 15 then
5894             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5895         elsif UnalignedSupport() || address<1:0> = '00' then
5896             R[t] = data;
5897         else // Can only apply before ARMv7
5898             if CurrentInstrSet() == InstrSet_ARM then
5899                 R[t] = ROR(data, 8*UInt(address<1:0>));
5900             else
5901                 R[t] = bits(32) UNKNOWN;
5902 #endif
5903 
5904     bool success = false;
5905 
5906     if (ConditionPassed(opcode))
5907     {
5908         const uint32_t addr_byte_size = GetAddressByteSize();
5909 
5910         uint32_t t;
5911         uint32_t n;
5912         uint32_t m;
5913         bool index;
5914         bool add;
5915         bool wback;
5916         ARM_ShifterType shift_t;
5917         uint32_t shift_n;
5918 
5919         switch (encoding)
5920         {
5921             case eEncodingT1:
5922                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5923                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5924                 t = Bits32 (opcode, 2, 0);
5925                 n = Bits32 (opcode, 5, 3);
5926                 m = Bits32 (opcode, 8, 6);
5927 
5928                 // index = TRUE; add = TRUE; wback = FALSE;
5929                 index = true;
5930                 add = true;
5931                 wback = false;
5932 
5933                 // (shift_t, shift_n) = (SRType_LSL, 0);
5934                 shift_t = SRType_LSL;
5935                 shift_n = 0;
5936 
5937                 break;
5938 
5939             case eEncodingT2:
5940                 // if Rn == '1111' then SEE LDR (literal);
5941                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5942                 t = Bits32 (opcode, 15, 12);
5943                 n = Bits32 (opcode, 19, 16);
5944                 m = Bits32 (opcode, 3, 0);
5945 
5946                 // index = TRUE; add = TRUE; wback = FALSE;
5947                 index = true;
5948                 add = true;
5949                 wback = false;
5950 
5951                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5952                 shift_t = SRType_LSL;
5953                 shift_n = Bits32 (opcode, 5, 4);
5954 
5955                 // if BadReg(m) then UNPREDICTABLE;
5956                 if (BadReg (m))
5957                     return false;
5958 
5959                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
5960                 if ((t == 15) && InITBlock() && !LastInITBlock())
5961                     return false;
5962 
5963                 break;
5964 
5965             case eEncodingA1:
5966             {
5967                 // if P == '0' && W == '1' then SEE LDRT;
5968                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5969                 t = Bits32 (opcode, 15, 12);
5970                 n = Bits32 (opcode, 19, 16);
5971                 m = Bits32 (opcode, 3, 0);
5972 
5973                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5974                 index = BitIsSet (opcode, 24);
5975                 add = BitIsSet (opcode, 23);
5976                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5977 
5978                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
5979                 uint32_t type = Bits32 (opcode, 6, 5);
5980                 uint32_t imm5 = Bits32 (opcode, 11, 7);
5981                 shift_n = DecodeImmShift (type, imm5, shift_t);
5982 
5983                 // if m == 15 then UNPREDICTABLE;
5984                 if (m == 15)
5985                     return false;
5986 
5987                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5988                 if (wback && ((n == 15) || (n == t)))
5989                     return false;
5990             }
5991                 break;
5992 
5993 
5994             default:
5995                 return false;
5996         }
5997 
5998         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
5999         if (!success)
6000             return false;
6001 
6002         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6003         if (!success)
6004             return false;
6005 
6006         addr_t offset_addr;
6007         addr_t address;
6008 
6009         // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an application level alias for the CPSR".
6010         addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success);
6011         if (!success)
6012             return false;
6013 
6014         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6015         if (add)
6016             offset_addr = Rn + offset;
6017         else
6018             offset_addr = Rn - offset;
6019 
6020         // address = if index then offset_addr else R[n];
6021             if (index)
6022                 address = offset_addr;
6023             else
6024                 address = Rn;
6025 
6026         // data = MemU[address,4];
6027         RegisterInfo base_reg;
6028         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6029 
6030         EmulateInstruction::Context context;
6031         context.type = eContextRegisterLoad;
6032         context.SetRegisterPlusOffset (base_reg, address - Rn);
6033 
6034         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
6035         if (!success)
6036             return false;
6037 
6038         // if wback then R[n] = offset_addr;
6039         if (wback)
6040         {
6041             context.type = eContextAdjustBaseRegister;
6042             context.SetAddress (offset_addr);
6043             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6044                 return false;
6045         }
6046 
6047         // if t == 15 then
6048         if (t == 15)
6049         {
6050             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6051             if (BitIsClear (address, 1) && BitIsClear (address, 0))
6052             {
6053                 context.type = eContextRegisterLoad;
6054                 context.SetRegisterPlusOffset (base_reg, address - Rn);
6055                 LoadWritePC (context, data);
6056             }
6057             else
6058                 return false;
6059         }
6060         // elsif UnalignedSupport() || address<1:0> = '00' then
6061         else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
6062         {
6063             // R[t] = data;
6064             context.type = eContextRegisterLoad;
6065             context.SetRegisterPlusOffset (base_reg, address - Rn);
6066             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6067                 return false;
6068         }
6069         else // Can only apply before ARMv7
6070         {
6071             // if CurrentInstrSet() == InstrSet_ARM then
6072             if (CurrentInstrSet () == eModeARM)
6073             {
6074                 // R[t] = ROR(data, 8*UInt(address<1:0>));
6075                 data = ROR (data, Bits32 (address, 1, 0), &success);
6076                 if (!success)
6077                     return false;
6078                 context.type = eContextRegisterLoad;
6079                 context.SetImmediate (data);
6080                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6081                     return false;
6082             }
6083             else
6084             {
6085                 // R[t] = bits(32) UNKNOWN;
6086                 WriteBits32Unknown (t);
6087             }
6088         }
6089     }
6090     return true;
6091 }
6092 
6093 // LDRB (immediate, Thumb)
6094 bool
6095 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6096 {
6097 #if 0
6098     if ConditionPassed() then
6099         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6100         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6101         address = if index then offset_addr else R[n];
6102         R[t] = ZeroExtend(MemU[address,1], 32);
6103         if wback then R[n] = offset_addr;
6104 #endif
6105 
6106     bool success = false;
6107 
6108     if (ConditionPassed(opcode))
6109     {
6110         uint32_t t;
6111         uint32_t n;
6112         uint32_t imm32;
6113         bool index;
6114         bool add;
6115         bool wback;
6116 
6117         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6118         switch (encoding)
6119         {
6120             case eEncodingT1:
6121                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6122                 t = Bits32 (opcode, 2, 0);
6123                 n = Bits32 (opcode, 5, 3);
6124                 imm32 = Bits32 (opcode, 10, 6);
6125 
6126                 // index = TRUE; add = TRUE; wback = FALSE;
6127                 index = true;
6128                 add = true;
6129                 wback= false;
6130 
6131                 break;
6132 
6133             case eEncodingT2:
6134                 // if Rt == '1111' then SEE PLD;
6135                 // if Rn == '1111' then SEE LDRB (literal);
6136                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6137                 t = Bits32 (opcode, 15, 12);
6138                 n = Bits32 (opcode, 19, 16);
6139                 imm32 = Bits32 (opcode, 11, 0);
6140 
6141                 // index = TRUE; add = TRUE; wback = FALSE;
6142                 index = true;
6143                 add = true;
6144                 wback = false;
6145 
6146                 // if t == 13 then UNPREDICTABLE;
6147                 if (t == 13)
6148                     return false;
6149 
6150                 break;
6151 
6152             case eEncodingT3:
6153                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6154                 // if Rn == '1111' then SEE LDRB (literal);
6155                 // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6156                 // if P == '0' && W == '0' then UNDEFINED;
6157                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6158                     return false;
6159 
6160                   // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6161                 t = Bits32 (opcode, 15, 12);
6162                 n = Bits32 (opcode, 19, 16);
6163                 imm32 = Bits32 (opcode, 7, 0);
6164 
6165                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6166                 index = BitIsSet (opcode, 10);
6167                 add = BitIsSet (opcode, 9);
6168                 wback = BitIsSet (opcode, 8);
6169 
6170                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6171                 if (BadReg (t) || (wback && (n == t)))
6172                     return false;
6173 
6174                 break;
6175 
6176             default:
6177                 return false;
6178         }
6179 
6180         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6181         if (!success)
6182             return false;
6183 
6184         addr_t address;
6185         addr_t offset_addr;
6186 
6187         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6188         if (add)
6189             offset_addr = Rn + imm32;
6190         else
6191             offset_addr = Rn - imm32;
6192 
6193         // address = if index then offset_addr else R[n];
6194         if (index)
6195             address = offset_addr;
6196         else
6197             address = Rn;
6198 
6199         // R[t] = ZeroExtend(MemU[address,1], 32);
6200         RegisterInfo base_reg;
6201         RegisterInfo data_reg;
6202         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6203         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6204 
6205         EmulateInstruction::Context context;
6206         context.type = eContextRegisterLoad;
6207         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
6208 
6209         uint64_t data = MemURead (context, address, 1, 0, &success);
6210         if (!success)
6211             return false;
6212 
6213         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6214             return false;
6215 
6216         // if wback then R[n] = offset_addr;
6217         if (wback)
6218         {
6219             context.type = eContextAdjustBaseRegister;
6220             context.SetAddress (offset_addr);
6221             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6222                 return false;
6223         }
6224     }
6225     return true;
6226 }
6227 
6228 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6229 // zero-extends it to form a 32-bit word and writes it to a register.
6230 bool
6231 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6232 {
6233 #if 0
6234     if ConditionPassed() then
6235         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6236         base = Align(PC,4);
6237         address = if add then (base + imm32) else (base - imm32);
6238         R[t] = ZeroExtend(MemU[address,1], 32);
6239 #endif
6240 
6241     bool success = false;
6242 
6243     if (ConditionPassed(opcode))
6244     {
6245         uint32_t t;
6246         uint32_t imm32;
6247         bool add;
6248         switch (encoding)
6249         {
6250             case eEncodingT1:
6251                 // if Rt == '1111' then SEE PLD;
6252                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6253                 t = Bits32 (opcode, 15, 12);
6254                 imm32 = Bits32 (opcode, 11, 0);
6255                 add = BitIsSet (opcode, 23);
6256 
6257                 // if t == 13 then UNPREDICTABLE;
6258                 if (t == 13)
6259                     return false;
6260 
6261                 break;
6262 
6263             case eEncodingA1:
6264                 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6265                 t = Bits32 (opcode, 15, 12);
6266                 imm32 = Bits32 (opcode, 11, 0);
6267                 add = BitIsSet (opcode, 23);
6268 
6269                 // if t == 15 then UNPREDICTABLE;
6270                 if (t == 15)
6271                     return false;
6272                 break;
6273 
6274             default:
6275                 return false;
6276         }
6277 
6278         // base = Align(PC,4);
6279         uint32_t pc_val = ReadCoreReg (PC_REG, &success);
6280         if (!success)
6281             return false;
6282 
6283         uint32_t base = AlignPC (pc_val);
6284 
6285         addr_t address;
6286         // address = if add then (base + imm32) else (base - imm32);
6287         if (add)
6288             address = base + imm32;
6289         else
6290             address = base - imm32;
6291 
6292         // R[t] = ZeroExtend(MemU[address,1], 32);
6293         EmulateInstruction::Context context;
6294         context.type = eContextRelativeBranchImmediate;
6295         context.SetImmediate (address - base);
6296 
6297         uint64_t data = MemURead (context, address, 1, 0, &success);
6298         if (!success)
6299             return false;
6300 
6301         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6302             return false;
6303     }
6304     return true;
6305 }
6306 
6307 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from
6308 // memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6309 // optionally be shifted.
6310 bool
6311 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding)
6312 {
6313 #if 0
6314     if ConditionPassed() then
6315         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6316         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6317         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6318         address = if index then offset_addr else R[n];
6319         R[t] = ZeroExtend(MemU[address,1],32);
6320         if wback then R[n] = offset_addr;
6321 #endif
6322 
6323     bool success = false;
6324 
6325     if (ConditionPassed(opcode))
6326     {
6327         uint32_t t;
6328         uint32_t n;
6329         uint32_t m;
6330         bool index;
6331         bool add;
6332         bool wback;
6333         ARM_ShifterType shift_t;
6334         uint32_t shift_n;
6335 
6336         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6337         switch (encoding)
6338         {
6339             case eEncodingT1:
6340                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6341                 t = Bits32 (opcode, 2, 0);
6342                 n = Bits32 (opcode, 5, 3);
6343                 m = Bits32 (opcode, 8, 6);
6344 
6345                 // index = TRUE; add = TRUE; wback = FALSE;
6346                 index = true;
6347                 add = true;
6348                 wback = false;
6349 
6350                 // (shift_t, shift_n) = (SRType_LSL, 0);
6351                 shift_t = SRType_LSL;
6352                 shift_n = 0;
6353                 break;
6354 
6355             case eEncodingT2:
6356                 // if Rt == '1111' then SEE PLD;
6357                 // if Rn == '1111' then SEE LDRB (literal);
6358                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6359                 t = Bits32 (opcode, 15, 12);
6360                 n = Bits32 (opcode, 19, 16);
6361                 m = Bits32 (opcode, 3, 0);
6362 
6363                 // index = TRUE; add = TRUE; wback = FALSE;
6364                 index = true;
6365                 add = true;
6366                 wback = false;
6367 
6368                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6369                 shift_t = SRType_LSL;
6370                 shift_n = Bits32 (opcode, 5, 4);
6371 
6372                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6373                 if ((t == 13) || BadReg (m))
6374                     return false;
6375                 break;
6376 
6377             case eEncodingA1:
6378             {
6379                 // if P == '0' && W == '1' then SEE LDRBT;
6380                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6381                 t = Bits32 (opcode, 15, 12);
6382                 n = Bits32 (opcode, 19, 16);
6383                 m = Bits32 (opcode, 3, 0);
6384 
6385                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6386                 index = BitIsSet (opcode, 24);
6387                 add = BitIsSet (opcode, 23);
6388                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6389 
6390                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6391                 uint32_t type = Bits32 (opcode, 6, 5);
6392                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6393                 shift_n = DecodeImmShift (type, imm5, shift_t);
6394 
6395                 // if t == 15 || m == 15 then UNPREDICTABLE;
6396                 if ((t == 15) || (m == 15))
6397                     return false;
6398 
6399                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6400                 if (wback && ((n == 15) || (n == t)))
6401                     return false;
6402             }
6403                 break;
6404 
6405             default:
6406                 return false;
6407         }
6408 
6409         addr_t offset_addr;
6410         addr_t address;
6411 
6412         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6413         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6414         if (!success)
6415             return false;
6416 
6417         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6418         if (!success)
6419             return false;
6420 
6421         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6422         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6423         if (!success)
6424             return false;
6425 
6426         if (add)
6427             offset_addr = Rn + offset;
6428         else
6429             offset_addr = Rn - offset;
6430 
6431         // address = if index then offset_addr else R[n];
6432         if (index)
6433             address = offset_addr;
6434         else
6435             address = Rn;
6436 
6437         // R[t] = ZeroExtend(MemU[address,1],32);
6438         RegisterInfo base_reg;
6439         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6440 
6441         EmulateInstruction::Context context;
6442         context.type = eContextRegisterLoad;
6443         context.SetRegisterPlusOffset (base_reg, address - Rn);
6444 
6445         uint64_t data = MemURead (context, address, 1, 0, &success);
6446         if (!success)
6447             return false;
6448 
6449         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6450             return false;
6451 
6452         // if wback then R[n] = offset_addr;
6453         if (wback)
6454         {
6455             context.type = eContextAdjustBaseRegister;
6456             context.SetAddress (offset_addr);
6457             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6458                 return false;
6459         }
6460     }
6461     return true;
6462 }
6463 
6464 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a
6465 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register.  It can use offset,
6466 // post-indexed, or pre-indexed addressing.
6467 bool
6468 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding)
6469 {
6470 #if 0
6471     if ConditionPassed() then
6472         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6473         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6474         address = if index then offset_addr else R[n];
6475         data = MemU[address,2];
6476         if wback then R[n] = offset_addr;
6477         if UnalignedSupport() || address<0> = '0' then
6478             R[t] = ZeroExtend(data, 32);
6479         else // Can only apply before ARMv7
6480             R[t] = bits(32) UNKNOWN;
6481 #endif
6482 
6483 
6484     bool success = false;
6485 
6486     if (ConditionPassed(opcode))
6487     {
6488         uint32_t t;
6489         uint32_t n;
6490         uint32_t imm32;
6491         bool index;
6492         bool add;
6493         bool wback;
6494 
6495         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6496         switch (encoding)
6497         {
6498             case eEncodingT1:
6499                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
6500                 t = Bits32 (opcode, 2, 0);
6501                 n = Bits32 (opcode, 5, 3);
6502                 imm32 = Bits32 (opcode, 10, 6) << 1;
6503 
6504                 // index = TRUE; add = TRUE; wback = FALSE;
6505                 index = true;
6506                 add = true;
6507                 wback = false;
6508 
6509                 break;
6510 
6511             case eEncodingT2:
6512                 // if Rt == '1111' then SEE "Unallocated memory hints";
6513                 // if Rn == '1111' then SEE LDRH (literal);
6514                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6515                 t = Bits32 (opcode, 15, 12);
6516                 n = Bits32 (opcode, 19, 16);
6517                 imm32 = Bits32 (opcode, 11, 0);
6518 
6519                 // index = TRUE; add = TRUE; wback = FALSE;
6520                 index = true;
6521                 add = true;
6522                 wback = false;
6523 
6524                 // if t == 13 then UNPREDICTABLE;
6525                 if (t == 13)
6526                     return false;
6527                 break;
6528 
6529             case eEncodingT3:
6530                 // if Rn == '1111' then SEE LDRH (literal);
6531                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
6532                 // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
6533                 // if P == '0' && W == '0' then UNDEFINED;
6534                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6535                     return false;
6536 
6537                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6538                 t = Bits32 (opcode, 15, 12);
6539                 n = Bits32 (opcode, 19, 16);
6540                 imm32 = Bits32 (opcode, 7, 0);
6541 
6542                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6543                 index = BitIsSet (opcode, 10);
6544                 add = BitIsSet (opcode, 9);
6545                 wback = BitIsSet (opcode, 8);
6546 
6547                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6548                 if (BadReg (t) || (wback && (n == t)))
6549                     return false;
6550                 break;
6551 
6552             default:
6553                 return false;
6554         }
6555 
6556         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6557         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6558         if (!success)
6559             return false;
6560 
6561         addr_t offset_addr;
6562         addr_t address;
6563 
6564         if (add)
6565             offset_addr = Rn + imm32;
6566         else
6567             offset_addr = Rn - imm32;
6568 
6569         // address = if index then offset_addr else R[n];
6570         if (index)
6571             address = offset_addr;
6572         else
6573             address = Rn;
6574 
6575         // data = MemU[address,2];
6576         RegisterInfo base_reg;
6577         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6578 
6579         EmulateInstruction::Context context;
6580         context.type = eContextRegisterLoad;
6581         context.SetRegisterPlusOffset (base_reg, address - Rn);
6582 
6583         uint64_t data = MemURead (context, address, 2, 0, &success);
6584         if (!success)
6585             return false;
6586 
6587         // if wback then R[n] = offset_addr;
6588         if (wback)
6589         {
6590             context.type = eContextAdjustBaseRegister;
6591             context.SetAddress (offset_addr);
6592             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6593                 return false;
6594         }
6595 
6596         // if UnalignedSupport() || address<0> = '0' then
6597         if (UnalignedSupport () || BitIsClear (address, 0))
6598         {
6599             // R[t] = ZeroExtend(data, 32);
6600             context.type = eContextRegisterLoad;
6601             context.SetRegisterPlusOffset (base_reg, address - Rn);
6602             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6603                 return false;
6604         }
6605         else // Can only apply before ARMv7
6606         {
6607             // R[t] = bits(32) UNKNOWN;
6608             WriteBits32Unknown (t);
6609         }
6610     }
6611     return true;
6612 }
6613 
6614 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory,
6615 // zero-extends it to form a 32-bit word, and writes it to a register.
6616 bool
6617 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding)
6618 {
6619 #if 0
6620     if ConditionPassed() then
6621         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6622         base = Align(PC,4);
6623         address = if add then (base + imm32) else (base - imm32);
6624         data = MemU[address,2];
6625         if UnalignedSupport() || address<0> = '0' then
6626             R[t] = ZeroExtend(data, 32);
6627         else // Can only apply before ARMv7
6628             R[t] = bits(32) UNKNOWN;
6629 #endif
6630 
6631     bool success = false;
6632 
6633     if (ConditionPassed(opcode))
6634     {
6635         uint32_t t;
6636         uint32_t imm32;
6637         bool add;
6638 
6639         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6640         switch (encoding)
6641         {
6642             case eEncodingT1:
6643                 // if Rt == '1111' then SEE "Unallocated memory hints";
6644                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6645                 t = Bits32 (opcode, 15, 12);
6646                 imm32 = Bits32 (opcode, 11, 0);
6647                 add = BitIsSet (opcode, 23);
6648 
6649                 // if t == 13 then UNPREDICTABLE;
6650                 if (t == 13)
6651                     return false;
6652 
6653                 break;
6654 
6655             case eEncodingA1:
6656             {
6657                 uint32_t imm4H = Bits32 (opcode, 11, 8);
6658                 uint32_t imm4L = Bits32 (opcode, 3, 0);
6659 
6660                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6661                 t = Bits32 (opcode, 15, 12);
6662                 imm32 = (imm4H << 4) | imm4L;
6663                 add = BitIsSet (opcode, 23);
6664 
6665                 // if t == 15 then UNPREDICTABLE;
6666                 if (t == 15)
6667                     return false;
6668                 break;
6669             }
6670 
6671             default:
6672                 return false;
6673         }
6674 
6675         // base = Align(PC,4);
6676         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6677         if (!success)
6678             return false;
6679 
6680         addr_t base = AlignPC (pc_value);
6681         addr_t address;
6682 
6683         // address = if add then (base + imm32) else (base - imm32);
6684         if (add)
6685             address = base + imm32;
6686         else
6687             address = base - imm32;
6688 
6689         // data = MemU[address,2];
6690         RegisterInfo base_reg;
6691         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
6692 
6693         EmulateInstruction::Context context;
6694         context.type = eContextRegisterLoad;
6695         context.SetRegisterPlusOffset (base_reg, address - base);
6696 
6697         uint64_t data = MemURead (context, address, 2, 0, &success);
6698         if (!success)
6699             return false;
6700 
6701 
6702         // if UnalignedSupport() || address<0> = '0' then
6703         if (UnalignedSupport () || BitIsClear (address, 0))
6704         {
6705             // R[t] = ZeroExtend(data, 32);
6706             context.type = eContextRegisterLoad;
6707             context.SetRegisterPlusOffset (base_reg, address - base);
6708             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6709                 return false;
6710 
6711         }
6712         else // Can only apply before ARMv7
6713         {
6714             // R[t] = bits(32) UNKNOWN;
6715             WriteBits32Unknown (t);
6716         }
6717     }
6718     return true;
6719 }
6720 
6721 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword
6722 // from memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6723 // be shifted left by 0, 1, 2, or 3 bits.
6724 bool
6725 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding)
6726 {
6727 #if 0
6728     if ConditionPassed() then
6729         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6730         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6731         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6732         address = if index then offset_addr else R[n];
6733         data = MemU[address,2];
6734         if wback then R[n] = offset_addr;
6735         if UnalignedSupport() || address<0> = '0' then
6736             R[t] = ZeroExtend(data, 32);
6737         else // Can only apply before ARMv7
6738             R[t] = bits(32) UNKNOWN;
6739 #endif
6740 
6741     bool success = false;
6742 
6743     if (ConditionPassed(opcode))
6744     {
6745         uint32_t t;
6746         uint32_t n;
6747         uint32_t m;
6748         bool index;
6749         bool add;
6750         bool wback;
6751         ARM_ShifterType shift_t;
6752         uint32_t shift_n;
6753 
6754         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6755         switch (encoding)
6756         {
6757             case eEncodingT1:
6758                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6759                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6760                 t = Bits32 (opcode, 2, 0);
6761                 n = Bits32 (opcode, 5, 3);
6762                 m = Bits32 (opcode, 8, 6);
6763 
6764                 // index = TRUE; add = TRUE; wback = FALSE;
6765                 index = true;
6766                 add = true;
6767                 wback = false;
6768 
6769                 // (shift_t, shift_n) = (SRType_LSL, 0);
6770                 shift_t = SRType_LSL;
6771                 shift_n = 0;
6772 
6773                 break;
6774 
6775             case eEncodingT2:
6776                 // if Rn == '1111' then SEE LDRH (literal);
6777                 // if Rt == '1111' then SEE "Unallocated memory hints";
6778                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6779                 t = Bits32 (opcode, 15, 12);
6780                 n = Bits32 (opcode, 19, 16);
6781                 m = Bits32 (opcode, 3, 0);
6782 
6783                 // index = TRUE; add = TRUE; wback = FALSE;
6784                 index = true;
6785                 add = true;
6786                 wback = false;
6787 
6788                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6789                 shift_t = SRType_LSL;
6790                 shift_n = Bits32 (opcode, 5, 4);
6791 
6792                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6793                 if ((t == 13) || BadReg (m))
6794                     return false;
6795                 break;
6796 
6797             case eEncodingA1:
6798                 // if P == '0' && W == '1' then SEE LDRHT;
6799                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6800                 t = Bits32 (opcode, 15, 12);
6801                 n = Bits32 (opcode, 19, 16);
6802                 m = Bits32 (opcode, 3, 0);
6803 
6804                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6805                 index = BitIsSet (opcode, 24);
6806                 add = BitIsSet (opcode, 23);
6807                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6808 
6809                 // (shift_t, shift_n) = (SRType_LSL, 0);
6810                 shift_t = SRType_LSL;
6811                 shift_n = 0;
6812 
6813                 // if t == 15 || m == 15 then UNPREDICTABLE;
6814                 if ((t == 15) || (m == 15))
6815                     return false;
6816 
6817                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6818                 if (wback && ((n == 15) || (n == t)))
6819                     return false;
6820 
6821                 break;
6822 
6823             default:
6824                 return false;
6825         }
6826 
6827         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6828 
6829         uint64_t Rm  = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6830         if (!success)
6831             return false;
6832 
6833         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6834         if (!success)
6835             return false;
6836 
6837         addr_t offset_addr;
6838         addr_t address;
6839 
6840         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6841         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6842         if (!success)
6843             return false;
6844 
6845         if (add)
6846             offset_addr = Rn + offset;
6847         else
6848             offset_addr = Rn - offset;
6849 
6850         // address = if index then offset_addr else R[n];
6851         if (index)
6852             address = offset_addr;
6853         else
6854             address = Rn;
6855 
6856         // data = MemU[address,2];
6857         RegisterInfo base_reg;
6858         RegisterInfo offset_reg;
6859         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6860         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
6861 
6862         EmulateInstruction::Context context;
6863         context.type = eContextRegisterLoad;
6864         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6865         uint64_t data = MemURead (context, address, 2, 0, &success);
6866         if (!success)
6867             return false;
6868 
6869         // if wback then R[n] = offset_addr;
6870         if (wback)
6871         {
6872             context.type = eContextAdjustBaseRegister;
6873             context.SetAddress (offset_addr);
6874             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6875                 return false;
6876         }
6877 
6878         // if UnalignedSupport() || address<0> = '0' then
6879         if (UnalignedSupport() || BitIsClear (address, 0))
6880         {
6881             // R[t] = ZeroExtend(data, 32);
6882             context.type = eContextRegisterLoad;
6883             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6884             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6885                 return false;
6886         }
6887         else // Can only apply before ARMv7
6888         {
6889             // R[t] = bits(32) UNKNOWN;
6890             WriteBits32Unknown (t);
6891         }
6892     }
6893     return true;
6894 }
6895 
6896 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from
6897 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed,
6898 // or pre-indexed addressing.
6899 bool
6900 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6901 {
6902 #if 0
6903     if ConditionPassed() then
6904         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6905         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6906         address = if index then offset_addr else R[n];
6907         R[t] = SignExtend(MemU[address,1], 32);
6908         if wback then R[n] = offset_addr;
6909 #endif
6910 
6911     bool success = false;
6912 
6913     if (ConditionPassed(opcode))
6914     {
6915         uint32_t t;
6916         uint32_t n;
6917         uint32_t imm32;
6918         bool index;
6919         bool add;
6920         bool wback;
6921 
6922         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6923         switch (encoding)
6924         {
6925             case eEncodingT1:
6926                 // if Rt == '1111' then SEE PLI;
6927                 // if Rn == '1111' then SEE LDRSB (literal);
6928                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6929                 t = Bits32 (opcode, 15, 12);
6930                 n = Bits32 (opcode, 19, 16);
6931                 imm32 = Bits32 (opcode, 11, 0);
6932 
6933                 // index = TRUE; add = TRUE; wback = FALSE;
6934                 index = true;
6935                 add = true;
6936                 wback = false;
6937 
6938                 // if t == 13 then UNPREDICTABLE;
6939                 if (t == 13)
6940                     return false;
6941 
6942                 break;
6943 
6944             case eEncodingT2:
6945                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
6946                 // if Rn == '1111' then SEE LDRSB (literal);
6947                 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
6948                 // if P == '0' && W == '0' then UNDEFINED;
6949                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6950                     return false;
6951 
6952                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6953                 t = Bits32 (opcode, 15, 12);
6954                 n = Bits32 (opcode, 19, 16);
6955                 imm32 = Bits32 (opcode, 7, 0);
6956 
6957                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6958                 index = BitIsSet (opcode, 10);
6959                 add = BitIsSet (opcode, 9);
6960                 wback = BitIsSet (opcode, 8);
6961 
6962                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6963                   if (((t == 13) || ((t == 15)
6964                                      && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8))))
6965                       || (wback && (n == t)))
6966                     return false;
6967 
6968                 break;
6969 
6970             case eEncodingA1:
6971             {
6972                 // if Rn == '1111' then SEE LDRSB (literal);
6973                 // if P == '0' && W == '1' then SEE LDRSBT;
6974                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
6975                 t = Bits32 (opcode, 15, 12);
6976                 n = Bits32 (opcode, 19, 16);
6977 
6978                 uint32_t imm4H = Bits32 (opcode, 11, 8);
6979                 uint32_t imm4L = Bits32 (opcode, 3, 0);
6980                 imm32 = (imm4H << 4) | imm4L;
6981 
6982                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6983                 index = BitIsSet (opcode, 24);
6984                 add = BitIsSet (opcode, 23);
6985                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6986 
6987                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
6988                 if ((t == 15) || (wback && (n == t)))
6989                     return false;
6990 
6991                 break;
6992             }
6993 
6994             default:
6995                 return false;
6996         }
6997 
6998         uint64_t Rn = ReadCoreReg (n, &success);
6999         if (!success)
7000             return false;
7001 
7002         addr_t offset_addr;
7003         addr_t address;
7004 
7005         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7006         if (add)
7007             offset_addr = Rn + imm32;
7008         else
7009             offset_addr = Rn - imm32;
7010 
7011         // address = if index then offset_addr else R[n];
7012         if (index)
7013             address = offset_addr;
7014         else
7015             address = Rn;
7016 
7017         // R[t] = SignExtend(MemU[address,1], 32);
7018         RegisterInfo base_reg;
7019         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7020 
7021         EmulateInstruction::Context context;
7022         context.type = eContextRegisterLoad;
7023         context.SetRegisterPlusOffset (base_reg, address - Rn);
7024 
7025         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7026         if (!success)
7027             return false;
7028 
7029         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7030         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7031             return false;
7032 
7033         // if wback then R[n] = offset_addr;
7034         if (wback)
7035         {
7036             context.type = eContextAdjustBaseRegister;
7037             context.SetAddress (offset_addr);
7038             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7039                 return false;
7040         }
7041     }
7042 
7043     return true;
7044 }
7045 
7046 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
7047 // sign-extends it to form a 32-bit word, and writes tit to a register.
7048 bool
7049 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding)
7050 {
7051 #if 0
7052     if ConditionPassed() then
7053         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7054         base = Align(PC,4);
7055         address = if add then (base + imm32) else (base - imm32);
7056         R[t] = SignExtend(MemU[address,1], 32);
7057 #endif
7058 
7059     bool success = false;
7060 
7061     if (ConditionPassed(opcode))
7062     {
7063         uint32_t t;
7064         uint32_t imm32;
7065         bool add;
7066 
7067         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7068         switch (encoding)
7069         {
7070             case eEncodingT1:
7071                 // if Rt == '1111' then SEE PLI;
7072                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7073                 t = Bits32 (opcode, 15, 12);
7074                 imm32 = Bits32 (opcode, 11, 0);
7075                 add = BitIsSet (opcode, 23);
7076 
7077                 // if t == 13 then UNPREDICTABLE;
7078                 if (t == 13)
7079                     return false;
7080 
7081                 break;
7082 
7083             case eEncodingA1:
7084             {
7085                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7086                 t = Bits32 (opcode, 15, 12);
7087                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7088                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7089                 imm32 = (imm4H << 4) | imm4L;
7090                 add = BitIsSet (opcode, 23);
7091 
7092                 // if t == 15 then UNPREDICTABLE;
7093                 if (t == 15)
7094                     return false;
7095 
7096                 break;
7097             }
7098 
7099             default:
7100                 return false;
7101         }
7102 
7103         // base = Align(PC,4);
7104         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7105         if (!success)
7106             return false;
7107         uint64_t base = AlignPC (pc_value);
7108 
7109         // address = if add then (base + imm32) else (base - imm32);
7110         addr_t address;
7111         if (add)
7112             address = base + imm32;
7113         else
7114             address = base - imm32;
7115 
7116         // R[t] = SignExtend(MemU[address,1], 32);
7117         RegisterInfo base_reg;
7118         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7119 
7120         EmulateInstruction::Context context;
7121         context.type = eContextRegisterLoad;
7122         context.SetRegisterPlusOffset (base_reg, address - base);
7123 
7124         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7125         if (!success)
7126             return false;
7127 
7128         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7129         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7130             return false;
7131     }
7132     return true;
7133 }
7134 
7135 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from
7136 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7137 // shifted left by 0, 1, 2, or 3 bits.
7138 bool
7139 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding)
7140 {
7141 #if 0
7142     if ConditionPassed() then
7143         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7144         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7145         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7146         address = if index then offset_addr else R[n];
7147         R[t] = SignExtend(MemU[address,1], 32);
7148         if wback then R[n] = offset_addr;
7149 #endif
7150 
7151     bool success = false;
7152 
7153     if (ConditionPassed(opcode))
7154     {
7155         uint32_t t;
7156         uint32_t n;
7157         uint32_t m;
7158         bool index;
7159         bool add;
7160         bool wback;
7161         ARM_ShifterType shift_t;
7162         uint32_t shift_n;
7163 
7164         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7165         switch (encoding)
7166         {
7167             case eEncodingT1:
7168                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7169                 t = Bits32 (opcode, 2, 0);
7170                 n = Bits32 (opcode, 5, 3);
7171                 m = Bits32 (opcode, 8, 6);
7172 
7173                 // index = TRUE; add = TRUE; wback = FALSE;
7174                 index = true;
7175                 add = true;
7176                 wback = false;
7177 
7178                 // (shift_t, shift_n) = (SRType_LSL, 0);
7179                 shift_t = SRType_LSL;
7180                 shift_n = 0;
7181 
7182                 break;
7183 
7184             case eEncodingT2:
7185                 // if Rt == '1111' then SEE PLI;
7186                 // if Rn == '1111' then SEE LDRSB (literal);
7187                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7188                 t = Bits32 (opcode, 15, 12);
7189                 n = Bits32 (opcode, 19, 16);
7190                 m = Bits32 (opcode, 3, 0);
7191 
7192                 // index = TRUE; add = TRUE; wback = FALSE;
7193                 index = true;
7194                 add = true;
7195                 wback = false;
7196 
7197                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7198                 shift_t = SRType_LSL;
7199                 shift_n = Bits32 (opcode, 5, 4);
7200 
7201                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7202                 if ((t == 13) || BadReg (m))
7203                     return false;
7204                 break;
7205 
7206             case eEncodingA1:
7207                 // if P == '0' && W == '1' then SEE LDRSBT;
7208                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7209                 t = Bits32 (opcode, 15, 12);
7210                 n = Bits32 (opcode, 19, 16);
7211                 m = Bits32 (opcode, 3, 0);
7212 
7213                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7214                 index = BitIsSet (opcode, 24);
7215                 add = BitIsSet (opcode, 23);
7216                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7217 
7218                 // (shift_t, shift_n) = (SRType_LSL, 0);
7219                 shift_t = SRType_LSL;
7220                 shift_n = 0;
7221 
7222                 // if t == 15 || m == 15 then UNPREDICTABLE;
7223                 if ((t == 15) || (m == 15))
7224                     return false;
7225 
7226                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7227                 if (wback && ((n == 15) || (n == t)))
7228                     return false;
7229                 break;
7230 
7231             default:
7232                 return false;
7233         }
7234 
7235         uint64_t Rm =  ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7236         if (!success)
7237             return false;
7238 
7239         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7240         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7241         if (!success)
7242             return false;
7243 
7244         addr_t offset_addr;
7245         addr_t address;
7246 
7247         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7248         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7249         if (!success)
7250             return false;
7251 
7252         if (add)
7253             offset_addr = Rn + offset;
7254         else
7255             offset_addr = Rn - offset;
7256 
7257         // address = if index then offset_addr else R[n];
7258         if (index)
7259             address = offset_addr;
7260         else
7261             address = Rn;
7262 
7263         // R[t] = SignExtend(MemU[address,1], 32);
7264         RegisterInfo base_reg;
7265         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7266         RegisterInfo offset_reg;
7267         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7268 
7269         EmulateInstruction::Context context;
7270         context.type = eContextRegisterLoad;
7271         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7272 
7273         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7274         if (!success)
7275             return false;
7276 
7277         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7278         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7279             return false;
7280 
7281         // if wback then R[n] = offset_addr;
7282         if (wback)
7283         {
7284             context.type = eContextAdjustBaseRegister;
7285             context.SetAddress (offset_addr);
7286             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7287                 return false;
7288         }
7289     }
7290     return true;
7291 }
7292 
7293 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from
7294 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed, or
7295 // pre-indexed addressing.
7296 bool
7297 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding)
7298 {
7299 #if 0
7300     if ConditionPassed() then
7301         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7302         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7303         address = if index then offset_addr else R[n];
7304         data = MemU[address,2];
7305         if wback then R[n] = offset_addr;
7306         if UnalignedSupport() || address<0> = '0' then
7307             R[t] = SignExtend(data, 32);
7308         else // Can only apply before ARMv7
7309             R[t] = bits(32) UNKNOWN;
7310 #endif
7311 
7312     bool success = false;
7313 
7314     if (ConditionPassed(opcode))
7315     {
7316         uint32_t t;
7317         uint32_t n;
7318         uint32_t imm32;
7319         bool index;
7320         bool add;
7321         bool wback;
7322 
7323         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7324         switch (encoding)
7325         {
7326             case eEncodingT1:
7327                 // if Rn == '1111' then SEE LDRSH (literal);
7328                 // if Rt == '1111' then SEE "Unallocated memory hints";
7329                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7330                 t = Bits32 (opcode, 15, 12);
7331                 n = Bits32 (opcode, 19, 16);
7332                 imm32 = Bits32 (opcode, 11, 0);
7333 
7334                 // index = TRUE; add = TRUE; wback = FALSE;
7335                 index = true;
7336                 add = true;
7337                 wback = false;
7338 
7339                 // if t == 13 then UNPREDICTABLE;
7340                 if (t == 13)
7341                     return false;
7342 
7343                 break;
7344 
7345             case eEncodingT2:
7346                 // if Rn == '1111' then SEE LDRSH (literal);
7347                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
7348                 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7349                 // if P == '0' && W == '0' then UNDEFINED;
7350                   if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7351                   return false;
7352 
7353                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7354                 t = Bits32 (opcode, 15, 12);
7355                 n = Bits32 (opcode, 19, 16);
7356                 imm32 = Bits32 (opcode, 7, 0);
7357 
7358                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7359                 index = BitIsSet (opcode, 10);
7360                 add = BitIsSet (opcode, 9);
7361                 wback = BitIsSet (opcode, 8);
7362 
7363                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7364                 if (BadReg (t) || (wback && (n == t)))
7365                     return false;
7366 
7367                 break;
7368 
7369             case eEncodingA1:
7370             {
7371                 // if Rn == '1111' then SEE LDRSH (literal);
7372                 // if P == '0' && W == '1' then SEE LDRSHT;
7373                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7374                 t = Bits32 (opcode, 15, 12);
7375                 n = Bits32 (opcode, 19, 16);
7376                 uint32_t imm4H = Bits32 (opcode, 11,8);
7377                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7378                 imm32 = (imm4H << 4) | imm4L;
7379 
7380                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7381                 index = BitIsSet (opcode, 24);
7382                 add = BitIsSet (opcode, 23);
7383                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7384 
7385                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7386                 if ((t == 15) || (wback && (n == t)))
7387                     return false;
7388 
7389                 break;
7390             }
7391 
7392             default:
7393                 return false;
7394         }
7395 
7396         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7397         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7398         if (!success)
7399             return false;
7400 
7401         addr_t offset_addr;
7402         if (add)
7403             offset_addr = Rn + imm32;
7404         else
7405             offset_addr = Rn - imm32;
7406 
7407         // address = if index then offset_addr else R[n];
7408         addr_t address;
7409         if (index)
7410             address = offset_addr;
7411         else
7412             address = Rn;
7413 
7414         // data = MemU[address,2];
7415         RegisterInfo base_reg;
7416         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7417 
7418         EmulateInstruction::Context context;
7419         context.type = eContextRegisterLoad;
7420         context.SetRegisterPlusOffset (base_reg, address - Rn);
7421 
7422         uint64_t data = MemURead (context, address, 2, 0, &success);
7423         if (!success)
7424             return false;
7425 
7426         // if wback then R[n] = offset_addr;
7427         if (wback)
7428         {
7429             context.type = eContextAdjustBaseRegister;
7430             context.SetAddress (offset_addr);
7431             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7432                 return false;
7433         }
7434 
7435         // if UnalignedSupport() || address<0> = '0' then
7436         if (UnalignedSupport() || BitIsClear (address, 0))
7437         {
7438             // R[t] = SignExtend(data, 32);
7439             int64_t signed_data = llvm::SignExtend64<16>(data);
7440             context.type = eContextRegisterLoad;
7441             context.SetRegisterPlusOffset (base_reg, address - Rn);
7442             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7443                 return false;
7444         }
7445         else // Can only apply before ARMv7
7446         {
7447             // R[t] = bits(32) UNKNOWN;
7448             WriteBits32Unknown (t);
7449         }
7450     }
7451     return true;
7452 }
7453 
7454 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory,
7455 // sign-extends it to from a 32-bit word, and writes it to a register.
7456 bool
7457 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding)
7458 {
7459 #if 0
7460     if ConditionPassed() then
7461         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7462         base = Align(PC,4);
7463         address = if add then (base + imm32) else (base - imm32);
7464         data = MemU[address,2];
7465         if UnalignedSupport() || address<0> = '0' then
7466             R[t] = SignExtend(data, 32);
7467         else // Can only apply before ARMv7
7468             R[t] = bits(32) UNKNOWN;
7469 #endif
7470 
7471     bool success = false;
7472 
7473     if (ConditionPassed(opcode))
7474     {
7475         uint32_t t;
7476         uint32_t imm32;
7477         bool add;
7478 
7479         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7480         switch (encoding)
7481         {
7482             case eEncodingT1:
7483                 // if Rt == '1111' then SEE "Unallocated memory hints";
7484                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7485                 t = Bits32  (opcode, 15, 12);
7486                 imm32 = Bits32 (opcode, 11, 0);
7487                 add = BitIsSet (opcode, 23);
7488 
7489                 // if t == 13 then UNPREDICTABLE;
7490                 if (t == 13)
7491                     return false;
7492 
7493                 break;
7494 
7495             case eEncodingA1:
7496             {
7497                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7498                 t = Bits32 (opcode, 15, 12);
7499                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7500                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7501                 imm32 = (imm4H << 4) | imm4L;
7502                 add = BitIsSet (opcode, 23);
7503 
7504                 // if t == 15 then UNPREDICTABLE;
7505                 if (t == 15)
7506                     return false;
7507 
7508                 break;
7509             }
7510             default:
7511                 return false;
7512         }
7513 
7514         // base = Align(PC,4);
7515         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7516         if (!success)
7517             return false;
7518 
7519         uint64_t base = AlignPC (pc_value);
7520 
7521         addr_t address;
7522         // address = if add then (base + imm32) else (base - imm32);
7523         if (add)
7524             address = base + imm32;
7525         else
7526             address = base - imm32;
7527 
7528         // data = MemU[address,2];
7529         RegisterInfo base_reg;
7530         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7531 
7532         EmulateInstruction::Context context;
7533         context.type = eContextRegisterLoad;
7534         context.SetRegisterPlusOffset (base_reg, imm32);
7535 
7536         uint64_t data = MemURead (context, address, 2, 0, &success);
7537         if (!success)
7538             return false;
7539 
7540         // if UnalignedSupport() || address<0> = '0' then
7541         if (UnalignedSupport() || BitIsClear (address, 0))
7542         {
7543             // R[t] = SignExtend(data, 32);
7544             int64_t signed_data = llvm::SignExtend64<16>(data);
7545             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7546                 return false;
7547         }
7548         else // Can only apply before ARMv7
7549         {
7550             // R[t] = bits(32) UNKNOWN;
7551             WriteBits32Unknown (t);
7552         }
7553     }
7554     return true;
7555 }
7556 
7557 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword
7558 // from memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7559 // shifted left by 0, 1, 2, or 3 bits.
7560 bool
7561 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding)
7562 {
7563 #if 0
7564     if ConditionPassed() then
7565         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7566         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7567         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7568         address = if index then offset_addr else R[n];
7569         data = MemU[address,2];
7570         if wback then R[n] = offset_addr;
7571         if UnalignedSupport() || address<0> = '0' then
7572             R[t] = SignExtend(data, 32);
7573         else // Can only apply before ARMv7
7574             R[t] = bits(32) UNKNOWN;
7575 #endif
7576 
7577     bool success = false;
7578 
7579     if (ConditionPassed(opcode))
7580     {
7581         uint32_t t;
7582         uint32_t n;
7583         uint32_t m;
7584         bool index;
7585         bool add;
7586         bool wback;
7587         ARM_ShifterType shift_t;
7588         uint32_t shift_n;
7589 
7590         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7591         switch (encoding)
7592         {
7593             case eEncodingT1:
7594                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
7595                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7596                 t = Bits32 (opcode, 2, 0);
7597                 n = Bits32 (opcode, 5, 3);
7598                 m = Bits32 (opcode, 8, 6);
7599 
7600                 // index = TRUE; add = TRUE; wback = FALSE;
7601                 index = true;
7602                 add = true;
7603                 wback = false;
7604 
7605                 // (shift_t, shift_n) = (SRType_LSL, 0);
7606                 shift_t = SRType_LSL;
7607                 shift_n = 0;
7608 
7609                 break;
7610 
7611             case eEncodingT2:
7612                 // if Rn == '1111' then SEE LDRSH (literal);
7613                 // if Rt == '1111' then SEE "Unallocated memory hints";
7614                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7615                 t = Bits32 (opcode, 15, 12);
7616                 n = Bits32 (opcode, 19, 16);
7617                 m = Bits32 (opcode, 3, 0);
7618 
7619                 // index = TRUE; add = TRUE; wback = FALSE;
7620                 index = true;
7621                 add = true;
7622                 wback = false;
7623 
7624                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7625                 shift_t = SRType_LSL;
7626                 shift_n = Bits32 (opcode, 5, 4);
7627 
7628                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7629                 if ((t == 13) || BadReg (m))
7630                     return false;
7631 
7632                 break;
7633 
7634             case eEncodingA1:
7635                 // if P == '0' && W == '1' then SEE LDRSHT;
7636                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7637                 t = Bits32 (opcode, 15, 12);
7638                 n = Bits32 (opcode, 19, 16);
7639                 m = Bits32 (opcode, 3, 0);
7640 
7641                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7642                 index = BitIsSet (opcode, 24);
7643                 add = BitIsSet (opcode, 23);
7644                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7645 
7646                 // (shift_t, shift_n) = (SRType_LSL, 0);
7647                 shift_t = SRType_LSL;
7648                 shift_n = 0;
7649 
7650                 // if t == 15 || m == 15 then UNPREDICTABLE;
7651                 if ((t == 15) || (m == 15))
7652                     return false;
7653 
7654                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7655                 if (wback && ((n == 15) || (n == t)))
7656                     return false;
7657 
7658                 break;
7659 
7660             default:
7661                 return false;
7662         }
7663 
7664         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7665         if (!success)
7666             return false;
7667 
7668         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7669         if (!success)
7670             return false;
7671 
7672         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7673         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7674         if (!success)
7675             return false;
7676 
7677         addr_t offset_addr;
7678         addr_t address;
7679 
7680         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7681         if (add)
7682             offset_addr = Rn + offset;
7683         else
7684             offset_addr = Rn - offset;
7685 
7686         // address = if index then offset_addr else R[n];
7687         if (index)
7688             address = offset_addr;
7689         else
7690             address = Rn;
7691 
7692         // data = MemU[address,2];
7693         RegisterInfo base_reg;
7694         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7695 
7696         RegisterInfo offset_reg;
7697         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7698 
7699         EmulateInstruction::Context context;
7700         context.type = eContextRegisterLoad;
7701         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7702 
7703         uint64_t data = MemURead (context, address, 2, 0, &success);
7704         if (!success)
7705             return false;
7706 
7707         // if wback then R[n] = offset_addr;
7708         if (wback)
7709         {
7710             context.type = eContextAdjustBaseRegister;
7711             context.SetAddress (offset_addr);
7712             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7713                 return false;
7714         }
7715 
7716         // if UnalignedSupport() || address<0> = '0' then
7717         if (UnalignedSupport() || BitIsClear (address, 0))
7718         {
7719             // R[t] = SignExtend(data, 32);
7720             context.type = eContextRegisterLoad;
7721             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7722 
7723             int64_t signed_data = llvm::SignExtend64<16>(data);
7724             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7725                 return false;
7726         }
7727         else // Can only apply before ARMv7
7728         {
7729             // R[t] = bits(32) UNKNOWN;
7730             WriteBits32Unknown (t);
7731         }
7732     }
7733     return true;
7734 }
7735 
7736 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7737 // register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7738 bool
7739 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding)
7740 {
7741 #if 0
7742     if ConditionPassed() then
7743         EncodingSpecificOperations();
7744         rotated = ROR(R[m], rotation);
7745         R[d] = SignExtend(rotated<7:0>, 32);
7746 #endif
7747 
7748     bool success = false;
7749 
7750     if (ConditionPassed(opcode))
7751     {
7752         uint32_t d;
7753         uint32_t m;
7754         uint32_t rotation;
7755 
7756         // EncodingSpecificOperations();
7757         switch (encoding)
7758         {
7759             case eEncodingT1:
7760                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7761                 d = Bits32 (opcode, 2, 0);
7762                 m = Bits32 (opcode, 5, 3);
7763                 rotation = 0;
7764 
7765                 break;
7766 
7767             case eEncodingT2:
7768                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7769                 d = Bits32 (opcode, 11, 8);
7770                 m = Bits32 (opcode, 3, 0);
7771                 rotation = Bits32 (opcode, 5, 4) << 3;
7772 
7773                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7774                 if (BadReg (d) || BadReg (m))
7775                     return false;
7776 
7777                 break;
7778 
7779             case eEncodingA1:
7780                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7781                 d = Bits32 (opcode, 15, 12);
7782                 m = Bits32 (opcode, 3, 0);
7783                 rotation = Bits32 (opcode, 11, 10) << 3;
7784 
7785                 // if d == 15 || m == 15 then UNPREDICTABLE;
7786                 if ((d == 15) || (m == 15))
7787                     return false;
7788 
7789                 break;
7790 
7791             default:
7792                 return false;
7793         }
7794 
7795         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7796         if (!success)
7797             return false;
7798 
7799         // rotated = ROR(R[m], rotation);
7800         uint64_t rotated = ROR (Rm, rotation, &success);
7801         if (!success)
7802             return false;
7803 
7804         // R[d] = SignExtend(rotated<7:0>, 32);
7805         int64_t data = llvm::SignExtend64<8>(rotated);
7806 
7807         RegisterInfo source_reg;
7808         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7809 
7810         EmulateInstruction::Context context;
7811         context.type = eContextRegisterLoad;
7812         context.SetRegister (source_reg);
7813 
7814         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7815             return false;
7816     }
7817     return true;
7818 }
7819 
7820 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7821 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7822 bool
7823 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding)
7824 {
7825 #if 0
7826     if ConditionPassed() then
7827         EncodingSpecificOperations();
7828         rotated = ROR(R[m], rotation);
7829         R[d] = SignExtend(rotated<15:0>, 32);
7830 #endif
7831 
7832     bool success = false;
7833 
7834     if (ConditionPassed(opcode))
7835     {
7836         uint32_t d;
7837         uint32_t m;
7838         uint32_t rotation;
7839 
7840         // EncodingSpecificOperations();
7841         switch (encoding)
7842         {
7843             case eEncodingT1:
7844                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7845                 d = Bits32 (opcode, 2, 0);
7846                 m = Bits32 (opcode, 5, 3);
7847                 rotation = 0;
7848 
7849                 break;
7850 
7851             case eEncodingT2:
7852                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7853                 d = Bits32 (opcode, 11, 8);
7854                 m = Bits32 (opcode, 3, 0);
7855                 rotation = Bits32 (opcode, 5, 4) << 3;
7856 
7857                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7858                 if (BadReg (d) || BadReg (m))
7859                     return false;
7860 
7861                 break;
7862 
7863             case eEncodingA1:
7864                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7865                 d = Bits32 (opcode, 15, 12);
7866                 m = Bits32 (opcode, 3, 0);
7867                 rotation = Bits32 (opcode, 11, 10) << 3;
7868 
7869                 // if d == 15 || m == 15 then UNPREDICTABLE;
7870                 if ((d == 15) || (m == 15))
7871                     return false;
7872 
7873                 break;
7874 
7875             default:
7876                 return false;
7877         }
7878 
7879         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7880         if (!success)
7881             return false;
7882 
7883         // rotated = ROR(R[m], rotation);
7884         uint64_t rotated = ROR (Rm, rotation, &success);
7885         if (!success)
7886             return false;
7887 
7888         // R[d] = SignExtend(rotated<15:0>, 32);
7889         RegisterInfo source_reg;
7890         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7891 
7892         EmulateInstruction::Context context;
7893         context.type = eContextRegisterLoad;
7894         context.SetRegister (source_reg);
7895 
7896         int64_t data = llvm::SignExtend64<16> (rotated);
7897         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7898             return false;
7899     }
7900 
7901     return true;
7902 }
7903 
7904 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination
7905 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7906 bool
7907 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding)
7908 {
7909 #if 0
7910     if ConditionPassed() then
7911         EncodingSpecificOperations();
7912         rotated = ROR(R[m], rotation);
7913         R[d] = ZeroExtend(rotated<7:0>, 32);
7914 #endif
7915 
7916     bool success = false;
7917 
7918     if (ConditionPassed(opcode))
7919     {
7920         uint32_t d;
7921         uint32_t m;
7922         uint32_t rotation;
7923 
7924         // EncodingSpecificOperations();
7925         switch (encoding)
7926         {
7927             case eEncodingT1:
7928                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7929                 d = Bits32 (opcode, 2, 0);
7930                 m = Bits32 (opcode, 5, 3);
7931                 rotation = 0;
7932 
7933                 break;
7934 
7935             case eEncodingT2:
7936                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7937                 d = Bits32 (opcode, 11, 8);
7938                 m = Bits32 (opcode, 3, 0);
7939                   rotation = Bits32 (opcode, 5, 4) << 3;
7940 
7941                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7942                 if (BadReg (d) || BadReg (m))
7943                   return false;
7944 
7945                 break;
7946 
7947             case eEncodingA1:
7948                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7949                 d = Bits32 (opcode, 15, 12);
7950                 m = Bits32 (opcode, 3, 0);
7951                 rotation = Bits32 (opcode, 11, 10) << 3;
7952 
7953                 // if d == 15 || m == 15 then UNPREDICTABLE;
7954                 if ((d == 15) || (m == 15))
7955                     return false;
7956 
7957                 break;
7958 
7959             default:
7960                 return false;
7961         }
7962 
7963         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7964         if (!success)
7965             return false;
7966 
7967         // rotated = ROR(R[m], rotation);
7968         uint64_t rotated = ROR (Rm, rotation, &success);
7969         if (!success)
7970             return false;
7971 
7972         // R[d] = ZeroExtend(rotated<7:0>, 32);
7973         RegisterInfo source_reg;
7974         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7975 
7976         EmulateInstruction::Context context;
7977         context.type = eContextRegisterLoad;
7978         context.SetRegister (source_reg);
7979 
7980         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0)))
7981             return false;
7982     }
7983     return true;
7984 }
7985 
7986 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination
7987 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7988 bool
7989 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding)
7990 {
7991 #if 0
7992     if ConditionPassed() then
7993         EncodingSpecificOperations();
7994         rotated = ROR(R[m], rotation);
7995         R[d] = ZeroExtend(rotated<15:0>, 32);
7996 #endif
7997 
7998     bool success = false;
7999 
8000     if (ConditionPassed(opcode))
8001     {
8002         uint32_t d;
8003         uint32_t m;
8004         uint32_t rotation;
8005 
8006         switch (encoding)
8007         {
8008             case eEncodingT1:
8009                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8010                 d = Bits32 (opcode, 2, 0);
8011                 m = Bits32 (opcode, 5, 3);
8012                 rotation = 0;
8013 
8014                 break;
8015 
8016             case eEncodingT2:
8017                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8018                 d = Bits32 (opcode, 11, 8);
8019                 m = Bits32 (opcode, 3, 0);
8020                 rotation = Bits32 (opcode, 5, 4) << 3;
8021 
8022                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8023                 if (BadReg (d) || BadReg (m))
8024                   return false;
8025 
8026                 break;
8027 
8028             case eEncodingA1:
8029                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8030                 d = Bits32 (opcode, 15, 12);
8031                 m = Bits32 (opcode, 3, 0);
8032                 rotation = Bits32 (opcode, 11, 10) << 3;
8033 
8034                 // if d == 15 || m == 15 then UNPREDICTABLE;
8035                 if ((d == 15) || (m == 15))
8036                     return false;
8037 
8038                 break;
8039 
8040             default:
8041                 return false;
8042         }
8043 
8044         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8045         if (!success)
8046             return false;
8047 
8048         // rotated = ROR(R[m], rotation);
8049         uint64_t rotated = ROR (Rm, rotation, &success);
8050         if (!success)
8051             return false;
8052 
8053         // R[d] = ZeroExtend(rotated<15:0>, 32);
8054         RegisterInfo source_reg;
8055         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8056 
8057         EmulateInstruction::Context context;
8058         context.type = eContextRegisterLoad;
8059         context.SetRegister (source_reg);
8060 
8061         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0)))
8062             return false;
8063     }
8064     return true;
8065 }
8066 
8067 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following
8068 // word respectively.
8069 bool
8070 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding)
8071 {
8072 #if 0
8073     if ConditionPassed() then
8074         EncodingSpecificOperations();
8075         if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8076             UNPREDICTABLE;
8077         else
8078             address = if increment then R[n] else R[n]-8;
8079             if wordhigher then address = address+4;
8080             CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8081             BranchWritePC(MemA[address,4]);
8082             if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8083 #endif
8084 
8085     bool success = false;
8086 
8087     if (ConditionPassed(opcode))
8088     {
8089         uint32_t n;
8090         bool wback;
8091         bool increment;
8092         bool wordhigher;
8093 
8094         // EncodingSpecificOperations();
8095         switch (encoding)
8096         {
8097             case eEncodingT1:
8098                 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE;
8099                 n = Bits32 (opcode, 19, 16);
8100                 wback = BitIsSet (opcode, 21);
8101                 increment = false;
8102                 wordhigher = false;
8103 
8104                 // if n == 15 then UNPREDICTABLE;
8105                 if (n == 15)
8106                     return false;
8107 
8108                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8109                 if (InITBlock() && !LastInITBlock())
8110                     return false;
8111 
8112                 break;
8113 
8114             case eEncodingT2:
8115                 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8116                 n = Bits32 (opcode, 19, 16);
8117                 wback = BitIsSet (opcode, 21);
8118                 increment = true;
8119                 wordhigher = false;
8120 
8121                 // if n == 15 then UNPREDICTABLE;
8122                 if (n == 15)
8123                     return false;
8124 
8125                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8126                 if (InITBlock() && !LastInITBlock())
8127                     return false;
8128 
8129                 break;
8130 
8131             case eEncodingA1:
8132                 // n = UInt(Rn);
8133                 n = Bits32 (opcode, 19, 16);
8134 
8135                 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8136                 wback = BitIsSet (opcode, 21);
8137                 increment = BitIsSet (opcode, 23);
8138                 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23));
8139 
8140                 // if n == 15 then UNPREDICTABLE;
8141                 if (n == 15)
8142                     return false;
8143 
8144                 break;
8145 
8146             default:
8147                 return false;
8148         }
8149 
8150         // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8151         if (!CurrentModeIsPrivileged ())
8152             // UNPREDICTABLE;
8153             return false;
8154         else
8155         {
8156             uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8157             if (!success)
8158                 return false;
8159 
8160             addr_t address;
8161             // address = if increment then R[n] else R[n]-8;
8162             if (increment)
8163                 address = Rn;
8164             else
8165                 address = Rn - 8;
8166 
8167             // if wordhigher then address = address+4;
8168             if (wordhigher)
8169                 address = address + 4;
8170 
8171             // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8172             RegisterInfo base_reg;
8173             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8174 
8175             EmulateInstruction::Context context;
8176             context.type = eContextReturnFromException;
8177             context.SetRegisterPlusOffset (base_reg, address - Rn);
8178 
8179             uint64_t data = MemARead (context, address + 4, 4, 0, &success);
8180             if (!success)
8181                 return false;
8182 
8183             CPSRWriteByInstr (data, 15, true);
8184 
8185             // BranchWritePC(MemA[address,4]);
8186             uint64_t data2 = MemARead (context, address, 4, 0, &success);
8187             if (!success)
8188                 return false;
8189 
8190             BranchWritePC (context, data2);
8191 
8192             // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8193             if (wback)
8194             {
8195                 context.type = eContextAdjustBaseRegister;
8196                 if (increment)
8197                 {
8198                     context.SetOffset (8);
8199                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8))
8200                         return false;
8201                 }
8202                 else
8203                 {
8204                     context.SetOffset (-8);
8205                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8))
8206                         return false;
8207                 }
8208             } // if wback
8209         }
8210     } // if ConditionPassed()
8211     return true;
8212 }
8213 
8214 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
8215 // and writes the result to the destination register.  It can optionally update the condition flags based on
8216 // the result.
8217 bool
8218 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding)
8219 {
8220 #if 0
8221     // ARM pseudo code...
8222     if ConditionPassed() then
8223         EncodingSpecificOperations();
8224         result = R[n] EOR imm32;
8225         if d == 15 then         // Can only occur for ARM encoding
8226             ALUWritePC(result); // setflags is always FALSE here
8227         else
8228             R[d] = result;
8229             if setflags then
8230                 APSR.N = result<31>;
8231                 APSR.Z = IsZeroBit(result);
8232                 APSR.C = carry;
8233                 // APSR.V unchanged
8234 #endif
8235 
8236     bool success = false;
8237 
8238     if (ConditionPassed(opcode))
8239     {
8240         uint32_t Rd, Rn;
8241         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8242         bool setflags;
8243         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8244         switch (encoding)
8245         {
8246         case eEncodingT1:
8247             Rd = Bits32(opcode, 11, 8);
8248             Rn = Bits32(opcode, 19, 16);
8249             setflags = BitIsSet(opcode, 20);
8250             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8251             // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8252             if (Rd == 15 && setflags)
8253                 return EmulateTEQImm (opcode, eEncodingT1);
8254             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8255                 return false;
8256             break;
8257         case eEncodingA1:
8258             Rd = Bits32(opcode, 15, 12);
8259             Rn = Bits32(opcode, 19, 16);
8260             setflags = BitIsSet(opcode, 20);
8261             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8262 
8263             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8264             if (Rd == 15 && setflags)
8265                 return EmulateSUBSPcLrEtc (opcode, encoding);
8266             break;
8267         default:
8268             return false;
8269         }
8270 
8271         // Read the first operand.
8272         uint32_t val1 = ReadCoreReg(Rn, &success);
8273         if (!success)
8274             return false;
8275 
8276         uint32_t result = val1 ^ imm32;
8277 
8278         EmulateInstruction::Context context;
8279         context.type = EmulateInstruction::eContextImmediate;
8280         context.SetNoArgs ();
8281 
8282         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8283             return false;
8284     }
8285     return true;
8286 }
8287 
8288 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an
8289 // optionally-shifted register value, and writes the result to the destination register.
8290 // It can optionally update the condition flags based on the result.
8291 bool
8292 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding)
8293 {
8294 #if 0
8295     // ARM pseudo code...
8296     if ConditionPassed() then
8297         EncodingSpecificOperations();
8298         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8299         result = R[n] EOR shifted;
8300         if d == 15 then         // Can only occur for ARM encoding
8301             ALUWritePC(result); // setflags is always FALSE here
8302         else
8303             R[d] = result;
8304             if setflags then
8305                 APSR.N = result<31>;
8306                 APSR.Z = IsZeroBit(result);
8307                 APSR.C = carry;
8308                 // APSR.V unchanged
8309 #endif
8310 
8311     bool success = false;
8312 
8313     if (ConditionPassed(opcode))
8314     {
8315         uint32_t Rd, Rn, Rm;
8316         ARM_ShifterType shift_t;
8317         uint32_t shift_n; // the shift applied to the value read from Rm
8318         bool setflags;
8319         uint32_t carry;
8320         switch (encoding)
8321         {
8322         case eEncodingT1:
8323             Rd = Rn = Bits32(opcode, 2, 0);
8324             Rm = Bits32(opcode, 5, 3);
8325             setflags = !InITBlock();
8326             shift_t = SRType_LSL;
8327             shift_n = 0;
8328             break;
8329         case eEncodingT2:
8330             Rd = Bits32(opcode, 11, 8);
8331             Rn = Bits32(opcode, 19, 16);
8332             Rm = Bits32(opcode, 3, 0);
8333             setflags = BitIsSet(opcode, 20);
8334             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8335             // if Rd == '1111' && S == '1' then SEE TEQ (register);
8336             if (Rd == 15 && setflags)
8337                 return EmulateTEQReg (opcode, eEncodingT1);
8338             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8339                 return false;
8340             break;
8341         case eEncodingA1:
8342             Rd = Bits32(opcode, 15, 12);
8343             Rn = Bits32(opcode, 19, 16);
8344             Rm = Bits32(opcode, 3, 0);
8345             setflags = BitIsSet(opcode, 20);
8346             shift_n = DecodeImmShiftARM(opcode, shift_t);
8347 
8348             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8349             if (Rd == 15 && setflags)
8350                 return EmulateSUBSPcLrEtc (opcode, encoding);
8351             break;
8352         default:
8353             return false;
8354         }
8355 
8356         // Read the first operand.
8357         uint32_t val1 = ReadCoreReg(Rn, &success);
8358         if (!success)
8359             return false;
8360 
8361         // Read the second operand.
8362         uint32_t val2 = ReadCoreReg(Rm, &success);
8363         if (!success)
8364             return false;
8365 
8366         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8367         if (!success)
8368             return false;
8369         uint32_t result = val1 ^ shifted;
8370 
8371         EmulateInstruction::Context context;
8372         context.type = EmulateInstruction::eContextImmediate;
8373         context.SetNoArgs ();
8374 
8375         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8376             return false;
8377     }
8378     return true;
8379 }
8380 
8381 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and
8382 // writes the result to the destination register.  It can optionally update the condition flags based
8383 // on the result.
8384 bool
8385 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding)
8386 {
8387 #if 0
8388     // ARM pseudo code...
8389     if ConditionPassed() then
8390         EncodingSpecificOperations();
8391         result = R[n] OR imm32;
8392         if d == 15 then         // Can only occur for ARM encoding
8393             ALUWritePC(result); // setflags is always FALSE here
8394         else
8395             R[d] = result;
8396             if setflags then
8397                 APSR.N = result<31>;
8398                 APSR.Z = IsZeroBit(result);
8399                 APSR.C = carry;
8400                 // APSR.V unchanged
8401 #endif
8402 
8403     bool success = false;
8404 
8405     if (ConditionPassed(opcode))
8406     {
8407         uint32_t Rd, Rn;
8408         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8409         bool setflags;
8410         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8411         switch (encoding)
8412         {
8413         case eEncodingT1:
8414             Rd = Bits32(opcode, 11, 8);
8415             Rn = Bits32(opcode, 19, 16);
8416             setflags = BitIsSet(opcode, 20);
8417             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8418             // if Rn == '1111' then SEE MOV (immediate);
8419             if (Rn == 15)
8420                 return EmulateMOVRdImm (opcode, eEncodingT2);
8421             if (BadReg(Rd) || Rn == 13)
8422                 return false;
8423             break;
8424         case eEncodingA1:
8425             Rd = Bits32(opcode, 15, 12);
8426             Rn = Bits32(opcode, 19, 16);
8427             setflags = BitIsSet(opcode, 20);
8428             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8429 
8430             if (Rd == 15 && setflags)
8431                 return EmulateSUBSPcLrEtc (opcode, encoding);
8432             break;
8433         default:
8434             return false;
8435         }
8436 
8437         // Read the first operand.
8438         uint32_t val1 = ReadCoreReg(Rn, &success);
8439         if (!success)
8440             return false;
8441 
8442         uint32_t result = val1 | imm32;
8443 
8444         EmulateInstruction::Context context;
8445         context.type = EmulateInstruction::eContextImmediate;
8446         context.SetNoArgs ();
8447 
8448         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8449             return false;
8450     }
8451     return true;
8452 }
8453 
8454 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register
8455 // value, and writes the result to the destination register.  It can optionally update the condition flags based
8456 // on the result.
8457 bool
8458 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding)
8459 {
8460 #if 0
8461     // ARM pseudo code...
8462     if ConditionPassed() then
8463         EncodingSpecificOperations();
8464         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8465         result = R[n] OR shifted;
8466         if d == 15 then         // Can only occur for ARM encoding
8467             ALUWritePC(result); // setflags is always FALSE here
8468         else
8469             R[d] = result;
8470             if setflags then
8471                 APSR.N = result<31>;
8472                 APSR.Z = IsZeroBit(result);
8473                 APSR.C = carry;
8474                 // APSR.V unchanged
8475 #endif
8476 
8477     bool success = false;
8478 
8479     if (ConditionPassed(opcode))
8480     {
8481         uint32_t Rd, Rn, Rm;
8482         ARM_ShifterType shift_t;
8483         uint32_t shift_n; // the shift applied to the value read from Rm
8484         bool setflags;
8485         uint32_t carry;
8486         switch (encoding)
8487         {
8488         case eEncodingT1:
8489             Rd = Rn = Bits32(opcode, 2, 0);
8490             Rm = Bits32(opcode, 5, 3);
8491             setflags = !InITBlock();
8492             shift_t = SRType_LSL;
8493             shift_n = 0;
8494             break;
8495         case eEncodingT2:
8496             Rd = Bits32(opcode, 11, 8);
8497             Rn = Bits32(opcode, 19, 16);
8498             Rm = Bits32(opcode, 3, 0);
8499             setflags = BitIsSet(opcode, 20);
8500             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8501             // if Rn == '1111' then SEE MOV (register);
8502             if (Rn == 15)
8503                 return EmulateMOVRdRm (opcode, eEncodingT3);
8504             if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
8505                 return false;
8506             break;
8507         case eEncodingA1:
8508             Rd = Bits32(opcode, 15, 12);
8509             Rn = Bits32(opcode, 19, 16);
8510             Rm = Bits32(opcode, 3, 0);
8511             setflags = BitIsSet(opcode, 20);
8512             shift_n = DecodeImmShiftARM(opcode, shift_t);
8513 
8514             if (Rd == 15 && setflags)
8515                 return EmulateSUBSPcLrEtc (opcode, encoding);
8516             break;
8517         default:
8518             return false;
8519         }
8520 
8521         // Read the first operand.
8522         uint32_t val1 = ReadCoreReg(Rn, &success);
8523         if (!success)
8524             return false;
8525 
8526         // Read the second operand.
8527         uint32_t val2 = ReadCoreReg(Rm, &success);
8528         if (!success)
8529             return false;
8530 
8531         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8532         if (!success)
8533             return false;
8534         uint32_t result = val1 | shifted;
8535 
8536         EmulateInstruction::Context context;
8537         context.type = EmulateInstruction::eContextImmediate;
8538         context.SetNoArgs ();
8539 
8540         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8541             return false;
8542     }
8543     return true;
8544 }
8545 
8546 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to
8547 // the destination register. It can optionally update the condition flags based on the result.
8548 bool
8549 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding)
8550 {
8551 #if 0
8552     // ARM pseudo code...
8553     if ConditionPassed() then
8554         EncodingSpecificOperations();
8555         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
8556         if d == 15 then         // Can only occur for ARM encoding
8557             ALUWritePC(result); // setflags is always FALSE here
8558         else
8559             R[d] = result;
8560             if setflags then
8561                 APSR.N = result<31>;
8562                 APSR.Z = IsZeroBit(result);
8563                 APSR.C = carry;
8564                 APSR.V = overflow;
8565 #endif
8566 
8567     bool success = false;
8568 
8569     uint32_t Rd; // the destination register
8570     uint32_t Rn; // the first operand
8571     bool setflags;
8572     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8573     switch (encoding) {
8574     case eEncodingT1:
8575         Rd = Bits32(opcode, 2, 0);
8576         Rn = Bits32(opcode, 5, 3);
8577         setflags = !InITBlock();
8578         imm32 = 0;
8579         break;
8580     case eEncodingT2:
8581         Rd = Bits32(opcode, 11, 8);
8582         Rn = Bits32(opcode, 19, 16);
8583         setflags = BitIsSet(opcode, 20);
8584         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8585         if (BadReg(Rd) || BadReg(Rn))
8586             return false;
8587         break;
8588     case eEncodingA1:
8589         Rd = Bits32(opcode, 15, 12);
8590         Rn = Bits32(opcode, 19, 16);
8591         setflags = BitIsSet(opcode, 20);
8592         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8593 
8594         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8595         if (Rd == 15 && setflags)
8596             return EmulateSUBSPcLrEtc (opcode, encoding);
8597         break;
8598     default:
8599         return false;
8600     }
8601     // Read the register value from the operand register Rn.
8602     uint32_t reg_val = ReadCoreReg(Rn, &success);
8603     if (!success)
8604         return false;
8605 
8606     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
8607 
8608     EmulateInstruction::Context context;
8609     context.type = EmulateInstruction::eContextImmediate;
8610     context.SetNoArgs ();
8611 
8612     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8613         return false;
8614 
8615     return true;
8616 }
8617 
8618 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the
8619 // result to the destination register. It can optionally update the condition flags based on the result.
8620 bool
8621 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding)
8622 {
8623 #if 0
8624     // ARM pseudo code...
8625     if ConditionPassed() then
8626         EncodingSpecificOperations();
8627         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8628         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
8629         if d == 15 then         // Can only occur for ARM encoding
8630             ALUWritePC(result); // setflags is always FALSE here
8631         else
8632             R[d] = result;
8633             if setflags then
8634                 APSR.N = result<31>;
8635                 APSR.Z = IsZeroBit(result);
8636                 APSR.C = carry;
8637                 APSR.V = overflow;
8638 #endif
8639 
8640     bool success = false;
8641 
8642     uint32_t Rd; // the destination register
8643     uint32_t Rn; // the first operand
8644     uint32_t Rm; // the second operand
8645     bool setflags;
8646     ARM_ShifterType shift_t;
8647     uint32_t shift_n; // the shift applied to the value read from Rm
8648     switch (encoding) {
8649     case eEncodingT1:
8650         Rd = Bits32(opcode, 11, 8);
8651         Rn = Bits32(opcode, 19, 16);
8652         Rm = Bits32(opcode, 3, 0);
8653         setflags = BitIsSet(opcode, 20);
8654         shift_n = DecodeImmShiftThumb(opcode, shift_t);
8655         // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
8656         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8657             return false;
8658         break;
8659     case eEncodingA1:
8660         Rd = Bits32(opcode, 15, 12);
8661         Rn = Bits32(opcode, 19, 16);
8662         Rm = Bits32(opcode, 3, 0);
8663         setflags = BitIsSet(opcode, 20);
8664         shift_n = DecodeImmShiftARM(opcode, shift_t);
8665 
8666         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8667         if (Rd == 15 && setflags)
8668             return EmulateSUBSPcLrEtc (opcode, encoding);
8669         break;
8670     default:
8671         return false;
8672     }
8673     // Read the register value from register Rn.
8674     uint32_t val1 = ReadCoreReg(Rn, &success);
8675     if (!success)
8676         return false;
8677 
8678     // Read the register value from register Rm.
8679     uint32_t val2 = ReadCoreReg(Rm, &success);
8680     if (!success)
8681         return false;
8682 
8683     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8684     if (!success)
8685         return false;
8686     AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
8687 
8688     EmulateInstruction::Context context;
8689     context.type = EmulateInstruction::eContextImmediate;
8690     context.SetNoArgs();
8691     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8692         return false;
8693 
8694     return true;
8695 }
8696 
8697 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from
8698 // an immediate value, and writes the result to the destination register. It can optionally update the condition
8699 // flags based on the result.
8700 bool
8701 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding)
8702 {
8703 #if 0
8704     // ARM pseudo code...
8705     if ConditionPassed() then
8706         EncodingSpecificOperations();
8707         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
8708         if d == 15 then
8709             ALUWritePC(result); // setflags is always FALSE here
8710         else
8711             R[d] = result;
8712             if setflags then
8713                 APSR.N = result<31>;
8714                 APSR.Z = IsZeroBit(result);
8715                 APSR.C = carry;
8716                 APSR.V = overflow;
8717 #endif
8718 
8719     bool success = false;
8720 
8721     uint32_t Rd; // the destination register
8722     uint32_t Rn; // the first operand
8723     bool setflags;
8724     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8725     switch (encoding) {
8726     case eEncodingA1:
8727         Rd = Bits32(opcode, 15, 12);
8728         Rn = Bits32(opcode, 19, 16);
8729         setflags = BitIsSet(opcode, 20);
8730         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8731 
8732         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8733         if (Rd == 15 && setflags)
8734             return EmulateSUBSPcLrEtc  (opcode, encoding);
8735         break;
8736     default:
8737         return false;
8738     }
8739     // Read the register value from the operand register Rn.
8740     uint32_t reg_val = ReadCoreReg(Rn, &success);
8741     if (!success)
8742         return false;
8743 
8744     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
8745 
8746     EmulateInstruction::Context context;
8747     context.type = EmulateInstruction::eContextImmediate;
8748     context.SetNoArgs ();
8749 
8750     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8751         return false;
8752 
8753     return true;
8754 }
8755 
8756 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an
8757 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the
8758 // condition flags based on the result.
8759 bool
8760 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding)
8761 {
8762 #if 0
8763     // ARM pseudo code...
8764     if ConditionPassed() then
8765         EncodingSpecificOperations();
8766         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8767         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
8768         if d == 15 then
8769             ALUWritePC(result); // setflags is always FALSE here
8770         else
8771             R[d] = result;
8772             if setflags then
8773                 APSR.N = result<31>;
8774                 APSR.Z = IsZeroBit(result);
8775                 APSR.C = carry;
8776                 APSR.V = overflow;
8777 #endif
8778 
8779     bool success = false;
8780 
8781     uint32_t Rd; // the destination register
8782     uint32_t Rn; // the first operand
8783     uint32_t Rm; // the second operand
8784     bool setflags;
8785     ARM_ShifterType shift_t;
8786     uint32_t shift_n; // the shift applied to the value read from Rm
8787     switch (encoding) {
8788     case eEncodingA1:
8789         Rd = Bits32(opcode, 15, 12);
8790         Rn = Bits32(opcode, 19, 16);
8791         Rm = Bits32(opcode, 3, 0);
8792         setflags = BitIsSet(opcode, 20);
8793         shift_n = DecodeImmShiftARM(opcode, shift_t);
8794 
8795         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8796         if (Rd == 15 && setflags)
8797             return EmulateSUBSPcLrEtc (opcode, encoding);
8798         break;
8799     default:
8800         return false;
8801     }
8802     // Read the register value from register Rn.
8803     uint32_t val1 = ReadCoreReg(Rn, &success);
8804     if (!success)
8805         return false;
8806 
8807     // Read the register value from register Rm.
8808     uint32_t val2 = ReadCoreReg(Rm, &success);
8809     if (!success)
8810         return false;
8811 
8812     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8813     if (!success)
8814         return false;
8815     AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
8816 
8817     EmulateInstruction::Context context;
8818     context.type = EmulateInstruction::eContextImmediate;
8819     context.SetNoArgs();
8820     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8821         return false;
8822 
8823     return true;
8824 }
8825 
8826 // Subtract with Carry (immediate) subtracts an immediate value and the value of
8827 // NOT (Carry flag) from a register value, and writes the result to the destination register.
8828 // It can optionally update the condition flags based on the result.
8829 bool
8830 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding)
8831 {
8832 #if 0
8833     // ARM pseudo code...
8834     if ConditionPassed() then
8835         EncodingSpecificOperations();
8836         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
8837         if d == 15 then         // Can only occur for ARM encoding
8838             ALUWritePC(result); // setflags is always FALSE here
8839         else
8840             R[d] = result;
8841             if setflags then
8842                 APSR.N = result<31>;
8843                 APSR.Z = IsZeroBit(result);
8844                 APSR.C = carry;
8845                 APSR.V = overflow;
8846 #endif
8847 
8848     bool success = false;
8849 
8850     uint32_t Rd; // the destination register
8851     uint32_t Rn; // the first operand
8852     bool setflags;
8853     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8854     switch (encoding) {
8855     case eEncodingT1:
8856         Rd = Bits32(opcode, 11, 8);
8857         Rn = Bits32(opcode, 19, 16);
8858         setflags = BitIsSet(opcode, 20);
8859         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8860         if (BadReg(Rd) || BadReg(Rn))
8861             return false;
8862         break;
8863     case eEncodingA1:
8864         Rd = Bits32(opcode, 15, 12);
8865         Rn = Bits32(opcode, 19, 16);
8866         setflags = BitIsSet(opcode, 20);
8867         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8868 
8869         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8870         if (Rd == 15 && setflags)
8871             return EmulateSUBSPcLrEtc (opcode, encoding);
8872         break;
8873     default:
8874         return false;
8875     }
8876     // Read the register value from the operand register Rn.
8877     uint32_t reg_val = ReadCoreReg(Rn, &success);
8878     if (!success)
8879         return false;
8880 
8881     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
8882 
8883     EmulateInstruction::Context context;
8884     context.type = EmulateInstruction::eContextImmediate;
8885     context.SetNoArgs ();
8886 
8887     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8888         return false;
8889 
8890     return true;
8891 }
8892 
8893 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of
8894 // NOT (Carry flag) from a register value, and writes the result to the destination register.
8895 // It can optionally update the condition flags based on the result.
8896 bool
8897 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding)
8898 {
8899 #if 0
8900     // ARM pseudo code...
8901     if ConditionPassed() then
8902         EncodingSpecificOperations();
8903         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8904         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
8905         if d == 15 then         // Can only occur for ARM encoding
8906             ALUWritePC(result); // setflags is always FALSE here
8907         else
8908             R[d] = result;
8909             if setflags then
8910                 APSR.N = result<31>;
8911                 APSR.Z = IsZeroBit(result);
8912                 APSR.C = carry;
8913                 APSR.V = overflow;
8914 #endif
8915 
8916     bool success = false;
8917 
8918     uint32_t Rd; // the destination register
8919     uint32_t Rn; // the first operand
8920     uint32_t Rm; // the second operand
8921     bool setflags;
8922     ARM_ShifterType shift_t;
8923     uint32_t shift_n; // the shift applied to the value read from Rm
8924     switch (encoding) {
8925     case eEncodingT1:
8926         Rd = Rn = Bits32(opcode, 2, 0);
8927         Rm = Bits32(opcode, 5, 3);
8928         setflags = !InITBlock();
8929         shift_t = SRType_LSL;
8930         shift_n = 0;
8931         break;
8932     case eEncodingT2:
8933         Rd = Bits32(opcode, 11, 8);
8934         Rn = Bits32(opcode, 19, 16);
8935         Rm = Bits32(opcode, 3, 0);
8936         setflags = BitIsSet(opcode, 20);
8937         shift_n = DecodeImmShiftThumb(opcode, shift_t);
8938         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8939             return false;
8940         break;
8941     case eEncodingA1:
8942         Rd = Bits32(opcode, 15, 12);
8943         Rn = Bits32(opcode, 19, 16);
8944         Rm = Bits32(opcode, 3, 0);
8945         setflags = BitIsSet(opcode, 20);
8946         shift_n = DecodeImmShiftARM(opcode, shift_t);
8947 
8948         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8949         if (Rd == 15 && setflags)
8950             return EmulateSUBSPcLrEtc (opcode, encoding);
8951         break;
8952     default:
8953         return false;
8954     }
8955     // Read the register value from register Rn.
8956     uint32_t val1 = ReadCoreReg(Rn, &success);
8957     if (!success)
8958         return false;
8959 
8960     // Read the register value from register Rm.
8961     uint32_t val2 = ReadCoreReg(Rm, &success);
8962     if (!success)
8963         return false;
8964 
8965     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8966     if (!success)
8967         return false;
8968     AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
8969 
8970     EmulateInstruction::Context context;
8971     context.type = EmulateInstruction::eContextImmediate;
8972     context.SetNoArgs();
8973     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8974         return false;
8975 
8976     return true;
8977 }
8978 
8979 // This instruction subtracts an immediate value from a register value, and writes the result
8980 // to the destination register.  It can optionally update the condition flags based on the result.
8981 bool
8982 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding)
8983 {
8984 #if 0
8985     // ARM pseudo code...
8986     if ConditionPassed() then
8987         EncodingSpecificOperations();
8988         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
8989         R[d] = result;
8990         if setflags then
8991             APSR.N = result<31>;
8992             APSR.Z = IsZeroBit(result);
8993             APSR.C = carry;
8994             APSR.V = overflow;
8995 #endif
8996 
8997     bool success = false;
8998 
8999     uint32_t Rd; // the destination register
9000     uint32_t Rn; // the first operand
9001     bool setflags;
9002     uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9003     switch (encoding) {
9004     case eEncodingT1:
9005         Rd = Bits32(opcode, 2, 0);
9006         Rn = Bits32(opcode, 5, 3);
9007         setflags = !InITBlock();
9008         imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9009         break;
9010     case eEncodingT2:
9011         Rd = Rn = Bits32(opcode, 10, 8);
9012         setflags = !InITBlock();
9013         imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9014         break;
9015     case eEncodingT3:
9016         Rd = Bits32(opcode, 11, 8);
9017         Rn = Bits32(opcode, 19, 16);
9018         setflags = BitIsSet(opcode, 20);
9019         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9020 
9021         // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9022         if (Rd == 15 && setflags)
9023             return EmulateCMPImm (opcode, eEncodingT2);
9024 
9025         // if Rn == '1101' then SEE SUB (SP minus immediate);
9026         if (Rn == 13)
9027             return EmulateSUBSPImm (opcode, eEncodingT2);
9028 
9029         // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9030         if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9031             return false;
9032         break;
9033     case eEncodingT4:
9034         Rd = Bits32(opcode, 11, 8);
9035         Rn = Bits32(opcode, 19, 16);
9036         setflags = BitIsSet(opcode, 20);
9037         imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9038 
9039         // if Rn == '1111' then SEE ADR;
9040         if (Rn == 15)
9041             return EmulateADR (opcode, eEncodingT2);
9042 
9043         // if Rn == '1101' then SEE SUB (SP minus immediate);
9044         if (Rn == 13)
9045             return EmulateSUBSPImm (opcode, eEncodingT3);
9046 
9047         if (BadReg(Rd))
9048             return false;
9049         break;
9050     default:
9051         return false;
9052     }
9053     // Read the register value from the operand register Rn.
9054     uint32_t reg_val = ReadCoreReg(Rn, &success);
9055     if (!success)
9056         return false;
9057 
9058     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9059 
9060     EmulateInstruction::Context context;
9061     context.type = EmulateInstruction::eContextImmediate;
9062     context.SetNoArgs ();
9063 
9064     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9065         return false;
9066 
9067     return true;
9068 }
9069 
9070 // This instruction subtracts an immediate value from a register value, and writes the result
9071 // to the destination register.  It can optionally update the condition flags based on the result.
9072 bool
9073 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9074 {
9075 #if 0
9076     // ARM pseudo code...
9077     if ConditionPassed() then
9078         EncodingSpecificOperations();
9079         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9080         if d == 15 then
9081             ALUWritePC(result); // setflags is always FALSE here
9082         else
9083             R[d] = result;
9084             if setflags then
9085                 APSR.N = result<31>;
9086                 APSR.Z = IsZeroBit(result);
9087                 APSR.C = carry;
9088                 APSR.V = overflow;
9089 #endif
9090 
9091     bool success = false;
9092 
9093     uint32_t Rd; // the destination register
9094     uint32_t Rn; // the first operand
9095     bool setflags;
9096     uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9097     switch (encoding) {
9098     case eEncodingA1:
9099         Rd = Bits32(opcode, 15, 12);
9100         Rn = Bits32(opcode, 19, 16);
9101         setflags = BitIsSet(opcode, 20);
9102         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9103 
9104         // if Rn == '1111' && S == '0' then SEE ADR;
9105         if (Rn == 15 && !setflags)
9106             return EmulateADR (opcode, eEncodingA2);
9107 
9108         // if Rn == '1101' then SEE SUB (SP minus immediate);
9109         if (Rn == 13)
9110             return EmulateSUBSPImm (opcode, eEncodingA1);
9111 
9112         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9113         if (Rd == 15 && setflags)
9114             return EmulateSUBSPcLrEtc (opcode, encoding);
9115         break;
9116     default:
9117         return false;
9118     }
9119     // Read the register value from the operand register Rn.
9120     uint32_t reg_val = ReadCoreReg(Rn, &success);
9121     if (!success)
9122         return false;
9123 
9124     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9125 
9126     EmulateInstruction::Context context;
9127     context.type = EmulateInstruction::eContextImmediate;
9128     context.SetNoArgs ();
9129 
9130     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9131         return false;
9132 
9133     return true;
9134 }
9135 
9136 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an
9137 // immediate value.  It updates the condition flags based on the result, and discards the result.
9138 bool
9139 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding)
9140 {
9141 #if 0
9142     // ARM pseudo code...
9143     if ConditionPassed() then
9144         EncodingSpecificOperations();
9145         result = R[n] EOR imm32;
9146         APSR.N = result<31>;
9147         APSR.Z = IsZeroBit(result);
9148         APSR.C = carry;
9149         // APSR.V unchanged
9150 #endif
9151 
9152     bool success = false;
9153 
9154     if (ConditionPassed(opcode))
9155     {
9156         uint32_t Rn;
9157         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9158         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9159         switch (encoding)
9160         {
9161         case eEncodingT1:
9162             Rn = Bits32(opcode, 19, 16);
9163             imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9164             if (BadReg(Rn))
9165                 return false;
9166             break;
9167         case eEncodingA1:
9168             Rn = Bits32(opcode, 19, 16);
9169             imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9170             break;
9171         default:
9172             return false;
9173         }
9174 
9175         // Read the first operand.
9176         uint32_t val1 = ReadCoreReg(Rn, &success);
9177         if (!success)
9178             return false;
9179 
9180         uint32_t result = val1 ^ imm32;
9181 
9182         EmulateInstruction::Context context;
9183         context.type = EmulateInstruction::eContextImmediate;
9184         context.SetNoArgs ();
9185 
9186         if (!WriteFlags(context, result, carry))
9187             return false;
9188     }
9189     return true;
9190 }
9191 
9192 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an
9193 // optionally-shifted register value.  It updates the condition flags based on the result, and discards
9194 // the result.
9195 bool
9196 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding)
9197 {
9198 #if 0
9199     // ARM pseudo code...
9200     if ConditionPassed() then
9201         EncodingSpecificOperations();
9202         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9203         result = R[n] EOR shifted;
9204         APSR.N = result<31>;
9205         APSR.Z = IsZeroBit(result);
9206         APSR.C = carry;
9207         // APSR.V unchanged
9208 #endif
9209 
9210     bool success = false;
9211 
9212     if (ConditionPassed(opcode))
9213     {
9214         uint32_t Rn, Rm;
9215         ARM_ShifterType shift_t;
9216         uint32_t shift_n; // the shift applied to the value read from Rm
9217         uint32_t carry;
9218         switch (encoding)
9219         {
9220         case eEncodingT1:
9221             Rn = Bits32(opcode, 19, 16);
9222             Rm = Bits32(opcode, 3, 0);
9223             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9224             if (BadReg(Rn) || BadReg(Rm))
9225                 return false;
9226             break;
9227         case eEncodingA1:
9228             Rn = Bits32(opcode, 19, 16);
9229             Rm = Bits32(opcode, 3, 0);
9230             shift_n = DecodeImmShiftARM(opcode, shift_t);
9231             break;
9232         default:
9233             return false;
9234         }
9235 
9236         // Read the first operand.
9237         uint32_t val1 = ReadCoreReg(Rn, &success);
9238         if (!success)
9239             return false;
9240 
9241         // Read the second operand.
9242         uint32_t val2 = ReadCoreReg(Rm, &success);
9243         if (!success)
9244             return false;
9245 
9246         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9247         if (!success)
9248             return false;
9249         uint32_t result = val1 ^ shifted;
9250 
9251         EmulateInstruction::Context context;
9252         context.type = EmulateInstruction::eContextImmediate;
9253         context.SetNoArgs ();
9254 
9255         if (!WriteFlags(context, result, carry))
9256             return false;
9257     }
9258     return true;
9259 }
9260 
9261 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value.
9262 // It updates the condition flags based on the result, and discards the result.
9263 bool
9264 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding)
9265 {
9266 #if 0
9267     // ARM pseudo code...
9268     if ConditionPassed() then
9269         EncodingSpecificOperations();
9270         result = R[n] AND imm32;
9271         APSR.N = result<31>;
9272         APSR.Z = IsZeroBit(result);
9273         APSR.C = carry;
9274         // APSR.V unchanged
9275 #endif
9276 
9277     bool success = false;
9278 
9279     if (ConditionPassed(opcode))
9280     {
9281         uint32_t Rn;
9282         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9283         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9284         switch (encoding)
9285         {
9286         case eEncodingT1:
9287             Rn = Bits32(opcode, 19, 16);
9288             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9289             if (BadReg(Rn))
9290                 return false;
9291             break;
9292         case eEncodingA1:
9293             Rn = Bits32(opcode, 19, 16);
9294             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9295             break;
9296         default:
9297             return false;
9298         }
9299 
9300         // Read the first operand.
9301         uint32_t val1 = ReadCoreReg(Rn, &success);
9302         if (!success)
9303             return false;
9304 
9305         uint32_t result = val1 & imm32;
9306 
9307         EmulateInstruction::Context context;
9308         context.type = EmulateInstruction::eContextImmediate;
9309         context.SetNoArgs ();
9310 
9311         if (!WriteFlags(context, result, carry))
9312             return false;
9313     }
9314     return true;
9315 }
9316 
9317 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value.
9318 // It updates the condition flags based on the result, and discards the result.
9319 bool
9320 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding)
9321 {
9322 #if 0
9323     // ARM pseudo code...
9324     if ConditionPassed() then
9325         EncodingSpecificOperations();
9326         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9327         result = R[n] AND shifted;
9328         APSR.N = result<31>;
9329         APSR.Z = IsZeroBit(result);
9330         APSR.C = carry;
9331         // APSR.V unchanged
9332 #endif
9333 
9334     bool success = false;
9335 
9336     if (ConditionPassed(opcode))
9337     {
9338         uint32_t Rn, Rm;
9339         ARM_ShifterType shift_t;
9340         uint32_t shift_n; // the shift applied to the value read from Rm
9341         uint32_t carry;
9342         switch (encoding)
9343         {
9344         case eEncodingT1:
9345             Rn = Bits32(opcode, 2, 0);
9346             Rm = Bits32(opcode, 5, 3);
9347             shift_t = SRType_LSL;
9348             shift_n = 0;
9349             break;
9350         case eEncodingT2:
9351             Rn = Bits32(opcode, 19, 16);
9352             Rm = Bits32(opcode, 3, 0);
9353             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9354             if (BadReg(Rn) || BadReg(Rm))
9355                 return false;
9356             break;
9357         case eEncodingA1:
9358             Rn = Bits32(opcode, 19, 16);
9359             Rm = Bits32(opcode, 3, 0);
9360             shift_n = DecodeImmShiftARM(opcode, shift_t);
9361             break;
9362         default:
9363             return false;
9364         }
9365 
9366         // Read the first operand.
9367         uint32_t val1 = ReadCoreReg(Rn, &success);
9368         if (!success)
9369             return false;
9370 
9371         // Read the second operand.
9372         uint32_t val2 = ReadCoreReg(Rm, &success);
9373         if (!success)
9374             return false;
9375 
9376         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9377         if (!success)
9378             return false;
9379         uint32_t result = val1 & shifted;
9380 
9381         EmulateInstruction::Context context;
9382         context.type = EmulateInstruction::eContextImmediate;
9383         context.SetNoArgs ();
9384 
9385         if (!WriteFlags(context, result, carry))
9386             return false;
9387     }
9388     return true;
9389 }
9390 
9391 // A8.6.216 SUB (SP minus register)
9392 bool
9393 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding)
9394 {
9395 #if 0
9396     if ConditionPassed() then
9397         EncodingSpecificOperations();
9398         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9399         (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9400         if d == 15 then // Can only occur for ARM encoding
9401             ALUWritePC(result); // setflags is always FALSE here
9402         else
9403             R[d] = result;
9404             if setflags then
9405                 APSR.N = result<31>;
9406                 APSR.Z = IsZeroBit(result);
9407                 APSR.C = carry;
9408                 APSR.V = overflow;
9409 #endif
9410 
9411     bool success = false;
9412 
9413     if (ConditionPassed(opcode))
9414     {
9415         uint32_t d;
9416         uint32_t m;
9417         bool setflags;
9418         ARM_ShifterType shift_t;
9419         uint32_t shift_n;
9420 
9421         switch (encoding)
9422         {
9423             case eEncodingT1:
9424                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9425                 d = Bits32 (opcode, 11, 8);
9426                 m = Bits32 (opcode, 3, 0);
9427                 setflags = BitIsSet (opcode, 20);
9428 
9429                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9430                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9431 
9432                 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE;
9433                 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
9434                     return false;
9435 
9436                 // if d == 15 || BadReg(m) then UNPREDICTABLE;
9437                 if ((d == 15) || BadReg (m))
9438                     return false;
9439                 break;
9440 
9441             case eEncodingA1:
9442                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9443                 d = Bits32 (opcode, 15, 12);
9444                 m = Bits32 (opcode, 3, 0);
9445                 setflags = BitIsSet (opcode, 20);
9446 
9447                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9448                 if (d == 15 && setflags)
9449                     EmulateSUBSPcLrEtc (opcode, encoding);
9450 
9451                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9452                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9453                 break;
9454 
9455             default:
9456                 return false;
9457         }
9458 
9459         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9460         uint32_t Rm = ReadCoreReg (m, &success);
9461         if (!success)
9462             return false;
9463 
9464         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9465         if (!success)
9466             return false;
9467 
9468         // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9469         uint32_t sp_val = ReadCoreReg (SP_REG, &success);
9470         if (!success)
9471             return false;
9472 
9473         AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1);
9474 
9475         EmulateInstruction::Context context;
9476         context.type = eContextArithmetic;
9477         RegisterInfo sp_reg;
9478         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
9479         RegisterInfo dwarf_reg;
9480         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
9481         context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
9482 
9483         if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9484             return false;
9485     }
9486     return true;
9487 }
9488 
9489 
9490 // A8.6.7 ADD (register-shifted register)
9491 bool
9492 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding)
9493 {
9494 #if 0
9495     if ConditionPassed() then
9496         EncodingSpecificOperations();
9497         shift_n = UInt(R[s]<7:0>);
9498         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9499         (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9500         R[d] = result;
9501         if setflags then
9502             APSR.N = result<31>;
9503             APSR.Z = IsZeroBit(result);
9504             APSR.C = carry;
9505             APSR.V = overflow;
9506 #endif
9507 
9508     bool success = false;
9509 
9510     if (ConditionPassed(opcode))
9511     {
9512         uint32_t d;
9513         uint32_t n;
9514         uint32_t m;
9515         uint32_t s;
9516         bool setflags;
9517         ARM_ShifterType shift_t;
9518 
9519         switch (encoding)
9520         {
9521             case eEncodingA1:
9522                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
9523                 d = Bits32 (opcode, 15, 12);
9524                 n = Bits32 (opcode, 19, 16);
9525                 m = Bits32 (opcode, 3, 0);
9526                 s = Bits32 (opcode, 11, 8);
9527 
9528                 // setflags = (S == �1�); shift_t = DecodeRegShift(type);
9529                 setflags = BitIsSet (opcode, 20);
9530                 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5));
9531 
9532                 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
9533                 if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
9534                     return false;
9535                 break;
9536 
9537             default:
9538                 return false;
9539         }
9540 
9541         // shift_n = UInt(R[s]<7:0>);
9542         uint32_t Rs = ReadCoreReg (s, &success);
9543         if (!success)
9544             return false;
9545 
9546         uint32_t shift_n = Bits32 (Rs, 7, 0);
9547 
9548         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9549         uint32_t Rm = ReadCoreReg (m, &success);
9550         if (!success)
9551             return false;
9552 
9553         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9554         if (!success)
9555             return false;
9556 
9557         // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9558         uint32_t Rn = ReadCoreReg (n, &success);
9559         if (!success)
9560             return false;
9561 
9562         AddWithCarryResult res = AddWithCarry (Rn, shifted, 0);
9563 
9564         // R[d] = result;
9565         EmulateInstruction::Context context;
9566         context.type = eContextArithmetic;
9567         RegisterInfo reg_n;
9568         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9569         RegisterInfo reg_m;
9570         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9571 
9572         context.SetRegisterRegisterOperands (reg_n, reg_m);
9573 
9574         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result))
9575             return false;
9576 
9577         // if setflags then
9578             // APSR.N = result<31>;
9579             // APSR.Z = IsZeroBit(result);
9580             // APSR.C = carry;
9581             // APSR.V = overflow;
9582         if (setflags)
9583             return WriteFlags (context, res.result, res.carry_out, res.overflow);
9584     }
9585     return true;
9586 }
9587 
9588 // A8.6.213 SUB (register)
9589 bool
9590 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding)
9591 {
9592 #if 0
9593     if ConditionPassed() then
9594         EncodingSpecificOperations();
9595         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9596         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9597         if d == 15 then // Can only occur for ARM encoding
9598             ALUWritePC(result); // setflags is always FALSE here
9599         else
9600             R[d] = result;
9601             if setflags then
9602                 APSR.N = result<31>;
9603                 APSR.Z = IsZeroBit(result);
9604                 APSR.C = carry;
9605                 APSR.V = overflow;
9606 #endif
9607 
9608     bool success = false;
9609 
9610     if (ConditionPassed(opcode))
9611     {
9612         uint32_t d;
9613         uint32_t n;
9614         uint32_t m;
9615         bool setflags;
9616         ARM_ShifterType shift_t;
9617         uint32_t shift_n;
9618 
9619         switch (encoding)
9620         {
9621             case eEncodingT1:
9622                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
9623                 d = Bits32 (opcode, 2, 0);
9624                 n = Bits32 (opcode, 5, 3);
9625                 m = Bits32 (opcode, 8, 6);
9626                 setflags = !InITBlock();
9627 
9628                 // (shift_t, shift_n) = (SRType_LSL, 0);
9629                 shift_t = SRType_LSL;
9630                 shift_n = 0;
9631 
9632                 break;
9633 
9634             case eEncodingT2:
9635                 // if Rd == �1111� && S == �1� then SEE CMP (register);
9636                 // if Rn == �1101� then SEE SUB (SP minus register);
9637                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9638                 d = Bits32 (opcode, 11, 8);
9639                 n = Bits32 (opcode, 19, 16);
9640                 m = Bits32 (opcode, 3, 0);
9641                 setflags = BitIsSet (opcode, 20);
9642 
9643                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9644                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9645 
9646                 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE;
9647                 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m))
9648                     return false;
9649 
9650                 break;
9651 
9652             case eEncodingA1:
9653                 // if Rn == �1101� then SEE SUB (SP minus register);
9654                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9655                 d = Bits32 (opcode, 15, 12);
9656                 n = Bits32 (opcode, 19, 16);
9657                 m = Bits32 (opcode, 3, 0);
9658                 setflags = BitIsSet (opcode, 20);
9659 
9660                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9661                 if ((d == 15) && setflags)
9662                     EmulateSUBSPcLrEtc (opcode, encoding);
9663 
9664                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9665                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9666 
9667                 break;
9668 
9669             default:
9670                 return false;
9671         }
9672 
9673         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9674         uint32_t Rm = ReadCoreReg (m, &success);
9675         if (!success)
9676             return false;
9677 
9678         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9679         if (!success)
9680             return false;
9681 
9682         // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9683         uint32_t Rn = ReadCoreReg (n, &success);
9684         if (!success)
9685             return false;
9686 
9687         AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1);
9688 
9689         // if d == 15 then // Can only occur for ARM encoding
9690             // ALUWritePC(result); // setflags is always FALSE here
9691         // else
9692             // R[d] = result;
9693             // if setflags then
9694                 // APSR.N = result<31>;
9695                 // APSR.Z = IsZeroBit(result);
9696                 // APSR.C = carry;
9697                 // APSR.V = overflow;
9698 
9699         EmulateInstruction::Context context;
9700         context.type = eContextArithmetic;
9701         RegisterInfo reg_n;
9702         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9703         RegisterInfo reg_m;
9704         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9705         context.SetRegisterRegisterOperands (reg_n, reg_m);
9706 
9707         if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9708             return false;
9709     }
9710     return true;
9711 }
9712 
9713 // A8.6.202 STREX
9714 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a
9715 // word from a register to memory if the executing processor has exclusive access to the memory addressed.
9716 bool
9717 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding)
9718 {
9719 #if 0
9720     if ConditionPassed() then
9721         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9722         address = R[n] + imm32;
9723         if ExclusiveMonitorsPass(address,4) then
9724             MemA[address,4] = R[t];
9725             R[d] = 0;
9726         else
9727             R[d] = 1;
9728 #endif
9729 
9730     bool success = false;
9731 
9732     if (ConditionPassed(opcode))
9733     {
9734         uint32_t d;
9735         uint32_t t;
9736         uint32_t n;
9737         uint32_t imm32;
9738         const uint32_t addr_byte_size = GetAddressByteSize();
9739 
9740         switch (encoding)
9741         {
9742             case eEncodingT1:
9743                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
9744                 d = Bits32 (opcode, 11, 8);
9745                 t = Bits32 (opcode, 15, 12);
9746                 n = Bits32 (opcode, 19, 16);
9747                 imm32 = Bits32 (opcode, 7, 0) << 2;
9748 
9749                 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
9750                 if (BadReg (d) || BadReg (t) || (n == 15))
9751                   return false;
9752 
9753                 // if d == n || d == t then UNPREDICTABLE;
9754                 if ((d == n) || (d == t))
9755                   return false;
9756 
9757                 break;
9758 
9759             case eEncodingA1:
9760                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset
9761                 d = Bits32 (opcode, 15, 12);
9762                 t = Bits32 (opcode, 3, 0);
9763                 n = Bits32 (opcode, 19, 16);
9764                 imm32 = 0;
9765 
9766                 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
9767                 if ((d == 15) || (t == 15) || (n == 15))
9768                     return false;
9769 
9770                 // if d == n || d == t then UNPREDICTABLE;
9771                 if ((d == n) || (d == t))
9772                     return false;
9773 
9774                 break;
9775 
9776             default:
9777                 return false;
9778         }
9779 
9780         // address = R[n] + imm32;
9781         uint32_t Rn = ReadCoreReg (n, &success);
9782         if (!success)
9783             return false;
9784 
9785         addr_t address = Rn + imm32;
9786 
9787         RegisterInfo base_reg;
9788         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9789         RegisterInfo data_reg;
9790         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9791         EmulateInstruction::Context context;
9792         context.type = eContextRegisterStore;
9793         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32);
9794 
9795         // if ExclusiveMonitorsPass(address,4) then
9796         // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this
9797         //                                                         always return true.
9798         if (true)
9799         {
9800             // MemA[address,4] = R[t];
9801             uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
9802             if (!success)
9803                 return false;
9804 
9805             if (!MemAWrite (context, address, Rt, addr_byte_size))
9806                 return false;
9807 
9808             // R[d] = 0;
9809             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0))
9810                 return false;
9811         }
9812         else
9813         {
9814             // R[d] = 1;
9815             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
9816                 return false;
9817         }
9818     }
9819     return true;
9820 }
9821 
9822 // A8.6.197 STRB (immediate, ARM)
9823 bool
9824 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9825 {
9826 #if 0
9827     if ConditionPassed() then
9828         EncodingSpecificOperations();
9829         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9830         address = if index then offset_addr else R[n];
9831         MemU[address,1] = R[t]<7:0>;
9832         if wback then R[n] = offset_addr;
9833 #endif
9834 
9835     bool success = false;
9836 
9837     if (ConditionPassed(opcode))
9838     {
9839         uint32_t t;
9840         uint32_t n;
9841         uint32_t imm32;
9842         bool index;
9843         bool add;
9844         bool wback;
9845 
9846         switch (encoding)
9847         {
9848             case eEncodingA1:
9849                 // if P == �0� && W == �1� then SEE STRBT;
9850                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9851                 t = Bits32 (opcode, 15, 12);
9852                 n = Bits32 (opcode, 19, 16);
9853                 imm32 = Bits32 (opcode, 11, 0);
9854 
9855                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9856                 index = BitIsSet (opcode, 24);
9857                 add = BitIsSet (opcode, 23);
9858                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9859 
9860                 // if t == 15 then UNPREDICTABLE;
9861                 if (t == 15)
9862                     return false;
9863 
9864                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9865                 if (wback && ((n == 15) || (n == t)))
9866                     return false;
9867 
9868                 break;
9869 
9870             default:
9871                 return false;
9872         }
9873 
9874         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9875         uint32_t Rn = ReadCoreReg (n, &success);
9876         if (!success)
9877             return false;
9878 
9879         addr_t offset_addr;
9880         if (add)
9881             offset_addr = Rn + imm32;
9882         else
9883             offset_addr = Rn - imm32;
9884 
9885         // address = if index then offset_addr else R[n];
9886         addr_t address;
9887         if (index)
9888             address = offset_addr;
9889         else
9890             address = Rn;
9891 
9892         // MemU[address,1] = R[t]<7:0>;
9893         uint32_t Rt = ReadCoreReg (t, &success);
9894         if (!success)
9895             return false;
9896 
9897         RegisterInfo base_reg;
9898         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9899         RegisterInfo data_reg;
9900         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9901         EmulateInstruction::Context context;
9902         context.type = eContextRegisterStore;
9903         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
9904 
9905         if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1))
9906             return false;
9907 
9908         // if wback then R[n] = offset_addr;
9909         if (wback)
9910         {
9911             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
9912                 return false;
9913         }
9914     }
9915     return true;
9916 }
9917 
9918 // A8.6.194 STR (immediate, ARM)
9919 bool
9920 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding)
9921 {
9922 #if 0
9923     if ConditionPassed() then
9924         EncodingSpecificOperations();
9925         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9926         address = if index then offset_addr else R[n];
9927         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
9928         if wback then R[n] = offset_addr;
9929 #endif
9930 
9931     bool success = false;
9932 
9933     if (ConditionPassed(opcode))
9934     {
9935         uint32_t t;
9936         uint32_t n;
9937         uint32_t imm32;
9938         bool index;
9939         bool add;
9940         bool wback;
9941 
9942         const uint32_t addr_byte_size = GetAddressByteSize();
9943 
9944         switch (encoding)
9945         {
9946             case eEncodingA1:
9947                 // if P == �0� && W == �1� then SEE STRT;
9948                 // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH;
9949                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9950                 t = Bits32 (opcode, 15, 12);
9951                 n = Bits32 (opcode, 19, 16);
9952                 imm32 = Bits32 (opcode, 11, 0);
9953 
9954                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9955                 index = BitIsSet (opcode, 24);
9956                 add = BitIsSet (opcode, 23);
9957                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9958 
9959                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9960                 if (wback && ((n == 15) || (n == t)))
9961                     return false;
9962 
9963                 break;
9964 
9965             default:
9966                 return false;
9967         }
9968 
9969         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9970         uint32_t Rn = ReadCoreReg (n, &success);
9971         if (!success)
9972             return false;
9973 
9974         addr_t offset_addr;
9975         if (add)
9976             offset_addr = Rn + imm32;
9977         else
9978             offset_addr = Rn - imm32;
9979 
9980         // address = if index then offset_addr else R[n];
9981         addr_t address;
9982         if (index)
9983             address = offset_addr;
9984         else
9985             address = Rn;
9986 
9987         RegisterInfo base_reg;
9988         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9989         RegisterInfo data_reg;
9990         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9991         EmulateInstruction::Context context;
9992         context.type = eContextRegisterStore;
9993         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
9994 
9995         // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
9996         uint32_t Rt = ReadCoreReg (t, &success);
9997         if (!success)
9998             return false;
9999 
10000         if (t == 15)
10001         {
10002             uint32_t pc_value = ReadCoreReg (PC_REG, &success);
10003             if (!success)
10004                 return false;
10005 
10006             if (!MemUWrite (context, address, pc_value, addr_byte_size))
10007                 return false;
10008         }
10009         else
10010         {
10011             if (!MemUWrite (context, address, Rt, addr_byte_size))
10012                   return false;
10013         }
10014 
10015         // if wback then R[n] = offset_addr;
10016         if (wback)
10017         {
10018             context.type = eContextAdjustBaseRegister;
10019             context.SetImmediate (offset_addr);
10020 
10021             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10022                 return false;
10023         }
10024     }
10025     return true;
10026 }
10027 
10028 // A8.6.66 LDRD (immediate)
10029 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two
10030 // words from memory, and writes them to two registers.  It can use offset, post-indexed, or pre-indexed addressing.
10031 bool
10032 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding)
10033 {
10034 #if 0
10035     if ConditionPassed() then
10036         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10037         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10038         address = if index then offset_addr else R[n];
10039         R[t] = MemA[address,4];
10040         R[t2] = MemA[address+4,4];
10041         if wback then R[n] = offset_addr;
10042 #endif
10043 
10044     bool success = false;
10045 
10046     if (ConditionPassed(opcode))
10047     {
10048         uint32_t t;
10049         uint32_t t2;
10050         uint32_t n;
10051         uint32_t imm32;
10052         bool index;
10053         bool add;
10054         bool wback;
10055 
10056         switch (encoding)
10057         {
10058             case eEncodingT1:
10059                 //if P == �0� && W == �0� then SEE �Related encodings�;
10060                 //if Rn == �1111� then SEE LDRD (literal);
10061                 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10062                 t = Bits32 (opcode, 15, 12);
10063                 t2 = Bits32 (opcode, 11, 8);
10064                 n = Bits32 (opcode, 19, 16);
10065                 imm32 = Bits32 (opcode, 7, 0) << 2;
10066 
10067                 //index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10068                 index = BitIsSet (opcode, 24);
10069                 add = BitIsSet (opcode, 23);
10070                 wback = BitIsSet (opcode, 21);
10071 
10072                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10073                 if (wback && ((n == t) || (n == t2)))
10074                     return false;
10075 
10076                 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10077                 if (BadReg (t) || BadReg (t2) || (t == t2))
10078                     return false;
10079 
10080                 break;
10081 
10082             case eEncodingA1:
10083                 //if Rn == �1111� then SEE LDRD (literal);
10084                 //if Rt<0> == �1� then UNPREDICTABLE;
10085                 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10086                 t = Bits32 (opcode, 15, 12);
10087                 if (BitIsSet (t, 0))
10088                     return false;
10089                 t2 = t + 1;
10090                 n = Bits32 (opcode, 19, 16);
10091                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10092 
10093                 //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10094                 index = BitIsSet (opcode, 24);
10095                 add = BitIsSet (opcode, 23);
10096                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10097 
10098                 //if P == �0� && W == �1� then UNPREDICTABLE;
10099                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10100                     return false;
10101 
10102                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10103                 if (wback && ((n == t) || (n == t2)))
10104                     return false;
10105 
10106                 //if t2 == 15 then UNPREDICTABLE;
10107                 if (t2 == 15)
10108                     return false;
10109 
10110                 break;
10111 
10112             default:
10113                 return false;
10114         }
10115 
10116         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10117         uint32_t Rn = ReadCoreReg (n, &success);
10118         if (!success)
10119             return false;
10120 
10121         addr_t offset_addr;
10122         if (add)
10123                   offset_addr = Rn + imm32;
10124         else
10125             offset_addr = Rn - imm32;
10126 
10127         //address = if index then offset_addr else R[n];
10128         addr_t address;
10129         if (index)
10130             address = offset_addr;
10131         else
10132             address = Rn;
10133 
10134         //R[t] = MemA[address,4];
10135         RegisterInfo base_reg;
10136         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10137 
10138         EmulateInstruction::Context context;
10139         context.type = eContextRegisterLoad;
10140         context.SetRegisterPlusOffset (base_reg, address - Rn);
10141 
10142         const uint32_t addr_byte_size = GetAddressByteSize();
10143         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10144         if (!success)
10145             return false;
10146 
10147         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10148             return false;
10149 
10150         //R[t2] = MemA[address+4,4];
10151 
10152         context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10153         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10154         if (!success)
10155             return false;
10156 
10157         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10158             return false;
10159 
10160         //if wback then R[n] = offset_addr;
10161         if (wback)
10162         {
10163             context.type = eContextAdjustBaseRegister;
10164             context.SetAddress (offset_addr);
10165 
10166             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10167                 return false;
10168         }
10169     }
10170     return true;
10171 }
10172 
10173 // A8.6.68 LDRD (register)
10174 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two
10175 // words from memory, and writes them to two registers.  It can use offset, post-indexed or pre-indexed addressing.
10176 bool
10177 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding)
10178 {
10179 #if 0
10180     if ConditionPassed() then
10181         EncodingSpecificOperations();
10182         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10183         address = if index then offset_addr else R[n];
10184         R[t] = MemA[address,4];
10185         R[t2] = MemA[address+4,4];
10186         if wback then R[n] = offset_addr;
10187 #endif
10188 
10189     bool success = false;
10190 
10191     if (ConditionPassed(opcode))
10192     {
10193         uint32_t t;
10194         uint32_t t2;
10195         uint32_t n;
10196         uint32_t m;
10197         bool index;
10198         bool add;
10199         bool wback;
10200 
10201         switch (encoding)
10202         {
10203             case eEncodingA1:
10204                 // if Rt<0> == �1� then UNPREDICTABLE;
10205                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10206                 t = Bits32 (opcode, 15, 12);
10207                 if (BitIsSet (t, 0))
10208                     return false;
10209                 t2 = t + 1;
10210                 n = Bits32 (opcode, 19, 16);
10211                 m = Bits32 (opcode, 3, 0);
10212 
10213                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10214                 index = BitIsSet (opcode, 24);
10215                 add = BitIsSet (opcode, 23);
10216                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10217 
10218                 // if P == �0� && W == �1� then UNPREDICTABLE;
10219                   if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10220                   return false;
10221 
10222                 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10223                   if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10224                   return false;
10225 
10226                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10227                   if (wback && ((n == 15) || (n == t) || (n == t2)))
10228                   return false;
10229 
10230                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10231                 if ((ArchVersion() < 6) && wback && (m == n))
10232                   return false;
10233                 break;
10234 
10235             default:
10236                 return false;
10237         }
10238 
10239         uint32_t Rn = ReadCoreReg (n, &success);
10240         if (!success)
10241             return false;
10242         RegisterInfo base_reg;
10243         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10244 
10245         uint32_t Rm = ReadCoreReg (m, &success);
10246         if (!success)
10247             return false;
10248         RegisterInfo offset_reg;
10249         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10250 
10251         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10252         addr_t offset_addr;
10253         if (add)
10254             offset_addr = Rn + Rm;
10255         else
10256             offset_addr = Rn - Rm;
10257 
10258         // address = if index then offset_addr else R[n];
10259         addr_t address;
10260         if (index)
10261             address = offset_addr;
10262         else
10263             address = Rn;
10264 
10265         EmulateInstruction::Context context;
10266         context.type = eContextRegisterLoad;
10267         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
10268 
10269         // R[t] = MemA[address,4];
10270         const uint32_t addr_byte_size = GetAddressByteSize();
10271         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10272         if (!success)
10273             return false;
10274 
10275         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10276             return false;
10277 
10278         // R[t2] = MemA[address+4,4];
10279 
10280         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10281         if (!success)
10282             return false;
10283 
10284         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10285             return false;
10286 
10287         // if wback then R[n] = offset_addr;
10288         if (wback)
10289         {
10290             context.type = eContextAdjustBaseRegister;
10291             context.SetAddress (offset_addr);
10292 
10293             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10294                 return false;
10295         }
10296     }
10297     return true;
10298 }
10299 
10300 // A8.6.200 STRD (immediate)
10301 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and
10302 // stores two words from two registers to memory.  It can use offset, post-indexed, or pre-indexed addressing.
10303 bool
10304 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding)
10305 {
10306 #if 0
10307     if ConditionPassed() then
10308         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10309         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10310         address = if index then offset_addr else R[n];
10311         MemA[address,4] = R[t];
10312         MemA[address+4,4] = R[t2];
10313         if wback then R[n] = offset_addr;
10314 #endif
10315 
10316     bool success = false;
10317 
10318     if (ConditionPassed(opcode))
10319     {
10320         uint32_t t;
10321         uint32_t t2;
10322         uint32_t n;
10323         uint32_t imm32;
10324         bool index;
10325         bool add;
10326         bool wback;
10327 
10328         switch (encoding)
10329         {
10330             case eEncodingT1:
10331                 // if P == �0� && W == �0� then SEE �Related encodings�;
10332                 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10333                 t = Bits32 (opcode, 15, 12);
10334                 t2 = Bits32 (opcode, 11, 8);
10335                 n = Bits32 (opcode, 19, 16);
10336                 imm32 = Bits32 (opcode, 7, 0) << 2;
10337 
10338                 // index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10339                 index = BitIsSet (opcode, 24);
10340                 add = BitIsSet (opcode, 23);
10341                 wback = BitIsSet (opcode, 21);
10342 
10343                 // if wback && (n == t || n == t2) then UNPREDICTABLE;
10344                 if (wback && ((n == t) || (n == t2)))
10345                     return false;
10346 
10347                 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10348                 if ((n == 15) || BadReg (t) || BadReg (t2))
10349                     return false;
10350 
10351                 break;
10352 
10353             case eEncodingA1:
10354                 // if Rt<0> == �1� then UNPREDICTABLE;
10355                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10356                 t = Bits32 (opcode, 15, 12);
10357                 if (BitIsSet (t, 0))
10358                     return false;
10359 
10360                 t2 = t + 1;
10361                 n = Bits32 (opcode, 19, 16);
10362                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10363 
10364                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10365                 index = BitIsSet (opcode, 24);
10366                 add = BitIsSet (opcode, 23);
10367                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10368 
10369                 // if P == �0� && W == �1� then UNPREDICTABLE;
10370                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10371                     return false;
10372 
10373                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10374                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10375                     return false;
10376 
10377                 // if t2 == 15 then UNPREDICTABLE;
10378                 if (t2 == 15)
10379                     return false;
10380 
10381                 break;
10382 
10383             default:
10384                 return false;
10385         }
10386 
10387         RegisterInfo base_reg;
10388         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10389 
10390         uint32_t Rn = ReadCoreReg (n, &success);
10391         if (!success)
10392             return false;
10393 
10394         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10395         addr_t offset_addr;
10396         if (add)
10397             offset_addr = Rn + imm32;
10398         else
10399             offset_addr = Rn - imm32;
10400 
10401         //address = if index then offset_addr else R[n];
10402         addr_t address;
10403         if (index)
10404             address = offset_addr;
10405         else
10406             address = Rn;
10407 
10408         //MemA[address,4] = R[t];
10409         RegisterInfo data_reg;
10410         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10411 
10412         uint32_t data = ReadCoreReg (t, &success);
10413         if (!success)
10414             return false;
10415 
10416         EmulateInstruction::Context context;
10417         context.type = eContextRegisterStore;
10418         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10419 
10420         const uint32_t addr_byte_size = GetAddressByteSize();
10421 
10422         if (!MemAWrite (context, address, data, addr_byte_size))
10423             return false;
10424 
10425         //MemA[address+4,4] = R[t2];
10426         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10427         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10428 
10429         data = ReadCoreReg (t2, &success);
10430         if (!success)
10431             return false;
10432 
10433         if (!MemAWrite (context, address + 4, data, addr_byte_size))
10434             return false;
10435 
10436         //if wback then R[n] = offset_addr;
10437         if (wback)
10438         {
10439             context.type = eContextAdjustBaseRegister;
10440             context.SetAddress (offset_addr);
10441 
10442             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10443                 return false;
10444         }
10445     }
10446     return true;
10447 }
10448 
10449 
10450 // A8.6.201 STRD (register)
10451 bool
10452 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding)
10453 {
10454 #if 0
10455     if ConditionPassed() then
10456         EncodingSpecificOperations();
10457         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10458         address = if index then offset_addr else R[n];
10459         MemA[address,4] = R[t];
10460         MemA[address+4,4] = R[t2];
10461         if wback then R[n] = offset_addr;
10462 #endif
10463 
10464     bool success = false;
10465 
10466     if (ConditionPassed(opcode))
10467     {
10468         uint32_t t;
10469         uint32_t t2;
10470         uint32_t n;
10471         uint32_t m;
10472         bool index;
10473         bool add;
10474         bool wback;
10475 
10476         switch (encoding)
10477         {
10478             case eEncodingA1:
10479                 // if Rt<0> == �1� then UNPREDICTABLE;
10480                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10481                 t = Bits32 (opcode, 15, 12);
10482                 if (BitIsSet (t, 0))
10483                    return false;
10484 
10485                 t2 = t+1;
10486                 n = Bits32 (opcode, 19, 16);
10487                 m = Bits32 (opcode, 3, 0);
10488 
10489                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10490                 index = BitIsSet (opcode, 24);
10491                 add = BitIsSet (opcode, 23);
10492                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10493 
10494                 // if P == �0� && W == �1� then UNPREDICTABLE;
10495                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10496                    return false;
10497 
10498                 // if t2 == 15 || m == 15 then UNPREDICTABLE;
10499                 if ((t2 == 15) || (m == 15))
10500                    return false;
10501 
10502                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10503                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10504                    return false;
10505 
10506                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10507                 if ((ArchVersion() < 6) && wback && (m == n))
10508                    return false;
10509 
10510                 break;
10511 
10512             default:
10513                 return false;
10514         }
10515 
10516         RegisterInfo base_reg;
10517         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10518         RegisterInfo offset_reg;
10519         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10520         RegisterInfo data_reg;
10521 
10522         uint32_t Rn = ReadCoreReg (n, &success);
10523         if (!success)
10524             return false;
10525 
10526         uint32_t Rm = ReadCoreReg (m, &success);
10527         if (!success)
10528             return false;
10529 
10530         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10531         addr_t offset_addr;
10532         if (add)
10533             offset_addr = Rn + Rm;
10534         else
10535             offset_addr = Rn - Rm;
10536 
10537         // address = if index then offset_addr else R[n];
10538         addr_t address;
10539         if (index)
10540             address = offset_addr;
10541         else
10542             address = Rn;
10543                           // MemA[address,4] = R[t];
10544         uint32_t Rt = ReadCoreReg (t, &success);
10545         if (!success)
10546             return false;
10547 
10548         EmulateInstruction::Context context;
10549         context.type = eContextRegisterStore;
10550         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10551         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10552 
10553         const uint32_t addr_byte_size = GetAddressByteSize();
10554 
10555         if (!MemAWrite (context, address, Rt, addr_byte_size))
10556             return false;
10557 
10558         // MemA[address+4,4] = R[t2];
10559         uint32_t Rt2 = ReadCoreReg (t2, &success);
10560         if (!success)
10561             return false;
10562 
10563         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10564 
10565         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10566 
10567         if (!MemAWrite (context, address + 4, Rt2, addr_byte_size))
10568             return false;
10569 
10570         // if wback then R[n] = offset_addr;
10571         if (wback)
10572         {
10573             context.type = eContextAdjustBaseRegister;
10574             context.SetAddress (offset_addr);
10575 
10576             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10577                 return false;
10578 
10579         }
10580     }
10581     return true;
10582 }
10583 
10584 // A8.6.319 VLDM
10585 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from
10586 // an ARM core register.
10587 bool
10588 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding)
10589 {
10590 #if 0
10591     if ConditionPassed() then
10592         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10593         address = if add then R[n] else R[n]-imm32;
10594         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10595         for r = 0 to regs-1
10596             if single_regs then
10597                 S[d+r] = MemA[address,4]; address = address+4;
10598             else
10599                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10600                 // Combine the word-aligned words in the correct order for current endianness.
10601                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10602 #endif
10603 
10604     bool success = false;
10605 
10606     if (ConditionPassed(opcode))
10607     {
10608         bool single_regs;
10609         bool add;
10610         bool wback;
10611         uint32_t d;
10612         uint32_t n;
10613         uint32_t imm32;
10614         uint32_t regs;
10615 
10616         switch (encoding)
10617         {
10618             case eEncodingT1:
10619             case eEncodingA1:
10620                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10621                 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10622                 // if P == �1� && W == �0� then SEE VLDR;
10623                 // if P == U && W == �1� then UNDEFINED;
10624                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10625                     return false;
10626 
10627                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10628                 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10629                 single_regs = false;
10630                 add = BitIsSet (opcode, 23);
10631                 wback = BitIsSet (opcode, 21);
10632 
10633                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10634                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10635                 n = Bits32 (opcode, 19, 16);
10636                 imm32 = Bits32 (opcode, 7, 0) << 2;
10637 
10638                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�.
10639                 regs = Bits32 (opcode, 7, 0) / 2;
10640 
10641                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10642                 if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
10643                     return false;
10644 
10645                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10646                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10647                     return false;
10648 
10649                 break;
10650 
10651             case eEncodingT2:
10652             case eEncodingA2:
10653                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10654                 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10655                 // if P == �1� && W == �0� then SEE VLDR;
10656                 // if P == U && W == �1� then UNDEFINED;
10657                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10658                     return false;
10659 
10660                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10661                 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10662                 single_regs = true;
10663                 add = BitIsSet (opcode, 23);
10664                 wback = BitIsSet (opcode, 21);
10665                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10666                 n = Bits32 (opcode, 19, 16);
10667 
10668                 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10669                 imm32 = Bits32 (opcode, 7, 0) << 2;
10670                 regs = Bits32 (opcode, 7, 0);
10671 
10672                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10673                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10674                     return false;
10675 
10676                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10677                 if ((regs == 0) || ((d + regs) > 32))
10678                     return false;
10679                 break;
10680 
10681             default:
10682                 return false;
10683         }
10684 
10685         RegisterInfo base_reg;
10686         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10687 
10688         uint32_t Rn = ReadCoreReg (n, &success);
10689         if (!success)
10690             return false;
10691 
10692         // address = if add then R[n] else R[n]-imm32;
10693         addr_t address;
10694         if (add)
10695             address = Rn;
10696         else
10697             address = Rn - imm32;
10698 
10699         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10700         EmulateInstruction::Context context;
10701 
10702         if (wback)
10703         {
10704             uint32_t value;
10705             if (add)
10706                 value = Rn + imm32;
10707             else
10708                 value = Rn - imm32;
10709 
10710             context.type = eContextAdjustBaseRegister;
10711             context.SetImmediateSigned (value - Rn);
10712             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10713                 return false;
10714 
10715         }
10716 
10717         const uint32_t addr_byte_size = GetAddressByteSize();
10718         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10719 
10720         context.type = eContextRegisterLoad;
10721 
10722         // for r = 0 to regs-1
10723         for (uint32_t r = 0; r < regs; ++r)
10724         {
10725             if (single_regs)
10726             {
10727                 // S[d+r] = MemA[address,4]; address = address+4;
10728                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10729 
10730                 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10731                 if (!success)
10732                     return false;
10733 
10734                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10735                     return false;
10736 
10737                 address = address + 4;
10738             }
10739             else
10740             {
10741                 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10742                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10743                 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10744                 if (!success)
10745                     return false;
10746 
10747                 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10748                 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10749                 if (!success)
10750                     return false;
10751 
10752                 address = address + 8;
10753                 // // Combine the word-aligned words in the correct order for current endianness.
10754                 // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10755                 uint64_t data;
10756                 if (GetByteOrder() == eByteOrderBig)
10757                 {
10758                     data = word1;
10759                     data = (data << 32) | word2;
10760                 }
10761                 else
10762                 {
10763                     data = word2;
10764                     data = (data << 32) | word1;
10765                 }
10766 
10767                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10768                     return false;
10769             }
10770         }
10771     }
10772     return true;
10773 }
10774 
10775 // A8.6.399 VSTM
10776 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an
10777 // ARM core register.
10778 bool
10779 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding)
10780 {
10781 #if 0
10782     if ConditionPassed() then
10783         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10784         address = if add then R[n] else R[n]-imm32;
10785         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10786         for r = 0 to regs-1
10787             if single_regs then
10788                 MemA[address,4] = S[d+r]; address = address+4;
10789             else
10790                 // Store as two word-aligned words in the correct order for current endianness.
10791                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10792                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10793                 address = address+8;
10794 #endif
10795 
10796     bool success = false;
10797 
10798     if (ConditionPassed (opcode))
10799     {
10800         bool single_regs;
10801         bool add;
10802         bool wback;
10803         uint32_t d;
10804         uint32_t n;
10805         uint32_t imm32;
10806         uint32_t regs;
10807 
10808         switch (encoding)
10809         {
10810             case eEncodingT1:
10811             case eEncodingA1:
10812                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10813                 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10814                 // if P == �1� && W == �0� then SEE VSTR;
10815                 // if P == U && W == �1� then UNDEFINED;
10816                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10817                     return false;
10818 
10819                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10820                 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10821                 single_regs = false;
10822                 add = BitIsSet (opcode, 23);
10823                 wback = BitIsSet (opcode, 21);
10824 
10825                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10826                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10827                 n = Bits32 (opcode, 19, 16);
10828                 imm32 = Bits32 (opcode, 7, 0) << 2;
10829 
10830                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�.
10831                 regs = Bits32 (opcode, 7, 0) / 2;
10832 
10833                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10834                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10835                     return false;
10836 
10837                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10838                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10839                     return false;
10840 
10841                 break;
10842 
10843             case eEncodingT2:
10844             case eEncodingA2:
10845                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10846                 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10847                 // if P == �1� && W == �0� then SEE VSTR;
10848                 // if P == U && W == �1� then UNDEFINED;
10849                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10850                     return false;
10851 
10852                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10853                 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10854                 single_regs = true;
10855                 add = BitIsSet (opcode, 23);
10856                 wback = BitIsSet (opcode, 21);
10857                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10858                 n = Bits32 (opcode, 19, 16);
10859 
10860                 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10861                 imm32 = Bits32 (opcode, 7, 0) << 2;
10862                 regs = Bits32 (opcode, 7, 0);
10863 
10864                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10865                 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM)))
10866                     return false;
10867 
10868                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10869                 if ((regs == 0) || ((d + regs) > 32))
10870                     return false;
10871 
10872                 break;
10873 
10874             default:
10875                 return false;
10876         }
10877 
10878         RegisterInfo base_reg;
10879         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10880 
10881         uint32_t Rn = ReadCoreReg (n, &success);
10882         if (!success)
10883             return false;
10884 
10885         // address = if add then R[n] else R[n]-imm32;
10886         addr_t address;
10887         if (add)
10888             address = Rn;
10889         else
10890             address = Rn - imm32;
10891 
10892         EmulateInstruction::Context context;
10893         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10894         if (wback)
10895         {
10896             uint32_t value;
10897             if (add)
10898                 value = Rn + imm32;
10899             else
10900                 value = Rn - imm32;
10901 
10902             context.type = eContextAdjustBaseRegister;
10903             context.SetRegisterPlusOffset (base_reg, value - Rn);
10904 
10905             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10906                 return false;
10907         }
10908 
10909         const uint32_t addr_byte_size = GetAddressByteSize();
10910         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10911 
10912         context.type = eContextRegisterStore;
10913         // for r = 0 to regs-1
10914         for (int r = 0; r < regs; ++r)
10915         {
10916 
10917             if (single_regs)
10918             {
10919                 // MemA[address,4] = S[d+r]; address = address+4;
10920                 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10921                 if (!success)
10922                     return false;
10923 
10924                 RegisterInfo data_reg;
10925                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
10926                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10927                 if (!MemAWrite (context, address, data, addr_byte_size))
10928                     return false;
10929 
10930                 address = address + 4;
10931             }
10932             else
10933             {
10934                 // // Store as two word-aligned words in the correct order for current endianness.
10935                 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10936                 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10937                 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10938                 if (!success)
10939                     return false;
10940 
10941                 RegisterInfo data_reg;
10942                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
10943 
10944                 if (GetByteOrder() == eByteOrderBig)
10945                 {
10946                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10947                     if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
10948                         return false;
10949 
10950                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10951                     if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size))
10952                         return false;
10953                 }
10954                 else
10955                 {
10956                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10957                     if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
10958                         return false;
10959 
10960                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10961                     if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
10962                         return false;
10963                 }
10964                 // address = address+8;
10965                 address = address + 8;
10966             }
10967         }
10968     }
10969     return true;
10970 }
10971 
10972 // A8.6.320
10973 // This instruciton loads a single extension register fronm memory, using an address from an ARM core register, with
10974 // an optional offset.
10975 bool
10976 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
10977 {
10978 #if 0
10979     if ConditionPassed() then
10980         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10981         base = if n == 15 then Align(PC,4) else R[n];
10982         address = if add then (base + imm32) else (base - imm32);
10983         if single_reg then
10984             S[d] = MemA[address,4];
10985         else
10986             word1 = MemA[address,4]; word2 = MemA[address+4,4];
10987             // Combine the word-aligned words in the correct order for current endianness.
10988             D[d] = if BigEndian() then word1:word2 else word2:word1;
10989 #endif
10990 
10991     bool success = false;
10992 
10993     if (ConditionPassed (opcode))
10994     {
10995         bool single_reg;
10996         bool add;
10997         uint32_t imm32;
10998         uint32_t d;
10999         uint32_t n;
11000 
11001         switch (encoding)
11002         {
11003             case eEncodingT1:
11004             case eEncodingA1:
11005                 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11006                 single_reg = false;
11007                 add = BitIsSet (opcode, 23);
11008                 imm32 = Bits32 (opcode, 7, 0) << 2;
11009 
11010                 // d = UInt(D:Vd); n = UInt(Rn);
11011                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11012                 n = Bits32 (opcode, 19, 16);
11013 
11014                 break;
11015 
11016             case eEncodingT2:
11017             case eEncodingA2:
11018                 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11019                 single_reg = true;
11020                 add = BitIsSet (opcode, 23);
11021                 imm32 = Bits32 (opcode, 7, 0) << 2;
11022 
11023                 // d = UInt(Vd:D); n = UInt(Rn);
11024                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11025                 n = Bits32 (opcode, 19, 16);
11026 
11027                 break;
11028 
11029             default:
11030                 return false;
11031         }
11032         RegisterInfo base_reg;
11033         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11034 
11035         uint32_t Rn = ReadCoreReg (n, &success);
11036         if (!success)
11037             return false;
11038 
11039         // base = if n == 15 then Align(PC,4) else R[n];
11040         uint32_t base;
11041         if (n == 15)
11042             base = AlignPC (Rn);
11043         else
11044             base = Rn;
11045 
11046         // address = if add then (base + imm32) else (base - imm32);
11047         addr_t address;
11048         if (add)
11049             address = base + imm32;
11050         else
11051             address = base - imm32;
11052 
11053         const uint32_t addr_byte_size = GetAddressByteSize();
11054         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11055 
11056         EmulateInstruction::Context context;
11057         context.type = eContextRegisterLoad;
11058         context.SetRegisterPlusOffset (base_reg, address - base);
11059 
11060         if (single_reg)
11061         {
11062             // S[d] = MemA[address,4];
11063             uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
11064             if (!success)
11065                 return false;
11066 
11067             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data))
11068                 return false;
11069         }
11070         else
11071         {
11072             // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11073             uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
11074             if (!success)
11075                 return false;
11076 
11077             context.SetRegisterPlusOffset (base_reg, (address + 4) - base);
11078             uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
11079             if (!success)
11080                 return false;
11081             // // Combine the word-aligned words in the correct order for current endianness.
11082             // D[d] = if BigEndian() then word1:word2 else word2:word1;
11083             uint64_t data64;
11084             if (GetByteOrder() == eByteOrderBig)
11085             {
11086                 data64 = word1;
11087                 data64 = (data64 << 32) | word2;
11088             }
11089             else
11090             {
11091                 data64 = word2;
11092                 data64 = (data64 << 32) | word1;
11093             }
11094 
11095             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64))
11096                 return false;
11097         }
11098     }
11099     return true;
11100 }
11101 
11102 // A8.6.400 VSTR
11103 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an
11104 // optional offset.
11105 bool
11106 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
11107 {
11108 #if 0
11109     if ConditionPassed() then
11110         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11111         address = if add then (R[n] + imm32) else (R[n] - imm32);
11112         if single_reg then
11113             MemA[address,4] = S[d];
11114         else
11115             // Store as two word-aligned words in the correct order for current endianness.
11116             MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11117             MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11118 #endif
11119 
11120     bool success = false;
11121 
11122     if (ConditionPassed (opcode))
11123     {
11124         bool single_reg;
11125         bool add;
11126         uint32_t imm32;
11127         uint32_t d;
11128         uint32_t n;
11129 
11130         switch (encoding)
11131         {
11132             case eEncodingT1:
11133             case eEncodingA1:
11134                 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11135                 single_reg = false;
11136                 add = BitIsSet (opcode, 23);
11137                 imm32 = Bits32 (opcode, 7, 0) << 2;
11138 
11139                 // d = UInt(D:Vd); n = UInt(Rn);
11140                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11141                 n = Bits32 (opcode, 19, 16);
11142 
11143                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11144                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11145                     return false;
11146 
11147                 break;
11148 
11149             case eEncodingT2:
11150             case eEncodingA2:
11151                 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11152                 single_reg = true;
11153                 add = BitIsSet (opcode, 23);
11154                 imm32 = Bits32 (opcode, 7, 0) << 2;
11155 
11156                 // d = UInt(Vd:D); n = UInt(Rn);
11157                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11158                 n = Bits32 (opcode, 19, 16);
11159 
11160                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11161                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11162                     return false;
11163 
11164                 break;
11165 
11166             default:
11167                 return false;
11168         }
11169 
11170         RegisterInfo base_reg;
11171         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11172 
11173         uint32_t Rn = ReadCoreReg (n, &success);
11174         if (!success)
11175             return false;
11176 
11177         // address = if add then (R[n] + imm32) else (R[n] - imm32);
11178         addr_t address;
11179         if (add)
11180             address = Rn + imm32;
11181         else
11182             address = Rn - imm32;
11183 
11184         const uint32_t addr_byte_size = GetAddressByteSize();
11185         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11186 
11187         RegisterInfo data_reg;
11188         GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg);
11189         EmulateInstruction::Context context;
11190         context.type = eContextRegisterStore;
11191         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11192 
11193         if (single_reg)
11194         {
11195             // MemA[address,4] = S[d];
11196             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11197             if (!success)
11198                 return false;
11199 
11200             if (!MemAWrite (context, address, data, addr_byte_size))
11201                 return false;
11202         }
11203         else
11204         {
11205             // // Store as two word-aligned words in the correct order for current endianness.
11206             // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11207             // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11208             uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11209             if (!success)
11210                 return false;
11211 
11212             if (GetByteOrder() == eByteOrderBig)
11213             {
11214                 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11215                     return false;
11216 
11217                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11218                 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size))
11219                     return false;
11220             }
11221             else
11222             {
11223                 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11224                     return false;
11225 
11226                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11227                 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11228                     return false;
11229             }
11230         }
11231     }
11232     return true;
11233 }
11234 
11235 // A8.6.307 VLDI1 (multiple single elements)
11236 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving.  Every
11237 // element of each register is loaded.
11238 bool
11239 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding)
11240 {
11241 #if 0
11242     if ConditionPassed() then
11243         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11244         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11245         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11246         for r = 0 to regs-1
11247             for e = 0 to elements-1
11248                 Elem[D[d+r],e,esize] = MemU[address,ebytes];
11249                 address = address + ebytes;
11250 #endif
11251 
11252     bool success = false;
11253 
11254     if (ConditionPassed (opcode))
11255     {
11256         uint32_t regs;
11257         uint32_t alignment;
11258         uint32_t ebytes;
11259         uint32_t esize;
11260         uint32_t elements;
11261         uint32_t d;
11262         uint32_t n;
11263         uint32_t m;
11264         bool wback;
11265         bool register_index;
11266 
11267         switch (encoding)
11268         {
11269             case eEncodingT1:
11270             case eEncodingA1:
11271             {
11272                 // case type of
11273                     // when �0111�
11274                         // regs = 1; if align<1> == �1� then UNDEFINED;
11275                     // when �1010�
11276                         // regs = 2; if align == �11� then UNDEFINED;
11277                     // when �0110�
11278                         // regs = 3; if align<1> == �1� then UNDEFINED;
11279                     // when �0010�
11280                         // regs = 4;
11281                     // otherwise
11282                         // SEE �Related encodings�;
11283                 uint32_t type = Bits32 (opcode, 11, 8);
11284                 uint32_t align = Bits32 (opcode, 5, 4);
11285                 if (type == 7) // '0111'
11286                 {
11287                     regs = 1;
11288                     if (BitIsSet (align, 1))
11289                         return false;
11290                 }
11291                 else if (type == 10) // '1010'
11292                 {
11293                     regs = 2;
11294                     if (align == 3)
11295                         return false;
11296 
11297                 }
11298                 else if (type == 6) // '0110'
11299                 {
11300                     regs = 3;
11301                     if (BitIsSet (align, 1))
11302                         return false;
11303                 }
11304                 else if (type == 2) // '0010'
11305                 {
11306                     regs = 4;
11307                 }
11308                 else
11309                     return false;
11310 
11311                 // alignment = if align == �00� then 1 else 4 << UInt(align);
11312                 if (align == 0)
11313                     alignment = 1;
11314                 else
11315                     alignment = 4 << align;
11316 
11317                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11318                 ebytes = 1 << Bits32 (opcode, 7, 6);
11319                 esize = 8 * ebytes;
11320                 elements = 8 / ebytes;
11321 
11322                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11323                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11324                 n = Bits32 (opcode, 19, 15);
11325                 m = Bits32 (opcode, 3, 0);
11326 
11327                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11328                 wback = (m != 15);
11329                 register_index = ((m != 15) && (m != 13));
11330 
11331                 // if d+regs > 32 then UNPREDICTABLE;
11332                 if ((d + regs) > 32)
11333                     return false;
11334             }
11335                 break;
11336 
11337             default:
11338                 return false;
11339         }
11340 
11341         RegisterInfo base_reg;
11342         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11343 
11344         uint32_t Rn = ReadCoreReg (n, &success);
11345         if (!success)
11346             return false;
11347 
11348         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11349         addr_t address = Rn;
11350         if ((address % alignment) != 0)
11351             return false;
11352 
11353         EmulateInstruction::Context context;
11354         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11355         if (wback)
11356         {
11357             uint32_t Rm = ReadCoreReg (m, &success);
11358             if (!success)
11359                 return false;
11360 
11361             uint32_t offset;
11362             if (register_index)
11363                 offset = Rm;
11364             else
11365                 offset = 8 * regs;
11366 
11367             uint32_t value = Rn + offset;
11368             context.type = eContextAdjustBaseRegister;
11369             context.SetRegisterPlusOffset (base_reg, offset);
11370 
11371             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11372                 return false;
11373 
11374         }
11375 
11376         // for r = 0 to regs-1
11377         for (int r = 0; r < regs; ++r)
11378         {
11379             // for e = 0 to elements-1
11380             uint64_t assembled_data = 0;
11381             for (int e = 0; e < elements; ++e)
11382             {
11383                 // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11384                 context.type = eContextRegisterLoad;
11385                 context.SetRegisterPlusOffset (base_reg, address - Rn);
11386                 uint64_t data = MemURead (context, address, ebytes, 0, &success);
11387                 if (!success)
11388                     return false;
11389 
11390                 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data
11391 
11392                 // address = address + ebytes;
11393                 address = address + ebytes;
11394             }
11395             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data))
11396                 return false;
11397         }
11398     }
11399     return true;
11400 }
11401 
11402 // A8.6.308 VLD1 (single element to one lane)
11403 //
11404 bool
11405 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding)
11406 {
11407 #if 0
11408     if ConditionPassed() then
11409         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11410         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11411         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11412         Elem[D[d],index,esize] = MemU[address,ebytes];
11413 #endif
11414 
11415     bool success = false;
11416 
11417     if (ConditionPassed (opcode))
11418     {
11419         uint32_t ebytes;
11420         uint32_t esize;
11421         uint32_t index;
11422         uint32_t alignment;
11423         uint32_t d;
11424         uint32_t n;
11425         uint32_t m;
11426         bool wback;
11427         bool register_index;
11428 
11429         switch (encoding)
11430         {
11431             case eEncodingT1:
11432             case eEncodingA1:
11433             {
11434                 uint32_t size = Bits32 (opcode, 11, 10);
11435                 uint32_t index_align = Bits32 (opcode, 7, 4);
11436                 // if size == �11� then SEE VLD1 (single element to all lanes);
11437                 if (size == 3)
11438                    return EmulateVLD1SingleAll (opcode, encoding);
11439                 // case size of
11440                 if (size == 0) // when '00'
11441                 {
11442                     // if index_align<0> != �0� then UNDEFINED;
11443                     if (BitIsClear (index_align, 0))
11444                         return false;
11445 
11446                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11447                     ebytes = 1;
11448                     esize = 8;
11449                     index = Bits32 (index_align, 3, 1);
11450                     alignment = 1;
11451                 }
11452                 else if (size == 1) // when �01�
11453                 {
11454                     // if index_align<1> != �0� then UNDEFINED;
11455                     if (BitIsClear (index_align, 1))
11456                         return false;
11457 
11458                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11459                     ebytes = 2;
11460                     esize = 16;
11461                     index = Bits32 (index_align, 3, 2);
11462 
11463                     // alignment = if index_align<0> == �0� then 1 else 2;
11464                     if (BitIsClear (index_align, 0))
11465                         alignment = 1;
11466                     else
11467                         alignment = 2;
11468                 }
11469                 else if (size == 2) // when �10�
11470                 {
11471                     // if index_align<2> != �0� then UNDEFINED;
11472                     if (BitIsClear (index_align, 2))
11473                         return false;
11474 
11475                     // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11476                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11477                         return false;
11478 
11479                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11480                     ebytes = 4;
11481                     esize = 32;
11482                     index = Bit32 (index_align, 3);
11483 
11484                     // alignment = if index_align<1:0> == �00� then 1 else 4;
11485                     if (Bits32 (index_align, 1, 0) == 0)
11486                         alignment = 1;
11487                     else
11488                         alignment = 4;
11489                 }
11490                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11491                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11492                 n = Bits32 (opcode, 19, 16);
11493                 m = Bits32 (opcode, 3, 0);
11494 
11495                 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
11496                 wback = (m != 15);
11497                 register_index = ((m != 15) && (m != 13));
11498 
11499                 if (n == 15)
11500                     return false;
11501 
11502             }
11503                 break;
11504 
11505             default:
11506                 return false;
11507         }
11508 
11509         RegisterInfo base_reg;
11510         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11511 
11512         uint32_t Rn = ReadCoreReg (n, &success);
11513         if (!success)
11514             return false;
11515 
11516         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11517         addr_t address = Rn;
11518         if ((address % alignment) != 0)
11519             return false;
11520 
11521         EmulateInstruction::Context context;
11522         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11523         if (wback)
11524         {
11525             uint32_t Rm = ReadCoreReg (m, &success);
11526             if (!success)
11527                 return false;
11528 
11529             uint32_t offset;
11530             if (register_index)
11531                 offset = Rm;
11532             else
11533                 offset = ebytes;
11534 
11535             uint32_t value = Rn + offset;
11536 
11537             context.type = eContextAdjustBaseRegister;
11538             context.SetRegisterPlusOffset (base_reg, offset);
11539 
11540             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11541                 return false;
11542         }
11543 
11544         // Elem[D[d],index,esize] = MemU[address,ebytes];
11545         uint32_t element = MemURead (context, address, esize, 0, &success);
11546         if (!success)
11547             return false;
11548 
11549         element = element << (index * esize);
11550 
11551         uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11552         if (!success)
11553             return false;
11554 
11555         uint64_t all_ones = -1;
11556         uint64_t mask = all_ones << ((index+1) * esize);  // mask is all 1's to left of where 'element' goes, & all 0's
11557                                                           // at element & to the right of element.
11558         if (index > 0)
11559             mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes.
11560                                                                      // now mask should be 0's where element goes & 1's
11561                                                                      // everywhere else.
11562 
11563         uint64_t masked_reg = reg_data & mask;  // Take original reg value & zero out 'element' bits
11564         reg_data = masked_reg & element;        // Put 'element' into those bits in reg_data.
11565 
11566         context.type = eContextRegisterLoad;
11567         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data))
11568             return false;
11569     }
11570     return true;
11571 }
11572 
11573 // A8.6.391 VST1 (multiple single elements)
11574 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four regsiters, without
11575 // interleaving.  Every element of each register is stored.
11576 bool
11577 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding)
11578 {
11579 #if 0
11580     if ConditionPassed() then
11581         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11582         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11583         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11584         for r = 0 to regs-1
11585             for e = 0 to elements-1
11586                 MemU[address,ebytes] = Elem[D[d+r],e,esize];
11587                 address = address + ebytes;
11588 #endif
11589 
11590     bool success = false;
11591 
11592     if (ConditionPassed (opcode))
11593     {
11594         uint32_t regs;
11595         uint32_t alignment;
11596         uint32_t ebytes;
11597         uint32_t esize;
11598         uint32_t elements;
11599         uint32_t d;
11600         uint32_t n;
11601         uint32_t m;
11602         bool wback;
11603         bool register_index;
11604 
11605         switch (encoding)
11606         {
11607             case eEncodingT1:
11608             case eEncodingA1:
11609             {
11610                 uint32_t type = Bits32 (opcode, 11, 8);
11611                 uint32_t align = Bits32 (opcode, 5, 4);
11612 
11613                 // case type of
11614                 if (type == 7)    // when �0111�
11615                 {
11616                     // regs = 1; if align<1> == �1� then UNDEFINED;
11617                     regs = 1;
11618                     if (BitIsSet (align, 1))
11619                         return false;
11620                 }
11621                 else if (type == 10) // when �1010�
11622                 {
11623                     // regs = 2; if align == �11� then UNDEFINED;
11624                     regs = 2;
11625                     if (align == 3)
11626                         return false;
11627                 }
11628                 else if (type == 6) // when �0110�
11629                 {
11630                     // regs = 3; if align<1> == �1� then UNDEFINED;
11631                     regs = 3;
11632                     if (BitIsSet (align, 1))
11633                         return false;
11634                 }
11635                 else if (type == 2) // when �0010�
11636                     // regs = 4;
11637                     regs = 4;
11638                 else // otherwise
11639                     // SEE �Related encodings�;
11640                     return false;
11641 
11642                 // alignment = if align == �00� then 1 else 4 << UInt(align);
11643                 if (align == 0)
11644                     alignment = 1;
11645                 else
11646                     alignment = 4 << align;
11647 
11648                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11649                 ebytes = 1 << Bits32 (opcode,7, 6);
11650                 esize = 8 * ebytes;
11651                 elements = 8 / ebytes;
11652 
11653                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11654                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11655                 n = Bits32 (opcode, 19, 16);
11656                 m = Bits32 (opcode, 3, 0);
11657 
11658                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11659                 wback = (m != 15);
11660                 register_index = ((m != 15) && (m != 13));
11661 
11662                 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11663                 if ((d + regs) > 32)
11664                     return false;
11665 
11666                 if (n == 15)
11667                     return false;
11668 
11669             }
11670                 break;
11671 
11672             default:
11673                 return false;
11674         }
11675 
11676         RegisterInfo base_reg;
11677         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11678 
11679         uint32_t Rn = ReadCoreReg (n, &success);
11680         if (!success)
11681             return false;
11682 
11683         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11684         addr_t address = Rn;
11685         if ((address % alignment) != 0)
11686             return false;
11687 
11688         EmulateInstruction::Context context;
11689         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11690         if (wback)
11691         {
11692             uint32_t Rm = ReadCoreReg (m, &success);
11693             if (!success)
11694                 return false;
11695 
11696             uint32_t offset;
11697             if (register_index)
11698                 offset = Rm;
11699             else
11700                 offset = 8 * regs;
11701 
11702             context.type = eContextAdjustBaseRegister;
11703             context.SetRegisterPlusOffset (base_reg, offset);
11704 
11705             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11706                 return false;
11707         }
11708 
11709         RegisterInfo data_reg;
11710         context.type = eContextRegisterStore;
11711         // for r = 0 to regs-1
11712         for (int r = 0; r < regs; ++r)
11713         {
11714             GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
11715             uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
11716             if (!success)
11717                 return false;
11718 
11719              // for e = 0 to elements-1
11720             for (int e = 0; e < elements; ++e)
11721             {
11722                 // MemU[address,ebytes] = Elem[D[d+r],e,esize];
11723                 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize);
11724 
11725                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11726                 if (!MemUWrite (context, address, word, ebytes))
11727                     return false;
11728 
11729                 // address = address + ebytes;
11730                 address = address + ebytes;
11731             }
11732         }
11733     }
11734     return true;
11735 }
11736 
11737 // A8.6.392 VST1 (single element from one lane)
11738 // This instruction stores one element to memory from one element of a register.
11739 bool
11740 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding)
11741 {
11742 #if 0
11743     if ConditionPassed() then
11744         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11745         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11746         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11747         MemU[address,ebytes] = Elem[D[d],index,esize];
11748 #endif
11749 
11750     bool success = false;
11751 
11752     if (ConditionPassed (opcode))
11753     {
11754         uint32_t ebytes;
11755         uint32_t esize;
11756         uint32_t index;
11757         uint32_t alignment;
11758         uint32_t d;
11759         uint32_t n;
11760         uint32_t m;
11761         bool wback;
11762         bool register_index;
11763 
11764         switch (encoding)
11765         {
11766             case eEncodingT1:
11767             case eEncodingA1:
11768             {
11769                 uint32_t size = Bits32 (opcode, 11, 10);
11770                 uint32_t index_align = Bits32 (opcode, 7, 4);
11771 
11772                 // if size == �11� then UNDEFINED;
11773                 if (size == 3)
11774                     return false;
11775 
11776                 // case size of
11777                 if (size == 0) // when �00�
11778                 {
11779                     // if index_align<0> != �0� then UNDEFINED;
11780                     if (BitIsClear (index_align, 0))
11781                         return false;
11782                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11783                     ebytes = 1;
11784                     esize = 8;
11785                     index = Bits32 (index_align, 3, 1);
11786                     alignment = 1;
11787                 }
11788                 else if (size == 1) // when �01�
11789                 {
11790                     // if index_align<1> != �0� then UNDEFINED;
11791                     if (BitIsClear (index_align, 1))
11792                         return false;
11793 
11794                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11795                     ebytes = 2;
11796                     esize = 16;
11797                     index = Bits32 (index_align, 3, 2);
11798 
11799                     // alignment = if index_align<0> == �0� then 1 else 2;
11800                     if (BitIsClear (index_align, 0))
11801                         alignment = 1;
11802                     else
11803                         alignment = 2;
11804                 }
11805                 else if (size == 2) // when �10�
11806                 {
11807                     // if index_align<2> != �0� then UNDEFINED;
11808                     if (BitIsClear (index_align, 2))
11809                         return false;
11810 
11811                     // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11812                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11813                         return false;
11814 
11815                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11816                     ebytes = 4;
11817                     esize = 32;
11818                     index = Bit32 (index_align, 3);
11819 
11820                     // alignment = if index_align<1:0> == �00� then 1 else 4;
11821                     if (Bits32 (index_align, 1, 0) == 0)
11822                         alignment = 1;
11823                     else
11824                         alignment = 4;
11825                 }
11826                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11827                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11828                 n = Bits32 (opcode, 19, 16);
11829                 m = Bits32 (opcode, 3, 0);
11830 
11831                 // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15 then UNPREDICTABLE;
11832                 wback = (m != 15);
11833                 register_index = ((m != 15) && (m != 13));
11834 
11835                 if (n == 15)
11836                     return false;
11837             }
11838                 break;
11839 
11840             default:
11841                 return false;
11842         }
11843 
11844         RegisterInfo base_reg;
11845         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11846 
11847         uint32_t Rn = ReadCoreReg (n, &success);
11848         if (!success)
11849             return false;
11850 
11851         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11852         addr_t address = Rn;
11853         if ((address % alignment) != 0)
11854             return false;
11855 
11856         EmulateInstruction::Context context;
11857         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11858         if (wback)
11859         {
11860             uint32_t Rm = ReadCoreReg (m, &success);
11861             if (!success)
11862                 return false;
11863 
11864             uint32_t offset;
11865             if (register_index)
11866                 offset = Rm;
11867             else
11868                 offset = ebytes;
11869 
11870             context.type = eContextAdjustBaseRegister;
11871             context.SetRegisterPlusOffset (base_reg, offset);
11872 
11873             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11874                 return false;
11875         }
11876 
11877         // MemU[address,ebytes] = Elem[D[d],index,esize];
11878         uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11879         if (!success)
11880             return false;
11881 
11882         uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1,  index * esize);
11883 
11884         RegisterInfo data_reg;
11885         GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg);
11886         context.type = eContextRegisterStore;
11887         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11888 
11889         if (!MemUWrite (context, address, word, ebytes))
11890             return false;
11891     }
11892     return true;
11893 }
11894 
11895 // A8.6.309 VLD1 (single element to all lanes)
11896 // This instruction loads one element from memory into every element of one or two vectors.
11897 bool
11898 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding)
11899 {
11900 #if 0
11901     if ConditionPassed() then
11902         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11903         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11904         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11905         replicated_element = Replicate(MemU[address,ebytes], elements);
11906         for r = 0 to regs-1
11907             D[d+r] = replicated_element;
11908 #endif
11909 
11910     bool success = false;
11911 
11912     if (ConditionPassed (opcode))
11913     {
11914         uint32_t ebytes;
11915         uint32_t elements;
11916         uint32_t regs;
11917         uint32_t alignment;
11918         uint32_t d;
11919         uint32_t n;
11920         uint32_t m;
11921         bool wback;
11922         bool register_index;
11923 
11924         switch (encoding)
11925         {
11926             case eEncodingT1:
11927             case eEncodingA1:
11928             {
11929                 //if size == �11� || (size == �00� && a == �1�) then UNDEFINED;
11930                 uint32_t size = Bits32 (opcode, 7, 6);
11931                 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4)))
11932                     return false;
11933 
11934                 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2;
11935                 ebytes = 1 << size;
11936                 elements = 8 / ebytes;
11937                 if (BitIsClear (opcode, 5))
11938                     regs = 1;
11939                 else
11940                     regs = 2;
11941 
11942                 //alignment = if a == �0� then 1 else ebytes;
11943                 if (BitIsClear (opcode, 4))
11944                     alignment = 1;
11945                 else
11946                     alignment = ebytes;
11947 
11948                 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11949                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11950                 n = Bits32 (opcode, 19, 16);
11951                 m = Bits32 (opcode, 3, 0);
11952 
11953                 //wback = (m != 15); register_index = (m != 15 && m != 13);
11954                 wback = (m != 15);
11955                 register_index = ((m != 15) && (m != 13));
11956 
11957                 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11958                 if ((d + regs) > 32)
11959                     return false;
11960 
11961                 if (n == 15)
11962                     return false;
11963             }
11964             break;
11965 
11966             default:
11967                 return false;
11968         }
11969 
11970         RegisterInfo base_reg;
11971         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11972 
11973         uint32_t Rn = ReadCoreReg (n, &success);
11974         if (!success)
11975             return false;
11976 
11977         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11978         addr_t address = Rn;
11979         if ((address % alignment) != 0)
11980             return false;
11981 
11982         EmulateInstruction::Context context;
11983         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11984         if (wback)
11985         {
11986             uint32_t Rm = ReadCoreReg (m, &success);
11987             if (!success)
11988                 return false;
11989 
11990             uint32_t offset;
11991             if (register_index)
11992                 offset = Rm;
11993             else
11994                 offset = ebytes;
11995 
11996             context.type = eContextAdjustBaseRegister;
11997             context.SetRegisterPlusOffset (base_reg, offset);
11998 
11999             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
12000                 return false;
12001         }
12002 
12003         // replicated_element = Replicate(MemU[address,ebytes], elements);
12004 
12005         context.type = eContextRegisterLoad;
12006         uint64_t word = MemURead (context, address, ebytes, 0, &success);
12007         if (!success)
12008             return false;
12009 
12010         uint64_t replicated_element = 0;
12011         uint32_t esize = ebytes * 8;
12012         for (int e = 0; e < elements; ++e)
12013             replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0);
12014 
12015         // for r = 0 to regs-1
12016         for (int r = 0; r < regs; ++r)
12017         {
12018             // D[d+r] = replicated_element;
12019             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element))
12020                 return false;
12021         }
12022     }
12023     return true;
12024 }
12025 
12026 // B6.2.13 SUBS PC, LR and related instructions
12027 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack.  It subtracts the
12028 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR.
12029 bool
12030 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding)
12031 {
12032 #if 0
12033     if ConditionPassed() then
12034         EncodingSpecificOperations();
12035         if CurrentInstrSet() == InstrSet_ThumbEE then
12036             UNPREDICTABLE;
12037         operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12038         case opcode of
12039             when �0000� result = R[n] AND operand2; // AND
12040             when �0001� result = R[n] EOR operand2; // EOR
12041             when �0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12042             when �0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12043             when �0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12044             when �0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12045             when �0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12046             when �0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12047             when �1100� result = R[n] OR operand2; // ORR
12048             when �1101� result = operand2; // MOV
12049             when �1110� result = R[n] AND NOT(operand2); // BIC
12050             when �1111� result = NOT(operand2); // MVN
12051         CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12052         BranchWritePC(result);
12053 #endif
12054 
12055     bool success = false;
12056 
12057     if (ConditionPassed (opcode))
12058     {
12059         uint32_t n;
12060         uint32_t m;
12061         uint32_t imm32;
12062         bool register_form;
12063         ARM_ShifterType shift_t;
12064         uint32_t shift_n;
12065         uint32_t code;
12066 
12067         switch (encoding)
12068         {
12069             case eEncodingT1:
12070                 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
12071                 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB
12072                 n = 14;
12073                 imm32 = Bits32 (opcode, 7, 0);
12074                 register_form = false;
12075                 code = 2;
12076 
12077                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12078                 if (InITBlock() && !LastInITBlock())
12079                     return false;
12080 
12081                 break;
12082 
12083             case eEncodingA1:
12084                 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12085                 n = Bits32 (opcode, 19, 16);
12086                 imm32 = ARMExpandImm (opcode);
12087                 register_form = false;
12088                 code = Bits32 (opcode, 24, 21);
12089 
12090                 break;
12091 
12092             case eEncodingA2:
12093                 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12094                 n = Bits32 (opcode, 19, 16);
12095                 m = Bits32 (opcode, 3, 0);
12096                 register_form = true;
12097 
12098                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12099                 shift_n = DecodeImmShiftARM (opcode, shift_t);
12100 
12101                 break;
12102 
12103             default:
12104                 return false;
12105         }
12106 
12107         // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12108         uint32_t operand2;
12109         if (register_form)
12110         {
12111             uint32_t Rm = ReadCoreReg (m, &success);
12112             if (!success)
12113                 return false;
12114 
12115             operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success);
12116             if (!success)
12117                 return false;
12118         }
12119         else
12120         {
12121             operand2 = imm32;
12122         }
12123 
12124         uint32_t Rn = ReadCoreReg (n, &success);
12125         if (!success)
12126             return false;
12127 
12128         AddWithCarryResult result;
12129 
12130         // case opcode of
12131         switch (code)
12132         {
12133             case 0: // when �0000�
12134                 // result = R[n] AND operand2; // AND
12135                 result.result = Rn & operand2;
12136                 break;
12137 
12138             case 1: // when �0001�
12139                 // result = R[n] EOR operand2; // EOR
12140                 result.result = Rn ^ operand2;
12141                 break;
12142 
12143             case 2: // when �0010�
12144                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12145                 result = AddWithCarry (Rn, ~(operand2), 1);
12146                 break;
12147 
12148             case 3: // when �0011�
12149                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12150                 result = AddWithCarry (~(Rn), operand2, 1);
12151                 break;
12152 
12153             case 4: // when �0100�
12154                 // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12155                 result = AddWithCarry (Rn, operand2, 0);
12156                 break;
12157 
12158             case 5: // when �0101�
12159                 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12160                 result = AddWithCarry (Rn, operand2, APSR_C);
12161                 break;
12162 
12163             case 6: // when �0110�
12164                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12165                 result = AddWithCarry (Rn, ~(operand2), APSR_C);
12166                 break;
12167 
12168             case 7: // when �0111�
12169                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12170                 result = AddWithCarry (~(Rn), operand2, APSR_C);
12171                 break;
12172 
12173             case 10: // when �1100�
12174                 // result = R[n] OR operand2; // ORR
12175                 result.result = Rn | operand2;
12176                 break;
12177 
12178             case 11: // when �1101�
12179                 // result = operand2; // MOV
12180                 result.result = operand2;
12181                 break;
12182 
12183             case 12: // when �1110�
12184                 // result = R[n] AND NOT(operand2); // BIC
12185                 result.result = Rn & ~(operand2);
12186                 break;
12187 
12188             case 15: // when �1111�
12189                 // result = NOT(operand2); // MVN
12190                 result.result = ~(operand2);
12191                 break;
12192 
12193             default:
12194                 return false;
12195         }
12196         // CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12197 
12198         // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for
12199         // the best.
12200         uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12201         if (!success)
12202             return false;
12203 
12204         CPSRWriteByInstr (spsr, 15, true);
12205 
12206         // BranchWritePC(result);
12207         EmulateInstruction::Context context;
12208         context.type = eContextAdjustPC;
12209         context.SetImmediate (result.result);
12210 
12211         BranchWritePC (context, result.result);
12212     }
12213     return true;
12214 }
12215 
12216 EmulateInstructionARM::ARMOpcode*
12217 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12218 {
12219     static ARMOpcode
12220     g_arm_opcodes[] =
12221     {
12222         //----------------------------------------------------------------------
12223         // Prologue instructions
12224         //----------------------------------------------------------------------
12225 
12226         // push register(s)
12227         { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12228         { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
12229 
12230         // set r7 to point to a stack offset
12231         { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
12232         { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12233         // copy the stack pointer to ip
12234         { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
12235         { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
12236         { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12237 
12238         // adjust the stack pointer
12239         { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12240         { 0x0fef0010, 0x004d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12241 
12242         // push one register
12243         // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12244         { 0x0e5f0000, 0x040d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
12245 
12246         // vector push consecutive extension register(s)
12247         { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12248         { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12249 
12250         //----------------------------------------------------------------------
12251         // Epilogue instructions
12252         //----------------------------------------------------------------------
12253 
12254         { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12255         { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12256         { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12257         { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12258 
12259         //----------------------------------------------------------------------
12260         // Supervisor Call (previously Software Interrupt)
12261         //----------------------------------------------------------------------
12262         { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12263 
12264         //----------------------------------------------------------------------
12265         // Branch instructions
12266         //----------------------------------------------------------------------
12267         { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
12268         // To resolve ambiguity, "blx <label>" should come before "bl <label>".
12269         { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12270         { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12271         { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12272         // for example, "bx lr"
12273         { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12274         // bxj
12275         { 0x0ffffff0, 0x012fff20, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12276 
12277         //----------------------------------------------------------------------
12278         // Data-processing instructions
12279         //----------------------------------------------------------------------
12280         // adc (immediate)
12281         { 0x0fe00000, 0x02a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12282         // adc (register)
12283         { 0x0fe00010, 0x00a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12284         // add (immediate)
12285         { 0x0fe00000, 0x02800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
12286         // add (register)
12287         { 0x0fe00010, 0x00800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12288         // add (register-shifted register)
12289         { 0x0fe00090, 0x00800010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12290         // adr
12291         { 0x0fff0000, 0x028f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12292         { 0x0fff0000, 0x024f0000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12293         // and (immediate)
12294         { 0x0fe00000, 0x02000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12295         // and (register)
12296         { 0x0fe00010, 0x00000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12297         // bic (immediate)
12298         { 0x0fe00000, 0x03c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12299         // bic (register)
12300         { 0x0fe00010, 0x01c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12301         // eor (immediate)
12302         { 0x0fe00000, 0x02200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12303         // eor (register)
12304         { 0x0fe00010, 0x00200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12305         // orr (immediate)
12306         { 0x0fe00000, 0x03800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12307         // orr (register)
12308         { 0x0fe00010, 0x01800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12309         // rsb (immediate)
12310         { 0x0fe00000, 0x02600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12311         // rsb (register)
12312         { 0x0fe00010, 0x00600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12313         // rsc (immediate)
12314         { 0x0fe00000, 0x02e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12315         // rsc (register)
12316         { 0x0fe00010, 0x00e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12317         // sbc (immediate)
12318         { 0x0fe00000, 0x02c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12319         // sbc (register)
12320         { 0x0fe00010, 0x00c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12321         // sub (immediate, ARM)
12322         { 0x0fe00000, 0x02400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
12323         // sub (sp minus immediate)
12324         { 0x0fef0000, 0x024d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12325         // sub (register)
12326         { 0x0fe00010, 0x00400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12327         // teq (immediate)
12328         { 0x0ff0f000, 0x03300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12329         // teq (register)
12330         { 0x0ff0f010, 0x01300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12331         // tst (immediate)
12332         { 0x0ff0f000, 0x03100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12333         // tst (register)
12334         { 0x0ff0f010, 0x01100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12335 
12336         // mov (immediate)
12337         { 0x0fef0000, 0x03a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12338         { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
12339         // mov (register)
12340         { 0x0fef0ff0, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12341         // mvn (immediate)
12342         { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12343         // mvn (register)
12344         { 0x0fef0010, 0x01e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12345         // cmn (immediate)
12346         { 0x0ff0f000, 0x03700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12347         // cmn (register)
12348         { 0x0ff0f010, 0x01700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12349         // cmp (immediate)
12350         { 0x0ff0f000, 0x03500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
12351         // cmp (register)
12352         { 0x0ff0f010, 0x01500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
12353         // asr (immediate)
12354         { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
12355         // asr (register)
12356         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
12357         // lsl (immediate)
12358         { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
12359         // lsl (register)
12360         { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
12361         // lsr (immediate)
12362         { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
12363         // lsr (register)
12364         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
12365         // rrx is a special case encoding of ror (immediate)
12366         { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
12367         // ror (immediate)
12368         { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
12369         // ror (register)
12370         { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
12371         // mul
12372         { 0x0fe000f0, 0x00000090, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
12373 
12374         // subs pc, lr and related instructions
12375         { 0x0e10f000, 0x0210f000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" },
12376         { 0x0e10f010, 0x0010f000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" },
12377 
12378         //----------------------------------------------------------------------
12379         // Load instructions
12380         //----------------------------------------------------------------------
12381         { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12382         { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
12383         { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12384         { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
12385         { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
12386         { 0x0e500010, 0x06100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
12387         { 0x0e5f0000, 0x045f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
12388         { 0xfe500010, 0x06500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
12389         { 0x0e5f00f0, 0x005f00b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12390         { 0x0e5000f0, 0x001000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"  },
12391         { 0x0e5000f0, 0x005000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
12392         { 0x0e5f00f0, 0x005f00d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
12393         { 0x0e5000f0, 0x001000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12394         { 0x0e5000f0, 0x005000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
12395         { 0x0e5f00f0, 0x005f00f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12396         { 0x0e5000f0, 0x001000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12397         { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
12398         { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12399         { 0x0e100f00, 0x0c100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12400         { 0x0e100f00, 0x0c100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12401         { 0x0f300f00, 0x0d100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12402         { 0x0f300f00, 0x0d100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12403         { 0xffb00000, 0xf4200000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12404         { 0xffb00300, 0xf4a00000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12405         { 0xffb00f00, 0xf4a00c00, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12406 
12407         //----------------------------------------------------------------------
12408         // Store instructions
12409         //----------------------------------------------------------------------
12410         { 0x0fd00000, 0x08800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12411         { 0x0fd00000, 0x08000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
12412         { 0x0fd00000, 0x09000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12413         { 0x0fd00000, 0x09800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
12414         { 0x0e500010, 0x06000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
12415         { 0x0e5000f0, 0x000000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
12416         { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
12417         { 0x0e500000, 0x04400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12418         { 0x0e500000, 0x04000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12419         { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
12420         { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12421         { 0x0e100f00, 0x0c000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12422         { 0x0e100f00, 0x0c000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12423         { 0x0f300f00, 0x0d000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
12424         { 0x0f300f00, 0x0d000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
12425         { 0xffb00000, 0xf4000000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12426         { 0xffb00300, 0xf4800000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12427 
12428         //----------------------------------------------------------------------
12429         // Other instructions
12430         //----------------------------------------------------------------------
12431         { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
12432         { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
12433         { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
12434         { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
12435         { 0xfe500000, 0xf8100000, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
12436 
12437     };
12438     static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode);
12439 
12440     for (size_t i=0; i<k_num_arm_opcodes; ++i)
12441     {
12442         if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
12443             (g_arm_opcodes[i].variants & arm_isa) != 0)
12444             return &g_arm_opcodes[i];
12445     }
12446     return NULL;
12447 }
12448 
12449 
12450 EmulateInstructionARM::ARMOpcode*
12451 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12452 {
12453 
12454     static ARMOpcode
12455     g_thumb_opcodes[] =
12456     {
12457         //----------------------------------------------------------------------
12458         // Prologue instructions
12459         //----------------------------------------------------------------------
12460 
12461         // push register(s)
12462         { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12463         { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
12464         { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
12465 
12466         // set r7 to point to a stack offset
12467         { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
12468         // copy the stack pointer to r7
12469         { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
12470         // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
12471         { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
12472 
12473         // PC-relative load into register (see also EmulateADDSPRm)
12474         { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
12475 
12476         // adjust the stack pointer
12477         { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
12478         { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
12479         { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
12480         { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
12481         { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12482 
12483         // vector push consecutive extension register(s)
12484         { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12485         { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12486 
12487         //----------------------------------------------------------------------
12488         // Epilogue instructions
12489         //----------------------------------------------------------------------
12490 
12491         { 0xfffff800, 0x0000a800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
12492         { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
12493         { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12494         { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
12495         { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
12496         { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12497         { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12498 
12499         //----------------------------------------------------------------------
12500         // Supervisor Call (previously Software Interrupt)
12501         //----------------------------------------------------------------------
12502         { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
12503 
12504         //----------------------------------------------------------------------
12505         // If Then makes up to four following instructions conditional.
12506         //----------------------------------------------------------------------
12507         // The next 5 opcode _must_ come before the if then instruction
12508         { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"},
12509         { 0xffffffff, 0x0000bf10, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
12510         { 0xffffffff, 0x0000bf20, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
12511         { 0xffffffff, 0x0000bf30, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
12512         { 0xffffffff, 0x0000bf40, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
12513         { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
12514 
12515         //----------------------------------------------------------------------
12516         // Branch instructions
12517         //----------------------------------------------------------------------
12518         // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
12519         { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
12520         { 0xfffff800, 0x0000e000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
12521         { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
12522         { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
12523         // J1 == J2 == 1
12524         { 0xf800d000, 0xf000d000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12525         // J1 == J2 == 1
12526         { 0xf800d001, 0xf000c000, ARMV5_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12527         { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12528         // for example, "bx lr"
12529         { 0xffffff87, 0x00004700, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12530         // bxj
12531         { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12532         // compare and branch
12533         { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
12534         // table branch byte
12535         { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
12536         // table branch halfword
12537         { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
12538 
12539         //----------------------------------------------------------------------
12540         // Data-processing instructions
12541         //----------------------------------------------------------------------
12542         // adc (immediate)
12543         { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
12544         // adc (register)
12545         { 0xffffffc0, 0x00004140, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
12546         { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12547         // add (register)
12548         { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
12549         // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
12550         { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
12551         // adr
12552         { 0xfffff800, 0x0000a000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12553         { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12554         { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12555         // and (immediate)
12556         { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
12557         // and (register)
12558         { 0xffffffc0, 0x00004000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
12559         { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12560         // bic (immediate)
12561         { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
12562         // bic (register)
12563         { 0xffffffc0, 0x00004380, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
12564         { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12565         // eor (immediate)
12566         { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
12567         // eor (register)
12568         { 0xffffffc0, 0x00004040, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
12569         { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12570         // orr (immediate)
12571         { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
12572         // orr (register)
12573         { 0xffffffc0, 0x00004300, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
12574         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12575         // rsb (immediate)
12576         { 0xffffffc0, 0x00004240, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
12577         { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
12578         // rsb (register)
12579         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12580         // sbc (immediate)
12581         { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12582         // sbc (register)
12583         { 0xffffffc0, 0x00004180, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
12584         { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12585         // add (immediate, Thumb)
12586         { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
12587         { 0xfffff800, 0x00003000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
12588         { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
12589         { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
12590         // sub (immediate, Thumb)
12591         { 0xfffffe00, 0x00001e00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
12592         { 0xfffff800, 0x00003800, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
12593         { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
12594         { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
12595         // sub (sp minus immediate)
12596         { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
12597         { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
12598         // sub (register)
12599         { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
12600         { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
12601         // teq (immediate)
12602         { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
12603         // teq (register)
12604         { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12605         // tst (immediate)
12606         { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
12607         // tst (register)
12608         { 0xffffffc0, 0x00004200, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
12609         { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
12610 
12611 
12612         // move from high register to high register
12613         { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
12614         // move from low register to low register
12615         { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
12616         // mov{s}<c>.w <Rd>, <Rm>
12617         { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
12618         // move immediate
12619         { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
12620         { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
12621         { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
12622         // mvn (immediate)
12623         { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
12624         // mvn (register)
12625         { 0xffffffc0, 0x000043c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
12626         { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
12627         // cmn (immediate)
12628         { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12629         // cmn (register)
12630         { 0xffffffc0, 0x000042c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
12631         { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12632         // cmp (immediate)
12633         { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
12634         { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
12635         // cmp (register) (Rn and Rm both from r0-r7)
12636         { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12637         // cmp (register) (Rn and Rm not both from r0-r7)
12638         { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12639         // asr (immediate)
12640         { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
12641         { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
12642         // asr (register)
12643         { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
12644         { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12645         // lsl (immediate)
12646         { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
12647         { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
12648         // lsl (register)
12649         { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
12650         { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
12651         // lsr (immediate)
12652         { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
12653         { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
12654         // lsr (register)
12655         { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
12656         { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12657         // rrx is a special case encoding of ror (immediate)
12658         { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
12659         // ror (immediate)
12660         { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
12661         // ror (register)
12662         { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
12663         { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
12664         // mul
12665         { 0xffffffc0, 0x00004340, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
12666         // mul
12667         { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
12668 
12669         // subs pc, lr and related instructions
12670         { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" },
12671 
12672         //----------------------------------------------------------------------
12673         // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table;
12674         // otherwise the wrong instructions will be selected.
12675         //----------------------------------------------------------------------
12676 
12677         { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
12678         { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
12679 
12680         //----------------------------------------------------------------------
12681         // Load instructions
12682         //----------------------------------------------------------------------
12683         { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12684         { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
12685         { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12686         { 0xfffff800, 0x00006800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
12687         { 0xfffff800, 0x00009800, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
12688         { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
12689         { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
12690                   // Thumb2 PC-relative load into register
12691         { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
12692         { 0xfffffe00, 0x00005800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
12693         { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
12694         { 0xfffff800, 0x00007800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
12695         { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12696         { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" },
12697         { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
12698         { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
12699         { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
12700         { 0xfffff800, 0x00008800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"  },
12701         { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12702         { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"  },
12703         { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12704         { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
12705         { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12706         { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
12707         { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12708         { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
12709         { 0xfffffe00, 0x00005600, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
12710         { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"  },
12711         { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
12712         { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12713         { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12714         { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
12715         { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12716         { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
12717         { 0xfe100f00, 0xec100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12718         { 0xfe100f00, 0xec100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
12719         { 0xffe00f00, 0xed100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12720         { 0xff300f00, 0xed100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
12721         { 0xffb00000, 0xf9200000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12722         { 0xffb00300, 0xf9a00000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12723         { 0xffb00f00, 0xf9a00c00, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12724 
12725         //----------------------------------------------------------------------
12726         // Store instructions
12727         //----------------------------------------------------------------------
12728         { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12729         { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
12730         { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12731         { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
12732         { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
12733         { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
12734         { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
12735         { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
12736         { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
12737         { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
12738         { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
12739         { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
12740         { 0xfffffe00, 0x00005200, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
12741         { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12742         { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
12743         { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
12744         { 0xfe100f00, 0xec000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12745         { 0xfea00f00, 0xec000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12746         { 0xff300f00, 0xed000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12747         { 0xff300f00, 0xed000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12748         { 0xffb00000, 0xfa000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12749         { 0xffb00300, 0xf9800000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12750 
12751         //----------------------------------------------------------------------
12752         // Other instructions
12753         //----------------------------------------------------------------------
12754         { 0xffffffc0, 0x0000b240, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
12755         { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12756         { 0xffffffc0, 0x0000b200, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
12757         { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12758         { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
12759         { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12760         { 0xffffffc0, 0x0000b280, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
12761         { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12762     };
12763 
12764     const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode);
12765     for (size_t i=0; i<k_num_thumb_opcodes; ++i)
12766     {
12767         if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
12768             (g_thumb_opcodes[i].variants & arm_isa) != 0)
12769             return &g_thumb_opcodes[i];
12770     }
12771     return NULL;
12772 }
12773 
12774 bool
12775 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
12776 {
12777     m_arch = arch;
12778     m_arm_isa = 0;
12779     const char *arch_cstr = arch.GetArchitectureName ();
12780     if (arch_cstr)
12781     {
12782         if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
12783         else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
12784         else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
12785         else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
12786         else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
12787         else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
12788         else if (0 == ::strcasecmp(arch_cstr, "armv7s"))    m_arm_isa = ARMv7S;
12789         else if (0 == ::strcasecmp(arch_cstr, "arm"))       m_arm_isa = ARMvAll;
12790         else if (0 == ::strcasecmp(arch_cstr, "thumb"))     m_arm_isa = ARMvAll;
12791         else if (0 == ::strncasecmp(arch_cstr,"armv4", 5))  m_arm_isa = ARMv4;
12792         else if (0 == ::strncasecmp(arch_cstr,"armv6", 5))  m_arm_isa = ARMv6;
12793         else if (0 == ::strncasecmp(arch_cstr,"armv7", 5))  m_arm_isa = ARMv7;
12794         else if (0 == ::strncasecmp(arch_cstr,"armv8", 5))  m_arm_isa = ARMv8;
12795     }
12796     return m_arm_isa != 0;
12797 }
12798 
12799 bool
12800 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
12801 {
12802     if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
12803     {
12804         if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
12805             m_opcode_mode = eModeThumb;
12806         else
12807         {
12808             AddressClass addr_class = inst_addr.GetAddressClass();
12809 
12810             if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
12811                 m_opcode_mode = eModeARM;
12812             else if (addr_class == eAddressClassCodeAlternateISA)
12813                 m_opcode_mode = eModeThumb;
12814             else
12815                 return false;
12816         }
12817         if (m_opcode_mode == eModeThumb)
12818             m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
12819         else
12820             m_opcode_cpsr = CPSR_MODE_USR;
12821         return true;
12822     }
12823     return false;
12824 }
12825 
12826 bool
12827 EmulateInstructionARM::ReadInstruction ()
12828 {
12829     bool success = false;
12830     m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
12831     if (success)
12832     {
12833         addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
12834         if (success)
12835         {
12836             Context read_inst_context;
12837             read_inst_context.type = eContextReadOpcode;
12838             read_inst_context.SetNoArgs ();
12839 
12840             if (m_opcode_cpsr & MASK_CPSR_T)
12841             {
12842                 m_opcode_mode = eModeThumb;
12843                 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
12844 
12845                 if (success)
12846                 {
12847                     if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
12848                     {
12849                         m_opcode.SetOpcode16 (thumb_opcode);
12850                     }
12851                     else
12852                     {
12853                         m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success));
12854                     }
12855                 }
12856             }
12857             else
12858             {
12859                 m_opcode_mode = eModeARM;
12860                 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success));
12861             }
12862         }
12863     }
12864     if (!success)
12865     {
12866         m_opcode_mode = eModeInvalid;
12867         m_addr = LLDB_INVALID_ADDRESS;
12868     }
12869     return success;
12870 }
12871 
12872 uint32_t
12873 EmulateInstructionARM::ArchVersion ()
12874 {
12875     return m_arm_isa;
12876 }
12877 
12878 bool
12879 EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional)
12880 {
12881    // If we are ignoring conditions, then always return true.
12882    // this allows us to iterate over disassembly code and still
12883    // emulate an instruction even if we don't have all the right
12884    // bits set in the CPSR register...
12885     if (m_ignore_conditions)
12886         return true;
12887 
12888     if (is_conditional)
12889         *is_conditional = true;
12890 
12891     const uint32_t cond = CurrentCond (opcode);
12892 
12893     if (cond == UINT32_MAX)
12894         return false;
12895 
12896     bool result = false;
12897     switch (UnsignedBits(cond, 3, 1))
12898     {
12899     case 0:
12900 		if (m_opcode_cpsr == 0)
12901 			result = true;
12902         else
12903             result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
12904 		break;
12905     case 1:
12906         if (m_opcode_cpsr == 0)
12907             result = true;
12908         else
12909             result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
12910 		break;
12911     case 2:
12912         if (m_opcode_cpsr == 0)
12913             result = true;
12914         else
12915             result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
12916 		break;
12917     case 3:
12918         if (m_opcode_cpsr == 0)
12919             result = true;
12920         else
12921             result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
12922 		break;
12923     case 4:
12924         if (m_opcode_cpsr == 0)
12925             result = true;
12926         else
12927             result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12928 		break;
12929     case 5:
12930         if (m_opcode_cpsr == 0)
12931             result = true;
12932         else
12933 		{
12934             bool n = (m_opcode_cpsr & MASK_CPSR_N);
12935             bool v = (m_opcode_cpsr & MASK_CPSR_V);
12936             result = n == v;
12937         }
12938         break;
12939     case 6:
12940         if (m_opcode_cpsr == 0)
12941             result = true;
12942         else
12943 		{
12944             bool n = (m_opcode_cpsr & MASK_CPSR_N);
12945             bool v = (m_opcode_cpsr & MASK_CPSR_V);
12946             result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12947         }
12948         break;
12949     case 7:
12950         // Always execute (cond == 0b1110, or the special 0b1111 which gives
12951         // opcodes different meanings, but always means execution happpens.
12952         if (is_conditional)
12953             *is_conditional = false;
12954         result = true;
12955         break;
12956     }
12957 
12958     if (cond & 1)
12959         result = !result;
12960     return result;
12961 }
12962 
12963 uint32_t
12964 EmulateInstructionARM::CurrentCond (const uint32_t opcode)
12965 {
12966     switch (m_opcode_mode)
12967     {
12968     default:
12969     case eModeInvalid:
12970         break;
12971 
12972     case eModeARM:
12973         return UnsignedBits(opcode, 31, 28);
12974 
12975     case eModeThumb:
12976         // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
12977         // 'cond' field of the encoding.
12978         {
12979             const uint32_t byte_size = m_opcode.GetByteSize();
12980             if (byte_size == 2)
12981             {
12982                 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f)
12983                     return Bits32(opcode, 11, 7);
12984             }
12985             else if (byte_size == 4)
12986             {
12987                 if (Bits32(opcode, 31, 27) == 0x1e &&
12988                     Bits32(opcode, 15, 14) == 0x02 &&
12989                     Bits32(opcode, 12, 12) == 0x00 &&
12990                     Bits32(opcode, 25, 22) <= 0x0d)
12991                 {
12992                     return Bits32(opcode, 25, 22);
12993                 }
12994             }
12995             else
12996                 // We have an invalid thumb instruction, let's bail out.
12997                 break;
12998 
12999             return m_it_session.GetCond();
13000         }
13001     }
13002     return UINT32_MAX;  // Return invalid value
13003 }
13004 
13005 bool
13006 EmulateInstructionARM::InITBlock()
13007 {
13008     return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13009 }
13010 
13011 bool
13012 EmulateInstructionARM::LastInITBlock()
13013 {
13014     return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13015 }
13016 
13017 bool
13018 EmulateInstructionARM::BadMode (uint32_t mode)
13019 {
13020 
13021     switch (mode)
13022     {
13023         case 16: return false; // '10000'
13024         case 17: return false; // '10001'
13025         case 18: return false; // '10010'
13026         case 19: return false; // '10011'
13027         case 22: return false; // '10110'
13028         case 23: return false; // '10111'
13029         case 27: return false; // '11011'
13030         case 31: return false; // '11111'
13031         default: return true;
13032     }
13033     return true;
13034 }
13035 
13036 bool
13037 EmulateInstructionARM::CurrentModeIsPrivileged ()
13038 {
13039     uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
13040 
13041     if (BadMode (mode))
13042         return false;
13043 
13044     if (mode == 16)
13045         return false;
13046 
13047     return true;
13048 }
13049 
13050 void
13051 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
13052 {
13053     bool privileged = CurrentModeIsPrivileged();
13054 
13055     uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20;
13056 
13057     if (BitIsSet (bytemask, 3))
13058     {
13059         tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
13060         if (affect_execstate)
13061             tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
13062     }
13063 
13064     if (BitIsSet (bytemask, 2))
13065     {
13066         tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
13067     }
13068 
13069     if (BitIsSet (bytemask, 1))
13070     {
13071         if (affect_execstate)
13072             tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
13073         tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
13074         if (privileged)
13075             tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
13076     }
13077 
13078     if (BitIsSet (bytemask, 0))
13079     {
13080         if (privileged)
13081             tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
13082         if (affect_execstate)
13083             tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
13084         if (privileged)
13085             tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
13086     }
13087 
13088     m_opcode_cpsr = tmp_cpsr;
13089 }
13090 
13091 
13092 bool
13093 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
13094 {
13095     addr_t target;
13096 
13097     // Check the current instruction set.
13098     if (CurrentInstrSet() == eModeARM)
13099         target = addr & 0xfffffffc;
13100     else
13101         target = addr & 0xfffffffe;
13102 
13103     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13104         return false;
13105 
13106     return true;
13107 }
13108 
13109 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
13110 bool
13111 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
13112 {
13113     addr_t target;
13114     // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
13115     // we want to record it and issue a WriteRegister callback so the clients
13116     // can track the mode changes accordingly.
13117     bool cpsr_changed = false;
13118 
13119     if (BitIsSet(addr, 0))
13120     {
13121         if (CurrentInstrSet() != eModeThumb)
13122         {
13123             SelectInstrSet(eModeThumb);
13124             cpsr_changed = true;
13125         }
13126         target = addr & 0xfffffffe;
13127         context.SetISA (eModeThumb);
13128     }
13129     else if (BitIsClear(addr, 1))
13130     {
13131         if (CurrentInstrSet() != eModeARM)
13132         {
13133             SelectInstrSet(eModeARM);
13134             cpsr_changed = true;
13135         }
13136         target = addr & 0xfffffffc;
13137         context.SetISA (eModeARM);
13138     }
13139     else
13140         return false; // address<1:0> == '10' => UNPREDICTABLE
13141 
13142     if (cpsr_changed)
13143     {
13144         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13145             return false;
13146     }
13147     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13148         return false;
13149 
13150     return true;
13151 }
13152 
13153 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
13154 bool
13155 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
13156 {
13157     if (ArchVersion() >= ARMv5T)
13158         return BXWritePC(context, addr);
13159     else
13160         return BranchWritePC((const Context)context, addr);
13161 }
13162 
13163 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
13164 bool
13165 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
13166 {
13167     if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
13168         return BXWritePC(context, addr);
13169     else
13170         return BranchWritePC((const Context)context, addr);
13171 }
13172 
13173 EmulateInstructionARM::Mode
13174 EmulateInstructionARM::CurrentInstrSet ()
13175 {
13176     return m_opcode_mode;
13177 }
13178 
13179 // Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
13180 // ReadInstruction() is performed.  This function has a side effect of updating
13181 // the m_new_inst_cpsr member variable if necessary.
13182 bool
13183 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
13184 {
13185     m_new_inst_cpsr = m_opcode_cpsr;
13186     switch (arm_or_thumb)
13187     {
13188     default:
13189         return false;
13190     case eModeARM:
13191         // Clear the T bit.
13192         m_new_inst_cpsr &= ~MASK_CPSR_T;
13193         break;
13194     case eModeThumb:
13195         // Set the T bit.
13196         m_new_inst_cpsr |= MASK_CPSR_T;
13197         break;
13198     }
13199     return true;
13200 }
13201 
13202 // This function returns TRUE if the processor currently provides support for
13203 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
13204 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
13205 bool
13206 EmulateInstructionARM::UnalignedSupport()
13207 {
13208     return (ArchVersion() >= ARMv7);
13209 }
13210 
13211 // The main addition and subtraction instructions can produce status information
13212 // about both unsigned carry and signed overflow conditions.  This status
13213 // information can be used to synthesize multi-word additions and subtractions.
13214 EmulateInstructionARM::AddWithCarryResult
13215 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
13216 {
13217     uint32_t result;
13218     uint8_t carry_out;
13219     uint8_t overflow;
13220 
13221     uint64_t unsigned_sum = x + y + carry_in;
13222     int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
13223 
13224     result = UnsignedBits(unsigned_sum, 31, 0);
13225 //    carry_out = (result == unsigned_sum ? 0 : 1);
13226     overflow = ((int32_t)result == signed_sum ? 0 : 1);
13227 
13228     if (carry_in)
13229         carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0;
13230     else
13231         carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0;
13232 
13233     AddWithCarryResult res = { result, carry_out, overflow };
13234     return res;
13235 }
13236 
13237 uint32_t
13238 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
13239 {
13240     uint32_t reg_kind, reg_num;
13241     switch (num)
13242     {
13243     case SP_REG:
13244         reg_kind = eRegisterKindGeneric;
13245         reg_num  = LLDB_REGNUM_GENERIC_SP;
13246         break;
13247     case LR_REG:
13248         reg_kind = eRegisterKindGeneric;
13249         reg_num  = LLDB_REGNUM_GENERIC_RA;
13250         break;
13251     case PC_REG:
13252         reg_kind = eRegisterKindGeneric;
13253         reg_num  = LLDB_REGNUM_GENERIC_PC;
13254         break;
13255     default:
13256         if (num < SP_REG)
13257         {
13258             reg_kind = eRegisterKindDWARF;
13259             reg_num  = dwarf_r0 + num;
13260         }
13261         else
13262         {
13263             //assert(0 && "Invalid register number");
13264             *success = false;
13265             return UINT32_MAX;
13266         }
13267         break;
13268     }
13269 
13270     // Read our register.
13271     uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
13272 
13273     // When executing an ARM instruction , PC reads as the address of the current
13274     // instruction plus 8.
13275     // When executing a Thumb instruction , PC reads as the address of the current
13276     // instruction plus 4.
13277     if (num == 15)
13278     {
13279         if (CurrentInstrSet() == eModeARM)
13280             val += 8;
13281         else
13282             val += 4;
13283     }
13284 
13285     return val;
13286 }
13287 
13288 // Write the result to the ARM core register Rd, and optionally update the
13289 // condition flags based on the result.
13290 //
13291 // This helper method tries to encapsulate the following pseudocode from the
13292 // ARM Architecture Reference Manual:
13293 //
13294 // if d == 15 then         // Can only occur for encoding A1
13295 //     ALUWritePC(result); // setflags is always FALSE here
13296 // else
13297 //     R[d] = result;
13298 //     if setflags then
13299 //         APSR.N = result<31>;
13300 //         APSR.Z = IsZeroBit(result);
13301 //         APSR.C = carry;
13302 //         // APSR.V unchanged
13303 //
13304 // In the above case, the API client does not pass in the overflow arg, which
13305 // defaults to ~0u.
13306 bool
13307 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
13308                                                   const uint32_t result,
13309                                                   const uint32_t Rd,
13310                                                   bool setflags,
13311                                                   const uint32_t carry,
13312                                                   const uint32_t overflow)
13313 {
13314     if (Rd == 15)
13315     {
13316         if (!ALUWritePC (context, result))
13317             return false;
13318     }
13319     else
13320     {
13321         uint32_t reg_kind, reg_num;
13322         switch (Rd)
13323         {
13324         case SP_REG:
13325             reg_kind = eRegisterKindGeneric;
13326             reg_num  = LLDB_REGNUM_GENERIC_SP;
13327             break;
13328         case LR_REG:
13329             reg_kind = eRegisterKindGeneric;
13330             reg_num  = LLDB_REGNUM_GENERIC_RA;
13331             break;
13332         default:
13333             reg_kind = eRegisterKindDWARF;
13334             reg_num  = dwarf_r0 + Rd;
13335         }
13336         if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
13337             return false;
13338         if (setflags)
13339             return WriteFlags (context, result, carry, overflow);
13340     }
13341     return true;
13342 }
13343 
13344 // This helper method tries to encapsulate the following pseudocode from the
13345 // ARM Architecture Reference Manual:
13346 //
13347 // APSR.N = result<31>;
13348 // APSR.Z = IsZeroBit(result);
13349 // APSR.C = carry;
13350 // APSR.V = overflow
13351 //
13352 // Default arguments can be specified for carry and overflow parameters, which means
13353 // not to update the respective flags.
13354 bool
13355 EmulateInstructionARM::WriteFlags (Context &context,
13356                                    const uint32_t result,
13357                                    const uint32_t carry,
13358                                    const uint32_t overflow)
13359 {
13360     m_new_inst_cpsr = m_opcode_cpsr;
13361     SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
13362     SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
13363     if (carry != ~0u)
13364         SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
13365     if (overflow != ~0u)
13366         SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
13367     if (m_new_inst_cpsr != m_opcode_cpsr)
13368     {
13369         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13370             return false;
13371     }
13372     return true;
13373 }
13374 
13375 bool
13376 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
13377 {
13378     // Advance the ITSTATE bits to their values for the next instruction.
13379     if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
13380         m_it_session.ITAdvance();
13381 
13382     ARMOpcode *opcode_data = NULL;
13383 
13384     if (m_opcode_mode == eModeThumb)
13385         opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13386     else if (m_opcode_mode == eModeARM)
13387         opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13388 
13389     if (opcode_data == NULL)
13390         return false;
13391 
13392     const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
13393     m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
13394 
13395     bool success = false;
13396     if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
13397     {
13398         m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF,
13399                                                 dwarf_cpsr,
13400                                                 0,
13401                                                 &success);
13402     }
13403 
13404     // Only return false if we are unable to read the CPSR if we care about conditions
13405     if (success == false && m_ignore_conditions == false)
13406         return false;
13407 
13408     uint32_t orig_pc_value = 0;
13409     if (auto_advance_pc)
13410     {
13411         orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13412         if (!success)
13413             return false;
13414     }
13415 
13416     // Call the Emulate... function.
13417     success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
13418     if (!success)
13419         return false;
13420 
13421     if (auto_advance_pc)
13422     {
13423         uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13424         if (!success)
13425             return false;
13426 
13427         if (auto_advance_pc && (after_pc_value == orig_pc_value))
13428         {
13429             if (opcode_data->size == eSize32)
13430                 after_pc_value += 4;
13431             else if (opcode_data->size == eSize16)
13432                 after_pc_value += 2;
13433 
13434             EmulateInstruction::Context context;
13435             context.type = eContextAdvancePC;
13436             context.SetNoArgs();
13437             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
13438                 return false;
13439 
13440         }
13441     }
13442     return true;
13443 }
13444 
13445 bool
13446 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data)
13447 {
13448     if (!test_data)
13449     {
13450         out_stream->Printf ("TestEmulation: Missing test data.\n");
13451         return false;
13452     }
13453 
13454     static ConstString opcode_key ("opcode");
13455     static ConstString before_key ("before_state");
13456     static ConstString after_key ("after_state");
13457 
13458     OptionValueSP value_sp = test_data->GetValueForKey (opcode_key);
13459 
13460     uint32_t test_opcode;
13461     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64))
13462     {
13463         out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n");
13464         return false;
13465     }
13466     test_opcode = value_sp->GetUInt64Value ();
13467 
13468     if (arch.GetTriple().getArch() == llvm::Triple::arm)
13469     {
13470         m_opcode_mode = eModeARM;
13471         m_opcode.SetOpcode32 (test_opcode);
13472     }
13473     else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
13474     {
13475         m_opcode_mode = eModeThumb;
13476         if (test_opcode < 0x10000)
13477             m_opcode.SetOpcode16 (test_opcode);
13478         else
13479             m_opcode.SetOpcode32 (test_opcode);
13480 
13481     }
13482     else
13483     {
13484         out_stream->Printf ("TestEmulation:  Invalid arch.\n");
13485         return false;
13486     }
13487 
13488     EmulationStateARM before_state;
13489     EmulationStateARM after_state;
13490 
13491     value_sp = test_data->GetValueForKey (before_key);
13492     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13493     {
13494         out_stream->Printf ("TestEmulation:  Failed to find 'before' state.\n");
13495         return false;
13496     }
13497 
13498     OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary ();
13499     if (!before_state.LoadStateFromDictionary (state_dictionary))
13500     {
13501         out_stream->Printf ("TestEmulation:  Failed loading 'before' state.\n");
13502         return false;
13503     }
13504 
13505     value_sp = test_data->GetValueForKey (after_key);
13506     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13507     {
13508         out_stream->Printf ("TestEmulation:  Failed to find 'after' state.\n");
13509         return false;
13510     }
13511 
13512     state_dictionary = value_sp->GetAsDictionary ();
13513     if (!after_state.LoadStateFromDictionary (state_dictionary))
13514     {
13515         out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n");
13516         return false;
13517     }
13518 
13519     SetBaton ((void *) &before_state);
13520     SetCallbacks (&EmulationStateARM::ReadPseudoMemory,
13521                   &EmulationStateARM::WritePseudoMemory,
13522                   &EmulationStateARM::ReadPseudoRegister,
13523                   &EmulationStateARM::WritePseudoRegister);
13524 
13525     bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC);
13526     if (!success)
13527     {
13528         out_stream->Printf ("TestEmulation:  EvaluateInstruction() failed.\n");
13529         return false;
13530     }
13531 
13532     success = before_state.CompareState (after_state);
13533     if (!success)
13534         out_stream->Printf ("TestEmulation:  'before' and 'after' states do not match.\n");
13535 
13536     return success;
13537 }
13538 //
13539 //
13540 //const char *
13541 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
13542 //{
13543 //    if (reg_kind == eRegisterKindGeneric)
13544 //    {
13545 //        switch (reg_num)
13546 //        {
13547 //        case LLDB_REGNUM_GENERIC_PC:    return "pc";
13548 //        case LLDB_REGNUM_GENERIC_SP:    return "sp";
13549 //        case LLDB_REGNUM_GENERIC_FP:    return "fp";
13550 //        case LLDB_REGNUM_GENERIC_RA:    return "lr";
13551 //        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
13552 //        default: return NULL;
13553 //        }
13554 //    }
13555 //    else if (reg_kind == eRegisterKindDWARF)
13556 //    {
13557 //        return GetARMDWARFRegisterName (reg_num);
13558 //    }
13559 //    return NULL;
13560 //}
13561 //
13562 bool
13563 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
13564 {
13565     unwind_plan.Clear();
13566     unwind_plan.SetRegisterKind (eRegisterKindDWARF);
13567 
13568     UnwindPlan::Row row;
13569 
13570     // Our previous Call Frame Address is the stack pointer
13571     row.SetCFARegister (dwarf_sp);
13572 
13573     // Our previous PC is in the LR
13574     row.SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true);
13575     unwind_plan.AppendRow (row);
13576 
13577     // All other registers are the same.
13578 
13579     unwind_plan.SetSourceName ("EmulateInstructionARM");
13580     return true;
13581 }
13582 
13583 
13584 
13585 
13586