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)
284     {
285         switch (m_arch.GetTriple().getOS())
286         {
287             case llvm::Triple::Darwin:
288             case llvm::Triple::MacOSX:
289             case llvm::Triple::IOS:
290                 return 7;
291             default:
292                 break;
293         }
294     }
295     return 11;
296 }
297 
298 uint32_t
299 EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const
300 {
301     if (m_opcode_mode == eModeThumb)
302     {
303         switch (m_arch.GetTriple().getOS())
304         {
305             case llvm::Triple::Darwin:
306             case llvm::Triple::MacOSX:
307             case llvm::Triple::IOS:
308                 return dwarf_r7;
309             default:
310                 break;
311         }
312     }
313     return dwarf_r11;
314 }
315 
316 // Push Multiple Registers stores multiple registers to the stack, storing to
317 // consecutive memory locations ending just below the address in SP, and updates
318 // SP to point to the start of the stored data.
319 bool
320 EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding)
321 {
322 #if 0
323     // ARM pseudo code...
324     if (ConditionPassed())
325     {
326         EncodingSpecificOperations();
327         NullCheckIfThumbEE(13);
328         address = SP - 4*BitCount(registers);
329 
330         for (i = 0 to 14)
331         {
332             if (registers<i> == '1')
333             {
334                 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
335                     MemA[address,4] = bits(32) UNKNOWN;
336                 else
337                     MemA[address,4] = R[i];
338                 address = address + 4;
339             }
340         }
341 
342         if (registers<15> == '1') // Only possible for encoding A1 or A2
343             MemA[address,4] = PCStoreValue();
344 
345         SP = SP - 4*BitCount(registers);
346     }
347 #endif
348 
349     bool conditional = false;
350     bool success = false;
351     if (ConditionPassed(opcode, &conditional))
352     {
353         const uint32_t addr_byte_size = GetAddressByteSize();
354         const addr_t sp = ReadCoreReg (SP_REG, &success);
355         if (!success)
356             return false;
357         uint32_t registers = 0;
358         uint32_t Rt; // the source register
359         switch (encoding) {
360         case eEncodingT1:
361             registers = Bits32(opcode, 7, 0);
362             // The M bit represents LR.
363             if (Bit32(opcode, 8))
364                 registers |= (1u << 14);
365             // if BitCount(registers) < 1 then UNPREDICTABLE;
366             if (BitCount(registers) < 1)
367                 return false;
368             break;
369         case eEncodingT2:
370             // Ignore bits 15 & 13.
371             registers = Bits32(opcode, 15, 0) & ~0xa000;
372             // if BitCount(registers) < 2 then UNPREDICTABLE;
373             if (BitCount(registers) < 2)
374                 return false;
375             break;
376         case eEncodingT3:
377             Rt = Bits32(opcode, 15, 12);
378             // if BadReg(t) then UNPREDICTABLE;
379             if (BadReg(Rt))
380                 return false;
381             registers = (1u << Rt);
382             break;
383         case eEncodingA1:
384             registers = Bits32(opcode, 15, 0);
385             // Instead of return false, let's handle the following case as well,
386             // which amounts to pushing one reg onto the full descending stacks.
387             // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
388             break;
389         case eEncodingA2:
390             Rt = Bits32(opcode, 15, 12);
391             // if t == 13 then UNPREDICTABLE;
392             if (Rt == dwarf_sp)
393                 return false;
394             registers = (1u << Rt);
395             break;
396         default:
397             return false;
398         }
399         addr_t sp_offset = addr_byte_size * BitCount (registers);
400         addr_t addr = sp - sp_offset;
401         uint32_t i;
402 
403         EmulateInstruction::Context context;
404         if (conditional)
405             context.type = EmulateInstruction::eContextRegisterStore;
406         else
407             context.type = EmulateInstruction::eContextPushRegisterOnStack;
408         RegisterInfo reg_info;
409         RegisterInfo sp_reg;
410         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
411         for (i=0; i<15; ++i)
412         {
413             if (BitIsSet (registers, i))
414             {
415                 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info);
416                 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
417                 uint32_t reg_value = ReadCoreReg(i, &success);
418                 if (!success)
419                     return false;
420                 if (!MemAWrite (context, addr, reg_value, addr_byte_size))
421                     return false;
422                 addr += addr_byte_size;
423             }
424         }
425 
426         if (BitIsSet (registers, 15))
427         {
428             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info);
429             context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
430             const uint32_t pc = ReadCoreReg(PC_REG, &success);
431             if (!success)
432                 return false;
433             if (!MemAWrite (context, addr, pc, addr_byte_size))
434                 return false;
435         }
436 
437         context.type = EmulateInstruction::eContextAdjustStackPointer;
438         context.SetImmediateSigned (-sp_offset);
439 
440         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
441             return false;
442     }
443     return true;
444 }
445 
446 // Pop Multiple Registers loads multiple registers from the stack, loading from
447 // consecutive memory locations staring at the address in SP, and updates
448 // SP to point just above the loaded data.
449 bool
450 EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding)
451 {
452 #if 0
453     // ARM pseudo code...
454     if (ConditionPassed())
455     {
456         EncodingSpecificOperations(); NullCheckIfThumbEE(13);
457         address = SP;
458         for i = 0 to 14
459             if registers<i> == '1' then
460                 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
461         if registers<15> == '1' then
462             if UnalignedAllowed then
463                 LoadWritePC(MemU[address,4]);
464             else
465                 LoadWritePC(MemA[address,4]);
466         if registers<13> == '0' then SP = SP + 4*BitCount(registers);
467         if registers<13> == '1' then SP = bits(32) UNKNOWN;
468     }
469 #endif
470 
471     bool success = false;
472 
473     bool conditional = false;
474     if (ConditionPassed(opcode, &conditional))
475     {
476         const uint32_t addr_byte_size = GetAddressByteSize();
477         const addr_t sp = ReadCoreReg (SP_REG, &success);
478         if (!success)
479             return false;
480         uint32_t registers = 0;
481         uint32_t Rt; // the destination register
482         switch (encoding) {
483         case eEncodingT1:
484             registers = Bits32(opcode, 7, 0);
485             // The P bit represents PC.
486             if (Bit32(opcode, 8))
487                 registers |= (1u << 15);
488             // if BitCount(registers) < 1 then UNPREDICTABLE;
489             if (BitCount(registers) < 1)
490                 return false;
491             break;
492         case eEncodingT2:
493             // Ignore bit 13.
494             registers = Bits32(opcode, 15, 0) & ~0x2000;
495             // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
496             if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
497                 return false;
498             // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
499             if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
500                 return false;
501             break;
502         case eEncodingT3:
503             Rt = Bits32(opcode, 15, 12);
504             // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
505             if (Rt == 13)
506                 return false;
507             if (Rt == 15 && InITBlock() && !LastInITBlock())
508                 return false;
509             registers = (1u << Rt);
510             break;
511         case eEncodingA1:
512             registers = Bits32(opcode, 15, 0);
513             // Instead of return false, let's handle the following case as well,
514             // which amounts to popping one reg from the full descending stacks.
515             // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
516 
517             // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
518             if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
519                 return false;
520             break;
521         case eEncodingA2:
522             Rt = Bits32(opcode, 15, 12);
523             // if t == 13 then UNPREDICTABLE;
524             if (Rt == dwarf_sp)
525                 return false;
526             registers = (1u << Rt);
527             break;
528         default:
529             return false;
530         }
531         addr_t sp_offset = addr_byte_size * BitCount (registers);
532         addr_t addr = sp;
533         uint32_t i, data;
534 
535         EmulateInstruction::Context context;
536         if (conditional)
537             context.type = EmulateInstruction::eContextRegisterLoad;
538         else
539             context.type = EmulateInstruction::eContextPopRegisterOffStack;
540 
541         RegisterInfo sp_reg;
542         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
543 
544         for (i=0; i<15; ++i)
545         {
546             if (BitIsSet (registers, i))
547             {
548                 context.SetRegisterPlusOffset (sp_reg, addr - sp);
549                 data = MemARead(context, addr, 4, 0, &success);
550                 if (!success)
551                     return false;
552                 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data))
553                     return false;
554                 addr += addr_byte_size;
555             }
556         }
557 
558         if (BitIsSet (registers, 15))
559         {
560             context.SetRegisterPlusOffset (sp_reg, addr - sp);
561             data = MemARead(context, addr, 4, 0, &success);
562             if (!success)
563                 return false;
564             // In ARMv5T and above, this is an interworking branch.
565             if (!LoadWritePC(context, data))
566                 return false;
567             addr += addr_byte_size;
568         }
569 
570         context.type = EmulateInstruction::eContextAdjustStackPointer;
571         context.SetImmediateSigned (sp_offset);
572 
573         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
574             return false;
575     }
576     return true;
577 }
578 
579 // Set r7 or ip to point to saved value residing within the stack.
580 // ADD (SP plus immediate)
581 bool
582 EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding)
583 {
584 #if 0
585     // ARM pseudo code...
586     if (ConditionPassed())
587     {
588         EncodingSpecificOperations();
589         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
590         if d == 15 then
591            ALUWritePC(result); // setflags is always FALSE here
592         else
593             R[d] = result;
594             if setflags then
595                 APSR.N = result<31>;
596                 APSR.Z = IsZeroBit(result);
597                 APSR.C = carry;
598                 APSR.V = overflow;
599     }
600 #endif
601 
602     bool success = false;
603 
604     if (ConditionPassed(opcode))
605     {
606         const addr_t sp = ReadCoreReg (SP_REG, &success);
607         if (!success)
608             return false;
609         uint32_t Rd; // the destination register
610         uint32_t imm32;
611         switch (encoding) {
612         case eEncodingT1:
613             Rd = 7;
614             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
615             break;
616         case eEncodingA1:
617             Rd = Bits32(opcode, 15, 12);
618             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
619             break;
620         default:
621             return false;
622         }
623         addr_t sp_offset = imm32;
624         addr_t addr = sp + sp_offset; // a pointer to the stack area
625 
626         EmulateInstruction::Context context;
627         context.type = eContextSetFramePointer;
628         RegisterInfo sp_reg;
629         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
630         context.SetRegisterPlusOffset (sp_reg, sp_offset);
631 
632         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
633             return false;
634     }
635     return true;
636 }
637 
638 // Set r7 or ip to the current stack pointer.
639 // MOV (register)
640 bool
641 EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding)
642 {
643 #if 0
644     // ARM pseudo code...
645     if (ConditionPassed())
646     {
647         EncodingSpecificOperations();
648         result = R[m];
649         if d == 15 then
650             ALUWritePC(result); // setflags is always FALSE here
651         else
652             R[d] = result;
653             if setflags then
654                 APSR.N = result<31>;
655                 APSR.Z = IsZeroBit(result);
656                 // APSR.C unchanged
657                 // APSR.V unchanged
658     }
659 #endif
660 
661     bool success = false;
662 
663     if (ConditionPassed(opcode))
664     {
665         const addr_t sp = ReadCoreReg (SP_REG, &success);
666         if (!success)
667             return false;
668         uint32_t Rd; // the destination register
669         switch (encoding) {
670         case eEncodingT1:
671             Rd = 7;
672             break;
673         case eEncodingA1:
674             Rd = 12;
675             break;
676         default:
677             return false;
678         }
679 
680         EmulateInstruction::Context context;
681         if (Rd == GetFramePointerRegisterNumber())
682             context.type = EmulateInstruction::eContextSetFramePointer;
683         else
684             context.type = EmulateInstruction::eContextRegisterPlusOffset;
685         RegisterInfo sp_reg;
686         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
687         context.SetRegisterPlusOffset (sp_reg, 0);
688 
689         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
690             return false;
691     }
692     return true;
693 }
694 
695 // Move from high register (r8-r15) to low register (r0-r7).
696 // MOV (register)
697 bool
698 EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding)
699 {
700     return EmulateMOVRdRm (opcode, encoding);
701 }
702 
703 // Move from register to register.
704 // MOV (register)
705 bool
706 EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding)
707 {
708 #if 0
709     // ARM pseudo code...
710     if (ConditionPassed())
711     {
712         EncodingSpecificOperations();
713         result = R[m];
714         if d == 15 then
715             ALUWritePC(result); // setflags is always FALSE here
716         else
717             R[d] = result;
718             if setflags then
719                 APSR.N = result<31>;
720                 APSR.Z = IsZeroBit(result);
721                 // APSR.C unchanged
722                 // APSR.V unchanged
723     }
724 #endif
725 
726     bool success = false;
727 
728     if (ConditionPassed(opcode))
729     {
730         uint32_t Rm; // the source register
731         uint32_t Rd; // the destination register
732         bool setflags;
733         switch (encoding) {
734         case eEncodingT1:
735             Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
736             Rm = Bits32(opcode, 6, 3);
737             setflags = false;
738             if (Rd == 15 && InITBlock() && !LastInITBlock())
739                 return false;
740             break;
741         case eEncodingT2:
742             Rd = Bits32(opcode, 2, 0);
743             Rm = Bits32(opcode, 5, 3);
744             setflags = true;
745             if (InITBlock())
746                 return false;
747             break;
748         case eEncodingT3:
749             Rd = Bits32(opcode, 11, 8);
750             Rm = Bits32(opcode, 3, 0);
751             setflags = BitIsSet(opcode, 20);
752             // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
753             if (setflags && (BadReg(Rd) || BadReg(Rm)))
754                 return false;
755             // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE;
756             if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
757                 return false;
758             break;
759         case eEncodingA1:
760             Rd = Bits32(opcode, 15, 12);
761             Rm = Bits32(opcode, 3, 0);
762             setflags = BitIsSet(opcode, 20);
763 
764             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
765             if (Rd == 15 && setflags)
766                 return EmulateSUBSPcLrEtc (opcode, encoding);
767             break;
768         default:
769             return false;
770         }
771         uint32_t result = ReadCoreReg(Rm, &success);
772         if (!success)
773             return false;
774 
775         // The context specifies that Rm is to be moved into Rd.
776         EmulateInstruction::Context context;
777         context.type = EmulateInstruction::eContextRegisterLoad;
778         RegisterInfo dwarf_reg;
779         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
780         context.SetRegister (dwarf_reg);
781 
782         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
783             return false;
784     }
785     return true;
786 }
787 
788 // Move (immediate) writes an immediate value to the destination register.  It
789 // can optionally update the condition flags based on the value.
790 // MOV (immediate)
791 bool
792 EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding)
793 {
794 #if 0
795     // ARM pseudo code...
796     if (ConditionPassed())
797     {
798         EncodingSpecificOperations();
799         result = imm32;
800         if d == 15 then         // Can only occur for ARM encoding
801             ALUWritePC(result); // setflags is always FALSE here
802         else
803             R[d] = result;
804             if setflags then
805                 APSR.N = result<31>;
806                 APSR.Z = IsZeroBit(result);
807                 APSR.C = carry;
808                 // APSR.V unchanged
809     }
810 #endif
811 
812     if (ConditionPassed(opcode))
813     {
814         uint32_t Rd; // the destination register
815         uint32_t imm32; // the immediate value to be written to Rd
816         uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
817                             // for setflags == false, this value is a don't care
818                             // initialized to 0 to silence the static analyzer
819         bool setflags;
820         switch (encoding) {
821             case eEncodingT1:
822                 Rd = Bits32(opcode, 10, 8);
823                 setflags = !InITBlock();
824                 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
825                 carry = APSR_C;
826 
827                 break;
828 
829             case eEncodingT2:
830                 Rd = Bits32(opcode, 11, 8);
831                 setflags = BitIsSet(opcode, 20);
832                 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
833                 if (BadReg(Rd))
834                   return false;
835 
836                 break;
837 
838             case eEncodingT3:
839             {
840                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32);
841                 Rd = Bits32 (opcode, 11, 8);
842                 setflags = false;
843                 uint32_t imm4 = Bits32 (opcode, 19, 16);
844                 uint32_t imm3 = Bits32 (opcode, 14, 12);
845                 uint32_t i = Bit32 (opcode, 26);
846                 uint32_t imm8 = Bits32 (opcode, 7, 0);
847                 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
848 
849                 // if BadReg(d) then UNPREDICTABLE;
850                 if (BadReg (Rd))
851                     return false;
852             }
853                 break;
854 
855             case eEncodingA1:
856                 // d = UInt(Rd); setflags = (S == �1�); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C);
857                 Rd = Bits32 (opcode, 15, 12);
858                 setflags = BitIsSet (opcode, 20);
859                 imm32 = ARMExpandImm_C (opcode, APSR_C, carry);
860 
861                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
862                 if ((Rd == 15) && setflags)
863                     return EmulateSUBSPcLrEtc (opcode, encoding);
864 
865                 break;
866 
867             case eEncodingA2:
868             {
869                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
870                 Rd = Bits32 (opcode, 15, 12);
871                 setflags = false;
872                 uint32_t imm4 = Bits32 (opcode, 19, 16);
873                 uint32_t imm12 = Bits32 (opcode, 11, 0);
874                 imm32 = (imm4 << 12) | imm12;
875 
876                 // if d == 15 then UNPREDICTABLE;
877                 if (Rd == 15)
878                     return false;
879             }
880                 break;
881 
882             default:
883                 return false;
884         }
885         uint32_t result = imm32;
886 
887         // The context specifies that an immediate is to be moved into Rd.
888         EmulateInstruction::Context context;
889         context.type = EmulateInstruction::eContextImmediate;
890         context.SetNoArgs ();
891 
892         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
893             return false;
894     }
895     return true;
896 }
897 
898 // MUL multiplies two register values.  The least significant 32 bits of the result are written to the destination
899 // register.  These 32 bits do not depend on whether the source register values are considered to be signed values or
900 // unsigned values.
901 //
902 // Optionally, it can update the condition flags based on the result.  In the Thumb instruction set, this option is
903 // limited to only a few forms of the instruction.
904 bool
905 EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding)
906 {
907 #if 0
908     if ConditionPassed() then
909         EncodingSpecificOperations();
910         operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
911         operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
912         result = operand1 * operand2;
913         R[d] = result<31:0>;
914         if setflags then
915             APSR.N = result<31>;
916             APSR.Z = IsZeroBit(result);
917             if ArchVersion() == 4 then
918                 APSR.C = bit UNKNOWN;
919             // else APSR.C unchanged
920             // APSR.V always unchanged
921 #endif
922 
923     if (ConditionPassed(opcode))
924     {
925         uint32_t d;
926         uint32_t n;
927         uint32_t m;
928         bool setflags;
929 
930         // EncodingSpecificOperations();
931         switch (encoding)
932         {
933             case eEncodingT1:
934                 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
935                 d = Bits32 (opcode, 2, 0);
936                 n = Bits32 (opcode, 5, 3);
937                 m = Bits32 (opcode, 2, 0);
938                 setflags = !InITBlock();
939 
940                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
941                 if ((ArchVersion() < ARMv6) && (d == n))
942                     return false;
943 
944                 break;
945 
946             case eEncodingT2:
947                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
948                 d = Bits32 (opcode, 11, 8);
949                 n = Bits32 (opcode, 19, 16);
950                 m = Bits32 (opcode, 3, 0);
951                 setflags = false;
952 
953                 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
954                 if (BadReg (d) || BadReg (n) || BadReg (m))
955                     return false;
956 
957                 break;
958 
959             case eEncodingA1:
960                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
961                 d = Bits32 (opcode, 19, 16);
962                 n = Bits32 (opcode, 3, 0);
963                 m = Bits32 (opcode, 11, 8);
964                 setflags = BitIsSet (opcode, 20);
965 
966                 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
967                 if ((d == 15) ||  (n == 15) || (m == 15))
968                     return false;
969 
970                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
971                 if ((ArchVersion() < ARMv6) && (d == n))
972                     return false;
973 
974                 break;
975 
976             default:
977                 return false;
978         }
979 
980         bool success = false;
981 
982         // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
983         uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
984         if (!success)
985             return false;
986 
987         // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
988         uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
989         if (!success)
990             return false;
991 
992         // result = operand1 * operand2;
993         uint64_t result = operand1 * operand2;
994 
995         // R[d] = result<31:0>;
996         RegisterInfo op1_reg;
997         RegisterInfo op2_reg;
998         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
999         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
1000 
1001         EmulateInstruction::Context context;
1002         context.type = eContextArithmetic;
1003         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
1004 
1005         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result)))
1006             return false;
1007 
1008         // if setflags then
1009         if (setflags)
1010         {
1011             // APSR.N = result<31>;
1012             // APSR.Z = IsZeroBit(result);
1013             m_new_inst_cpsr = m_opcode_cpsr;
1014             SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31));
1015             SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1016             if (m_new_inst_cpsr != m_opcode_cpsr)
1017             {
1018                 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1019                     return false;
1020             }
1021 
1022             // if ArchVersion() == 4 then
1023                 // APSR.C = bit UNKNOWN;
1024         }
1025     }
1026     return true;
1027 }
1028 
1029 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register.
1030 // It can optionally update the condition flags based on the value.
1031 bool
1032 EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding)
1033 {
1034 #if 0
1035     // ARM pseudo code...
1036     if (ConditionPassed())
1037     {
1038         EncodingSpecificOperations();
1039         result = NOT(imm32);
1040         if d == 15 then         // Can only occur for ARM encoding
1041             ALUWritePC(result); // setflags is always FALSE here
1042         else
1043             R[d] = result;
1044             if setflags then
1045                 APSR.N = result<31>;
1046                 APSR.Z = IsZeroBit(result);
1047                 APSR.C = carry;
1048                 // APSR.V unchanged
1049     }
1050 #endif
1051 
1052     if (ConditionPassed(opcode))
1053     {
1054         uint32_t Rd; // the destination register
1055         uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1056         uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1057         bool setflags;
1058         switch (encoding) {
1059         case eEncodingT1:
1060             Rd = Bits32(opcode, 11, 8);
1061             setflags = BitIsSet(opcode, 20);
1062             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1063             break;
1064         case eEncodingA1:
1065             Rd = Bits32(opcode, 15, 12);
1066             setflags = BitIsSet(opcode, 20);
1067             imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1068 
1069             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1070             if (Rd == 15 && setflags)
1071                 return EmulateSUBSPcLrEtc (opcode, encoding);
1072             break;
1073         default:
1074             return false;
1075         }
1076         uint32_t result = ~imm32;
1077 
1078         // The context specifies that an immediate is to be moved into Rd.
1079         EmulateInstruction::Context context;
1080         context.type = EmulateInstruction::eContextImmediate;
1081         context.SetNoArgs ();
1082 
1083         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1084             return false;
1085     }
1086     return true;
1087 }
1088 
1089 // Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register.
1090 // It can optionally update the condition flags based on the result.
1091 bool
1092 EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding)
1093 {
1094 #if 0
1095     // ARM pseudo code...
1096     if (ConditionPassed())
1097     {
1098         EncodingSpecificOperations();
1099         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1100         result = NOT(shifted);
1101         if d == 15 then         // Can only occur for ARM encoding
1102             ALUWritePC(result); // setflags is always FALSE here
1103         else
1104             R[d] = result;
1105             if setflags then
1106                 APSR.N = result<31>;
1107                 APSR.Z = IsZeroBit(result);
1108                 APSR.C = carry;
1109                 // APSR.V unchanged
1110     }
1111 #endif
1112 
1113     if (ConditionPassed(opcode))
1114     {
1115         uint32_t Rm; // the source register
1116         uint32_t Rd; // the destination register
1117         ARM_ShifterType shift_t;
1118         uint32_t shift_n; // the shift applied to the value read from Rm
1119         bool setflags;
1120         uint32_t carry; // the carry bit after the shift operation
1121         switch (encoding) {
1122         case eEncodingT1:
1123             Rd = Bits32(opcode, 2, 0);
1124             Rm = Bits32(opcode, 5, 3);
1125             setflags = !InITBlock();
1126             shift_t = SRType_LSL;
1127             shift_n = 0;
1128             if (InITBlock())
1129                 return false;
1130             break;
1131         case eEncodingT2:
1132             Rd = Bits32(opcode, 11, 8);
1133             Rm = Bits32(opcode, 3, 0);
1134             setflags = BitIsSet(opcode, 20);
1135             shift_n = DecodeImmShiftThumb(opcode, shift_t);
1136             // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1137             if (BadReg(Rd) || BadReg(Rm))
1138                 return false;
1139             break;
1140         case eEncodingA1:
1141             Rd = Bits32(opcode, 15, 12);
1142             Rm = Bits32(opcode, 3, 0);
1143             setflags = BitIsSet(opcode, 20);
1144             shift_n = DecodeImmShiftARM(opcode, shift_t);
1145             break;
1146         default:
1147             return false;
1148         }
1149         bool success = false;
1150         uint32_t value = ReadCoreReg(Rm, &success);
1151         if (!success)
1152             return false;
1153 
1154         uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1155         if (!success)
1156             return false;
1157         uint32_t result = ~shifted;
1158 
1159         // The context specifies that an immediate is to be moved into Rd.
1160         EmulateInstruction::Context context;
1161         context.type = EmulateInstruction::eContextImmediate;
1162         context.SetNoArgs ();
1163 
1164         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1165             return false;
1166     }
1167     return true;
1168 }
1169 
1170 // PC relative immediate load into register, possibly followed by ADD (SP plus register).
1171 // LDR (literal)
1172 bool
1173 EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding)
1174 {
1175 #if 0
1176     // ARM pseudo code...
1177     if (ConditionPassed())
1178     {
1179         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1180         base = Align(PC,4);
1181         address = if add then (base + imm32) else (base - imm32);
1182         data = MemU[address,4];
1183         if t == 15 then
1184             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1185         elsif UnalignedSupport() || address<1:0> = '00' then
1186             R[t] = data;
1187         else // Can only apply before ARMv7
1188             if CurrentInstrSet() == InstrSet_ARM then
1189                 R[t] = ROR(data, 8*UInt(address<1:0>));
1190             else
1191                 R[t] = bits(32) UNKNOWN;
1192     }
1193 #endif
1194 
1195     if (ConditionPassed(opcode))
1196     {
1197         bool success = false;
1198         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1199         if (!success)
1200             return false;
1201 
1202         // PC relative immediate load context
1203         EmulateInstruction::Context context;
1204         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1205         RegisterInfo pc_reg;
1206         GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
1207         context.SetRegisterPlusOffset (pc_reg, 0);
1208 
1209         uint32_t Rt;    // the destination register
1210         uint32_t imm32; // immediate offset from the PC
1211         bool add;       // +imm32 or -imm32?
1212         addr_t base;    // the base address
1213         addr_t address; // the PC relative address
1214         uint32_t data;  // the literal data value from the PC relative load
1215         switch (encoding) {
1216         case eEncodingT1:
1217             Rt = Bits32(opcode, 10, 8);
1218             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1219             add = true;
1220             break;
1221         case eEncodingT2:
1222             Rt = Bits32(opcode, 15, 12);
1223             imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1224             add = BitIsSet(opcode, 23);
1225             if (Rt == 15 && InITBlock() && !LastInITBlock())
1226                 return false;
1227             break;
1228         default:
1229             return false;
1230         }
1231 
1232         base = Align(pc, 4);
1233         if (add)
1234             address = base + imm32;
1235         else
1236             address = base - imm32;
1237 
1238         context.SetRegisterPlusOffset(pc_reg, address - base);
1239         data = MemURead(context, address, 4, 0, &success);
1240         if (!success)
1241             return false;
1242 
1243         if (Rt == 15)
1244         {
1245             if (Bits32(address, 1, 0) == 0)
1246             {
1247                 // In ARMv5T and above, this is an interworking branch.
1248                 if (!LoadWritePC(context, data))
1249                     return false;
1250             }
1251             else
1252                 return false;
1253         }
1254         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
1255         {
1256             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
1257                 return false;
1258         }
1259         else // We don't handle ARM for now.
1260             return false;
1261 
1262     }
1263     return true;
1264 }
1265 
1266 // An add operation to adjust the SP.
1267 // ADD (SP plus immediate)
1268 bool
1269 EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding)
1270 {
1271 #if 0
1272     // ARM pseudo code...
1273     if (ConditionPassed())
1274     {
1275         EncodingSpecificOperations();
1276         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1277         if d == 15 then // Can only occur for ARM encoding
1278             ALUWritePC(result); // setflags is always FALSE here
1279         else
1280             R[d] = result;
1281             if setflags then
1282                 APSR.N = result<31>;
1283                 APSR.Z = IsZeroBit(result);
1284                 APSR.C = carry;
1285                 APSR.V = overflow;
1286     }
1287 #endif
1288 
1289     bool success = false;
1290 
1291     if (ConditionPassed(opcode))
1292     {
1293         const addr_t sp = ReadCoreReg (SP_REG, &success);
1294         if (!success)
1295             return false;
1296         uint32_t imm32; // the immediate operand
1297         uint32_t d;
1298         bool setflags;
1299         switch (encoding)
1300         {
1301             case eEncodingT1:
1302                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1303                 d = Bits32 (opcode, 10, 8);
1304                 setflags = false;
1305                 imm32 = (Bits32 (opcode, 7, 0) << 2);
1306 
1307                 break;
1308 
1309             case eEncodingT2:
1310                 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1311                 d = 13;
1312                 setflags = false;
1313                 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1314 
1315                 break;
1316 
1317             default:
1318                 return false;
1319         }
1320         addr_t sp_offset = imm32;
1321         addr_t addr = sp + sp_offset; // the adjusted stack pointer value
1322 
1323         EmulateInstruction::Context context;
1324         context.type = EmulateInstruction::eContextAdjustStackPointer;
1325         RegisterInfo sp_reg;
1326         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1327         context.SetRegisterPlusOffset (sp_reg, sp_offset);
1328 
1329         if (d == 15)
1330         {
1331             if (!ALUWritePC (context, addr))
1332                 return false;
1333         }
1334         else
1335         {
1336             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr))
1337                 return false;
1338         }
1339     }
1340     return true;
1341 }
1342 
1343 // An add operation to adjust the SP.
1344 // ADD (SP plus register)
1345 bool
1346 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding)
1347 {
1348 #if 0
1349     // ARM pseudo code...
1350     if (ConditionPassed())
1351     {
1352         EncodingSpecificOperations();
1353         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1354         (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1355         if d == 15 then
1356             ALUWritePC(result); // setflags is always FALSE here
1357         else
1358             R[d] = result;
1359             if setflags then
1360                 APSR.N = result<31>;
1361                 APSR.Z = IsZeroBit(result);
1362                 APSR.C = carry;
1363                 APSR.V = overflow;
1364     }
1365 #endif
1366 
1367     bool success = false;
1368 
1369     if (ConditionPassed(opcode))
1370     {
1371         const addr_t sp = ReadCoreReg (SP_REG, &success);
1372         if (!success)
1373             return false;
1374         uint32_t Rm; // the second operand
1375         switch (encoding) {
1376         case eEncodingT2:
1377             Rm = Bits32(opcode, 6, 3);
1378             break;
1379         default:
1380             return false;
1381         }
1382         int32_t reg_value = ReadCoreReg(Rm, &success);
1383         if (!success)
1384             return false;
1385 
1386         addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1387 
1388         EmulateInstruction::Context context;
1389         context.type = eContextArithmetic;
1390         RegisterInfo sp_reg;
1391         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1392 
1393         RegisterInfo other_reg;
1394         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1395         context.SetRegisterRegisterOperands (sp_reg, other_reg);
1396 
1397         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
1398             return false;
1399     }
1400     return true;
1401 }
1402 
1403 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
1404 // at a PC-relative address, and changes instruction set from ARM to Thumb, or
1405 // from Thumb to ARM.
1406 // BLX (immediate)
1407 bool
1408 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding)
1409 {
1410 #if 0
1411     // ARM pseudo code...
1412     if (ConditionPassed())
1413     {
1414         EncodingSpecificOperations();
1415         if CurrentInstrSet() == InstrSet_ARM then
1416             LR = PC - 4;
1417         else
1418             LR = PC<31:1> : '1';
1419         if targetInstrSet == InstrSet_ARM then
1420             targetAddress = Align(PC,4) + imm32;
1421         else
1422             targetAddress = PC + imm32;
1423         SelectInstrSet(targetInstrSet);
1424         BranchWritePC(targetAddress);
1425     }
1426 #endif
1427 
1428     bool success = true;
1429 
1430     if (ConditionPassed(opcode))
1431     {
1432         EmulateInstruction::Context context;
1433         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1434         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1435         if (!success)
1436             return false;
1437         addr_t lr; // next instruction address
1438         addr_t target; // target address
1439         int32_t imm32; // PC-relative offset
1440         switch (encoding) {
1441         case eEncodingT1:
1442             {
1443             lr = pc | 1u; // return address
1444             uint32_t S = Bit32(opcode, 26);
1445             uint32_t imm10 = Bits32(opcode, 25, 16);
1446             uint32_t J1 = Bit32(opcode, 13);
1447             uint32_t J2 = Bit32(opcode, 11);
1448             uint32_t imm11 = Bits32(opcode, 10, 0);
1449             uint32_t I1 = !(J1 ^ S);
1450             uint32_t I2 = !(J2 ^ S);
1451             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1452             imm32 = llvm::SignExtend32<25>(imm25);
1453             target = pc + imm32;
1454             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
1455             if (InITBlock() && !LastInITBlock())
1456                 return false;
1457             break;
1458             }
1459         case eEncodingT2:
1460             {
1461             lr = pc | 1u; // return address
1462             uint32_t S = Bit32(opcode, 26);
1463             uint32_t imm10H = Bits32(opcode, 25, 16);
1464             uint32_t J1 = Bit32(opcode, 13);
1465             uint32_t J2 = Bit32(opcode, 11);
1466             uint32_t imm10L = Bits32(opcode, 10, 1);
1467             uint32_t I1 = !(J1 ^ S);
1468             uint32_t I2 = !(J2 ^ S);
1469             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
1470             imm32 = llvm::SignExtend32<25>(imm25);
1471             target = Align(pc, 4) + imm32;
1472             context.SetISAAndImmediateSigned (eModeARM, 4 + imm32);
1473             if (InITBlock() && !LastInITBlock())
1474                 return false;
1475             break;
1476             }
1477         case eEncodingA1:
1478             lr = pc - 4; // return address
1479             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1480             target = Align(pc, 4) + imm32;
1481             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
1482             break;
1483         case eEncodingA2:
1484             lr = pc - 4; // return address
1485             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
1486             target = pc + imm32;
1487             context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32);
1488             break;
1489         default:
1490             return false;
1491         }
1492         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1493             return false;
1494         if (!BranchWritePC(context, target))
1495             return false;
1496     }
1497     return true;
1498 }
1499 
1500 // Branch with Link and Exchange (register) calls a subroutine at an address and
1501 // instruction set specified by a register.
1502 // BLX (register)
1503 bool
1504 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding)
1505 {
1506 #if 0
1507     // ARM pseudo code...
1508     if (ConditionPassed())
1509     {
1510         EncodingSpecificOperations();
1511         target = R[m];
1512         if CurrentInstrSet() == InstrSet_ARM then
1513             next_instr_addr = PC - 4;
1514             LR = next_instr_addr;
1515         else
1516             next_instr_addr = PC - 2;
1517             LR = next_instr_addr<31:1> : '1';
1518         BXWritePC(target);
1519     }
1520 #endif
1521 
1522     bool success = false;
1523 
1524     if (ConditionPassed(opcode))
1525     {
1526         EmulateInstruction::Context context;
1527         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1528         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1529         addr_t lr; // next instruction address
1530         if (!success)
1531             return false;
1532         uint32_t Rm; // the register with the target address
1533         switch (encoding) {
1534         case eEncodingT1:
1535             lr = (pc - 2) | 1u; // return address
1536             Rm = Bits32(opcode, 6, 3);
1537             // if m == 15 then UNPREDICTABLE;
1538             if (Rm == 15)
1539                 return false;
1540             if (InITBlock() && !LastInITBlock())
1541                 return false;
1542             break;
1543         case eEncodingA1:
1544             lr = pc - 4; // return address
1545             Rm = Bits32(opcode, 3, 0);
1546             // if m == 15 then UNPREDICTABLE;
1547             if (Rm == 15)
1548                 return false;
1549             break;
1550         default:
1551             return false;
1552         }
1553         addr_t target = ReadCoreReg (Rm, &success);
1554         if (!success)
1555             return false;
1556         RegisterInfo dwarf_reg;
1557         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1558         context.SetRegister (dwarf_reg);
1559         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1560             return false;
1561         if (!BXWritePC(context, target))
1562             return false;
1563     }
1564     return true;
1565 }
1566 
1567 // Branch and Exchange causes a branch to an address and instruction set specified by a register.
1568 bool
1569 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding)
1570 {
1571 #if 0
1572     // ARM pseudo code...
1573     if (ConditionPassed())
1574     {
1575         EncodingSpecificOperations();
1576         BXWritePC(R[m]);
1577     }
1578 #endif
1579 
1580     if (ConditionPassed(opcode))
1581     {
1582         EmulateInstruction::Context context;
1583         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1584         uint32_t Rm; // the register with the target address
1585         switch (encoding) {
1586         case eEncodingT1:
1587             Rm = Bits32(opcode, 6, 3);
1588             if (InITBlock() && !LastInITBlock())
1589                 return false;
1590             break;
1591         case eEncodingA1:
1592             Rm = Bits32(opcode, 3, 0);
1593             break;
1594         default:
1595             return false;
1596         }
1597         bool success = false;
1598         addr_t target = ReadCoreReg (Rm, &success);
1599         if (!success)
1600             return false;
1601 
1602         RegisterInfo dwarf_reg;
1603         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1604         context.SetRegister (dwarf_reg);
1605         if (!BXWritePC(context, target))
1606             return false;
1607     }
1608     return true;
1609 }
1610 
1611 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an
1612 // address and instruction set specified by a register as though it were a BX instruction.
1613 //
1614 // TODO: Emulate Jazelle architecture?
1615 //       We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation.
1616 bool
1617 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding)
1618 {
1619 #if 0
1620     // ARM pseudo code...
1621     if (ConditionPassed())
1622     {
1623         EncodingSpecificOperations();
1624         if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
1625             BXWritePC(R[m]);
1626         else
1627             if JazelleAcceptsExecution() then
1628                 SwitchToJazelleExecution();
1629             else
1630                 SUBARCHITECTURE_DEFINED handler call;
1631     }
1632 #endif
1633 
1634     if (ConditionPassed(opcode))
1635     {
1636         EmulateInstruction::Context context;
1637         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1638         uint32_t Rm; // the register with the target address
1639         switch (encoding) {
1640         case eEncodingT1:
1641             Rm = Bits32(opcode, 19, 16);
1642             if (BadReg(Rm))
1643                 return false;
1644             if (InITBlock() && !LastInITBlock())
1645                 return false;
1646             break;
1647         case eEncodingA1:
1648             Rm = Bits32(opcode, 3, 0);
1649             if (Rm == 15)
1650                 return false;
1651             break;
1652         default:
1653             return false;
1654         }
1655         bool success = false;
1656         addr_t target = ReadCoreReg (Rm, &success);
1657         if (!success)
1658             return false;
1659 
1660         RegisterInfo dwarf_reg;
1661         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1662         context.SetRegister (dwarf_reg);
1663         if (!BXWritePC(context, target))
1664             return false;
1665     }
1666     return true;
1667 }
1668 
1669 // Set r7 to point to some ip offset.
1670 // SUB (immediate)
1671 bool
1672 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding)
1673 {
1674 #if 0
1675     // ARM pseudo code...
1676     if (ConditionPassed())
1677     {
1678         EncodingSpecificOperations();
1679         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1680         if d == 15 then // Can only occur for ARM encoding
1681            ALUWritePC(result); // setflags is always FALSE here
1682         else
1683             R[d] = result;
1684             if setflags then
1685                 APSR.N = result<31>;
1686                 APSR.Z = IsZeroBit(result);
1687                 APSR.C = carry;
1688                 APSR.V = overflow;
1689     }
1690 #endif
1691 
1692     if (ConditionPassed(opcode))
1693     {
1694         bool success = false;
1695         const addr_t ip = ReadCoreReg (12, &success);
1696         if (!success)
1697             return false;
1698         uint32_t imm32;
1699         switch (encoding) {
1700         case eEncodingA1:
1701             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1702             break;
1703         default:
1704             return false;
1705         }
1706         addr_t ip_offset = imm32;
1707         addr_t addr = ip - ip_offset; // the adjusted ip value
1708 
1709         EmulateInstruction::Context context;
1710         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1711         RegisterInfo dwarf_reg;
1712         GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg);
1713         context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
1714 
1715         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
1716             return false;
1717     }
1718     return true;
1719 }
1720 
1721 // Set ip to point to some stack offset.
1722 // SUB (SP minus immediate)
1723 bool
1724 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding)
1725 {
1726 #if 0
1727     // ARM pseudo code...
1728     if (ConditionPassed())
1729     {
1730         EncodingSpecificOperations();
1731         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1732         if d == 15 then // Can only occur for ARM encoding
1733            ALUWritePC(result); // setflags is always FALSE here
1734         else
1735             R[d] = result;
1736             if setflags then
1737                 APSR.N = result<31>;
1738                 APSR.Z = IsZeroBit(result);
1739                 APSR.C = carry;
1740                 APSR.V = overflow;
1741     }
1742 #endif
1743 
1744     if (ConditionPassed(opcode))
1745     {
1746         bool success = false;
1747         const addr_t sp = ReadCoreReg (SP_REG, &success);
1748         if (!success)
1749             return false;
1750         uint32_t imm32;
1751         switch (encoding) {
1752         case eEncodingA1:
1753             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1754             break;
1755         default:
1756             return false;
1757         }
1758         addr_t sp_offset = imm32;
1759         addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1760 
1761         EmulateInstruction::Context context;
1762         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1763         RegisterInfo dwarf_reg;
1764         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
1765         context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
1766 
1767         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
1768             return false;
1769     }
1770     return true;
1771 }
1772 
1773 // This instruction subtracts an immediate value from the SP value, and writes
1774 // the result to the destination register.
1775 //
1776 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage.
1777 bool
1778 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding)
1779 {
1780 #if 0
1781     // ARM pseudo code...
1782     if (ConditionPassed())
1783     {
1784         EncodingSpecificOperations();
1785         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1786         if d == 15 then        // Can only occur for ARM encoding
1787            ALUWritePC(result); // setflags is always FALSE here
1788         else
1789             R[d] = result;
1790             if setflags then
1791                 APSR.N = result<31>;
1792                 APSR.Z = IsZeroBit(result);
1793                 APSR.C = carry;
1794                 APSR.V = overflow;
1795     }
1796 #endif
1797 
1798     bool success = false;
1799     if (ConditionPassed(opcode))
1800     {
1801         const addr_t sp = ReadCoreReg (SP_REG, &success);
1802         if (!success)
1803             return false;
1804 
1805         uint32_t Rd;
1806         bool setflags;
1807         uint32_t imm32;
1808         switch (encoding) {
1809         case eEncodingT1:
1810             Rd = 13;
1811             setflags = false;
1812             imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1813             break;
1814         case eEncodingT2:
1815             Rd = Bits32(opcode, 11, 8);
1816             setflags = BitIsSet(opcode, 20);
1817             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1818             if (Rd == 15 && setflags)
1819                 return EmulateCMPImm(opcode, eEncodingT2);
1820             if (Rd == 15 && !setflags)
1821                 return false;
1822             break;
1823         case eEncodingT3:
1824             Rd = Bits32(opcode, 11, 8);
1825             setflags = false;
1826             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
1827             if (Rd == 15)
1828                 return false;
1829             break;
1830         case eEncodingA1:
1831             Rd = Bits32(opcode, 15, 12);
1832             setflags = BitIsSet(opcode, 20);
1833             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1834 
1835             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1836             if (Rd == 15 && setflags)
1837                 return EmulateSUBSPcLrEtc (opcode, encoding);
1838             break;
1839         default:
1840             return false;
1841         }
1842         AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
1843 
1844         EmulateInstruction::Context context;
1845         if (Rd == 13)
1846         {
1847             uint64_t imm64 = imm32;  // Need to expand it to 64 bits before attempting to negate it, or the wrong
1848                                      // value gets passed down to context.SetImmediateSigned.
1849             context.type = EmulateInstruction::eContextAdjustStackPointer;
1850             context.SetImmediateSigned (-imm64); // the stack pointer offset
1851         }
1852         else
1853         {
1854             context.type = EmulateInstruction::eContextImmediate;
1855             context.SetNoArgs ();
1856         }
1857 
1858         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
1859             return false;
1860     }
1861     return true;
1862 }
1863 
1864 // A store operation to the stack that also updates the SP.
1865 bool
1866 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding)
1867 {
1868 #if 0
1869     // ARM pseudo code...
1870     if (ConditionPassed())
1871     {
1872         EncodingSpecificOperations();
1873         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1874         address = if index then offset_addr else R[n];
1875         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1876         if wback then R[n] = offset_addr;
1877     }
1878 #endif
1879 
1880     bool conditional = false;
1881     bool success = false;
1882     if (ConditionPassed(opcode, &conditional))
1883     {
1884         const uint32_t addr_byte_size = GetAddressByteSize();
1885         const addr_t sp = ReadCoreReg (SP_REG, &success);
1886         if (!success)
1887             return false;
1888         uint32_t Rt; // the source register
1889         uint32_t imm12;
1890         uint32_t Rn;  // This function assumes Rn is the SP, but we should verify that.
1891 
1892         bool index;
1893         bool add;
1894         bool wback;
1895         switch (encoding) {
1896         case eEncodingA1:
1897             Rt = Bits32(opcode, 15, 12);
1898             imm12 = Bits32(opcode, 11, 0);
1899             Rn = Bits32 (opcode, 19, 16);
1900 
1901             if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
1902                 return false;
1903 
1904             index = BitIsSet (opcode, 24);
1905             add = BitIsSet (opcode, 23);
1906             wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
1907 
1908             if (wback && ((Rn == 15) || (Rn == Rt)))
1909                 return false;
1910             break;
1911         default:
1912             return false;
1913         }
1914         addr_t offset_addr;
1915         if (add)
1916             offset_addr = sp + imm12;
1917         else
1918             offset_addr = sp - imm12;
1919 
1920         addr_t addr;
1921         if (index)
1922             addr = offset_addr;
1923         else
1924             addr = sp;
1925 
1926         EmulateInstruction::Context context;
1927         if (conditional)
1928             context.type = EmulateInstruction::eContextRegisterStore;
1929         else
1930             context.type = EmulateInstruction::eContextPushRegisterOnStack;
1931         RegisterInfo sp_reg;
1932         RegisterInfo dwarf_reg;
1933 
1934         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1935         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
1936         context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
1937         if (Rt != 15)
1938         {
1939             uint32_t reg_value = ReadCoreReg(Rt, &success);
1940             if (!success)
1941                 return false;
1942             if (!MemUWrite (context, addr, reg_value, addr_byte_size))
1943                 return false;
1944         }
1945         else
1946         {
1947             const uint32_t pc = ReadCoreReg(PC_REG, &success);
1948             if (!success)
1949                 return false;
1950             if (!MemUWrite (context, addr, pc, addr_byte_size))
1951                 return false;
1952         }
1953 
1954 
1955         if (wback)
1956         {
1957             context.type = EmulateInstruction::eContextAdjustStackPointer;
1958             context.SetImmediateSigned (addr - sp);
1959             if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr))
1960                 return false;
1961         }
1962     }
1963     return true;
1964 }
1965 
1966 // Vector Push stores multiple extension registers to the stack.
1967 // It also updates SP to point to the start of the stored data.
1968 bool
1969 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding)
1970 {
1971 #if 0
1972     // ARM pseudo code...
1973     if (ConditionPassed())
1974     {
1975         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1976         address = SP - imm32;
1977         SP = SP - imm32;
1978         if single_regs then
1979             for r = 0 to regs-1
1980                 MemA[address,4] = S[d+r]; address = address+4;
1981         else
1982             for r = 0 to regs-1
1983                 // Store as two word-aligned words in the correct order for current endianness.
1984                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
1985                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
1986                 address = address+8;
1987     }
1988 #endif
1989 
1990     bool success = false;
1991     bool conditional = false;
1992     if (ConditionPassed(opcode, &conditional))
1993     {
1994         const uint32_t addr_byte_size = GetAddressByteSize();
1995         const addr_t sp = ReadCoreReg (SP_REG, &success);
1996         if (!success)
1997             return false;
1998         bool single_regs;
1999         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2000         uint32_t imm32; // stack offset
2001         uint32_t regs;  // number of registers
2002         switch (encoding) {
2003         case eEncodingT1:
2004         case eEncodingA1:
2005             single_regs = false;
2006             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2007             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2008             // If UInt(imm8) is odd, see "FSTMX".
2009             regs = Bits32(opcode, 7, 0) / 2;
2010             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2011             if (regs == 0 || regs > 16 || (d + regs) > 32)
2012                 return false;
2013             break;
2014         case eEncodingT2:
2015         case eEncodingA2:
2016             single_regs = true;
2017             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2018             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2019             regs = Bits32(opcode, 7, 0);
2020             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2021             if (regs == 0 || regs > 16 || (d + regs) > 32)
2022                 return false;
2023             break;
2024         default:
2025             return false;
2026         }
2027         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2028         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2029         addr_t sp_offset = imm32;
2030         addr_t addr = sp - sp_offset;
2031         uint32_t i;
2032 
2033         EmulateInstruction::Context context;
2034         if (conditional)
2035             context.type = EmulateInstruction::eContextRegisterStore;
2036         else
2037             context.type = EmulateInstruction::eContextPushRegisterOnStack;
2038         RegisterInfo dwarf_reg;
2039         RegisterInfo sp_reg;
2040         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2041         for (i=0; i<regs; ++i)
2042         {
2043             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2044             context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
2045             // uint64_t to accommodate 64-bit registers.
2046             uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success);
2047             if (!success)
2048                 return false;
2049             if (!MemAWrite (context, addr, reg_value, reg_byte_size))
2050                 return false;
2051             addr += reg_byte_size;
2052         }
2053 
2054         context.type = EmulateInstruction::eContextAdjustStackPointer;
2055         context.SetImmediateSigned (-sp_offset);
2056 
2057         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2058             return false;
2059     }
2060     return true;
2061 }
2062 
2063 // Vector Pop loads multiple extension registers from the stack.
2064 // It also updates SP to point just above the loaded data.
2065 bool
2066 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding)
2067 {
2068 #if 0
2069     // ARM pseudo code...
2070     if (ConditionPassed())
2071     {
2072         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2073         address = SP;
2074         SP = SP + imm32;
2075         if single_regs then
2076             for r = 0 to regs-1
2077                 S[d+r] = MemA[address,4]; address = address+4;
2078         else
2079             for r = 0 to regs-1
2080                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2081                 // Combine the word-aligned words in the correct order for current endianness.
2082                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2083     }
2084 #endif
2085 
2086     bool success = false;
2087     bool conditional = false;
2088     if (ConditionPassed(opcode, &conditional))
2089     {
2090         const uint32_t addr_byte_size = GetAddressByteSize();
2091         const addr_t sp = ReadCoreReg (SP_REG, &success);
2092         if (!success)
2093             return false;
2094         bool single_regs;
2095         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2096         uint32_t imm32; // stack offset
2097         uint32_t regs;  // number of registers
2098         switch (encoding) {
2099         case eEncodingT1:
2100         case eEncodingA1:
2101             single_regs = false;
2102             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2103             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2104             // If UInt(imm8) is odd, see "FLDMX".
2105             regs = Bits32(opcode, 7, 0) / 2;
2106             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2107             if (regs == 0 || regs > 16 || (d + regs) > 32)
2108                 return false;
2109             break;
2110         case eEncodingT2:
2111         case eEncodingA2:
2112             single_regs = true;
2113             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2114             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2115             regs = Bits32(opcode, 7, 0);
2116             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2117             if (regs == 0 || regs > 16 || (d + regs) > 32)
2118                 return false;
2119             break;
2120         default:
2121             return false;
2122         }
2123         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2124         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2125         addr_t sp_offset = imm32;
2126         addr_t addr = sp;
2127         uint32_t i;
2128         uint64_t data; // uint64_t to accomodate 64-bit registers.
2129 
2130         EmulateInstruction::Context context;
2131         if (conditional)
2132             context.type = EmulateInstruction::eContextRegisterLoad;
2133         else
2134             context.type = EmulateInstruction::eContextPopRegisterOffStack;
2135         RegisterInfo dwarf_reg;
2136         RegisterInfo sp_reg;
2137         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2138         for (i=0; i<regs; ++i)
2139         {
2140             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2141             context.SetRegisterPlusOffset (sp_reg, addr - sp);
2142             data = MemARead(context, addr, reg_byte_size, 0, &success);
2143             if (!success)
2144                 return false;
2145             if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2146                 return false;
2147             addr += reg_byte_size;
2148         }
2149 
2150         context.type = EmulateInstruction::eContextAdjustStackPointer;
2151         context.SetImmediateSigned (sp_offset);
2152 
2153         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2154             return false;
2155     }
2156     return true;
2157 }
2158 
2159 // SVC (previously SWI)
2160 bool
2161 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding)
2162 {
2163 #if 0
2164     // ARM pseudo code...
2165     if (ConditionPassed())
2166     {
2167         EncodingSpecificOperations();
2168         CallSupervisor();
2169     }
2170 #endif
2171 
2172     bool success = false;
2173 
2174     if (ConditionPassed(opcode))
2175     {
2176         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2177         addr_t lr; // next instruction address
2178         if (!success)
2179             return false;
2180         uint32_t imm32; // the immediate constant
2181         uint32_t mode;  // ARM or Thumb mode
2182         switch (encoding) {
2183         case eEncodingT1:
2184             lr = (pc + 2) | 1u; // return address
2185             imm32 = Bits32(opcode, 7, 0);
2186             mode = eModeThumb;
2187             break;
2188         case eEncodingA1:
2189             lr = pc + 4; // return address
2190             imm32 = Bits32(opcode, 23, 0);
2191             mode = eModeARM;
2192             break;
2193         default:
2194             return false;
2195         }
2196 
2197         EmulateInstruction::Context context;
2198         context.type = EmulateInstruction::eContextSupervisorCall;
2199         context.SetISAAndImmediate (mode, imm32);
2200         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
2201             return false;
2202     }
2203     return true;
2204 }
2205 
2206 // If Then makes up to four following instructions (the IT block) conditional.
2207 bool
2208 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding)
2209 {
2210 #if 0
2211     // ARM pseudo code...
2212     EncodingSpecificOperations();
2213     ITSTATE.IT<7:0> = firstcond:mask;
2214 #endif
2215 
2216     m_it_session.InitIT(Bits32(opcode, 7, 0));
2217     return true;
2218 }
2219 
2220 bool
2221 EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding)
2222 {
2223     // NOP, nothing to do...
2224     return true;
2225 }
2226 
2227 // Branch causes a branch to a target address.
2228 bool
2229 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding)
2230 {
2231 #if 0
2232     // ARM pseudo code...
2233     if (ConditionPassed())
2234     {
2235         EncodingSpecificOperations();
2236         BranchWritePC(PC + imm32);
2237     }
2238 #endif
2239 
2240     bool success = false;
2241 
2242     if (ConditionPassed(opcode))
2243     {
2244         EmulateInstruction::Context context;
2245         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2246         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2247         if (!success)
2248             return false;
2249         addr_t target; // target address
2250         int32_t imm32; // PC-relative offset
2251         switch (encoding) {
2252         case eEncodingT1:
2253             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2254             imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2255             target = pc + imm32;
2256             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2257             break;
2258         case eEncodingT2:
2259             imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0));
2260             target = pc + imm32;
2261             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2262             break;
2263         case eEncodingT3:
2264             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2265             {
2266             uint32_t S = Bit32(opcode, 26);
2267             uint32_t imm6 = Bits32(opcode, 21, 16);
2268             uint32_t J1 = Bit32(opcode, 13);
2269             uint32_t J2 = Bit32(opcode, 11);
2270             uint32_t imm11 = Bits32(opcode, 10, 0);
2271             uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2272             imm32 = llvm::SignExtend32<21>(imm21);
2273             target = pc + imm32;
2274             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2275             break;
2276             }
2277         case eEncodingT4:
2278             {
2279             uint32_t S = Bit32(opcode, 26);
2280             uint32_t imm10 = Bits32(opcode, 25, 16);
2281             uint32_t J1 = Bit32(opcode, 13);
2282             uint32_t J2 = Bit32(opcode, 11);
2283             uint32_t imm11 = Bits32(opcode, 10, 0);
2284             uint32_t I1 = !(J1 ^ S);
2285             uint32_t I2 = !(J2 ^ S);
2286             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2287             imm32 = llvm::SignExtend32<25>(imm25);
2288             target = pc + imm32;
2289             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2290             break;
2291             }
2292         case eEncodingA1:
2293             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2294             target = pc + imm32;
2295             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
2296             break;
2297         default:
2298             return false;
2299         }
2300         if (!BranchWritePC(context, target))
2301             return false;
2302     }
2303     return true;
2304 }
2305 
2306 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
2307 // zero and conditionally branch forward a constant value.  They do not affect the condition flags.
2308 // CBNZ, CBZ
2309 bool
2310 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding)
2311 {
2312 #if 0
2313     // ARM pseudo code...
2314     EncodingSpecificOperations();
2315     if nonzero ^ IsZero(R[n]) then
2316         BranchWritePC(PC + imm32);
2317 #endif
2318 
2319     bool success = false;
2320 
2321     // Read the register value from the operand register Rn.
2322     uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2323     if (!success)
2324         return false;
2325 
2326     EmulateInstruction::Context context;
2327     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2328     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2329     if (!success)
2330         return false;
2331 
2332     addr_t target;  // target address
2333     uint32_t imm32; // PC-relative offset to branch forward
2334     bool nonzero;
2335     switch (encoding) {
2336     case eEncodingT1:
2337         imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2338         nonzero = BitIsSet(opcode, 11);
2339         target = pc + imm32;
2340         context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2341         break;
2342     default:
2343         return false;
2344     }
2345     if (nonzero ^ (reg_val == 0))
2346         if (!BranchWritePC(context, target))
2347             return false;
2348 
2349     return true;
2350 }
2351 
2352 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
2353 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2354 // The branch length is twice the value of the byte returned from the table.
2355 //
2356 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
2357 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2358 // The branch length is twice the value of the halfword returned from the table.
2359 // TBB, TBH
2360 bool
2361 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding)
2362 {
2363 #if 0
2364     // ARM pseudo code...
2365     EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2366     if is_tbh then
2367         halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2368     else
2369         halfwords = UInt(MemU[R[n]+R[m], 1]);
2370     BranchWritePC(PC + 2*halfwords);
2371 #endif
2372 
2373     bool success = false;
2374 
2375     uint32_t Rn;     // the base register which contains the address of the table of branch lengths
2376     uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
2377     bool is_tbh;     // true if table branch halfword
2378     switch (encoding) {
2379     case eEncodingT1:
2380         Rn = Bits32(opcode, 19, 16);
2381         Rm = Bits32(opcode, 3, 0);
2382         is_tbh = BitIsSet(opcode, 4);
2383         if (Rn == 13 || BadReg(Rm))
2384             return false;
2385         if (InITBlock() && !LastInITBlock())
2386             return false;
2387         break;
2388     default:
2389         return false;
2390     }
2391 
2392     // Read the address of the table from the operand register Rn.
2393     // The PC can be used, in which case the table immediately follows this instruction.
2394     uint32_t base = ReadCoreReg(Rm, &success);
2395     if (!success)
2396         return false;
2397 
2398     // the table index
2399     uint32_t index = ReadCoreReg(Rm, &success);
2400     if (!success)
2401         return false;
2402 
2403     // the offsetted table address
2404     addr_t addr = base + (is_tbh ? index*2 : index);
2405 
2406     // PC-relative offset to branch forward
2407     EmulateInstruction::Context context;
2408     context.type = EmulateInstruction::eContextTableBranchReadMemory;
2409     uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2410     if (!success)
2411         return false;
2412 
2413     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2414     if (!success)
2415         return false;
2416 
2417     // target address
2418     addr_t target = pc + offset;
2419     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2420     context.SetISAAndImmediateSigned (eModeThumb, 4 + offset);
2421 
2422     if (!BranchWritePC(context, target))
2423         return false;
2424 
2425     return true;
2426 }
2427 
2428 // This instruction adds an immediate value to a register value, and writes the result to the destination register.
2429 // It can optionally update the condition flags based on the result.
2430 bool
2431 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding)
2432 {
2433 #if 0
2434     if ConditionPassed() then
2435         EncodingSpecificOperations();
2436         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2437         R[d] = result;
2438         if setflags then
2439             APSR.N = result<31>;
2440             APSR.Z = IsZeroBit(result);
2441             APSR.C = carry;
2442             APSR.V = overflow;
2443 #endif
2444 
2445     bool success = false;
2446 
2447     if (ConditionPassed(opcode))
2448     {
2449         uint32_t d;
2450         uint32_t n;
2451         bool setflags;
2452         uint32_t imm32;
2453         uint32_t carry_out;
2454 
2455         //EncodingSpecificOperations();
2456         switch (encoding)
2457         {
2458             case eEncodingT1:
2459                 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32);
2460                 d = Bits32 (opcode, 2, 0);
2461                 n = Bits32 (opcode, 5, 3);
2462                 setflags = !InITBlock();
2463                 imm32 = Bits32 (opcode, 8,6);
2464 
2465                 break;
2466 
2467             case eEncodingT2:
2468                 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32);
2469                 d = Bits32 (opcode, 10, 8);
2470                 n = Bits32 (opcode, 10, 8);
2471                 setflags = !InITBlock();
2472                 imm32 = Bits32 (opcode, 7, 0);
2473 
2474                 break;
2475 
2476             case eEncodingT3:
2477                 // if Rd == '1111' && S == '1' then SEE CMN (immediate);
2478                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2479                 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8);
2480                 d = Bits32 (opcode, 11, 8);
2481                 n = Bits32 (opcode, 19, 16);
2482                 setflags = BitIsSet (opcode, 20);
2483                 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out);
2484 
2485                 // if BadReg(d) || n == 15 then UNPREDICTABLE;
2486                 if (BadReg (d) || (n == 15))
2487                     return false;
2488 
2489                 break;
2490 
2491             case eEncodingT4:
2492             {
2493                 // if Rn == '1111' then SEE ADR;
2494                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2495                 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
2496                 d = Bits32 (opcode, 11, 8);
2497                 n = Bits32 (opcode, 19, 16);
2498                 setflags = false;
2499                 uint32_t i = Bit32 (opcode, 26);
2500                 uint32_t imm3 = Bits32 (opcode, 14, 12);
2501                 uint32_t imm8 = Bits32 (opcode, 7, 0);
2502                 imm32 = (i << 11) | (imm3 << 8) | imm8;
2503 
2504                 // if BadReg(d) then UNPREDICTABLE;
2505                 if (BadReg (d))
2506                     return false;
2507 
2508                 break;
2509             }
2510             default:
2511                 return false;
2512         }
2513 
2514         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2515         if (!success)
2516             return false;
2517 
2518         //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2519         AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
2520 
2521         RegisterInfo reg_n;
2522         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
2523 
2524         EmulateInstruction::Context context;
2525         context.type = eContextArithmetic;
2526         context.SetRegisterPlusOffset (reg_n, imm32);
2527 
2528         //R[d] = result;
2529         //if setflags then
2530             //APSR.N = result<31>;
2531             //APSR.Z = IsZeroBit(result);
2532             //APSR.C = carry;
2533             //APSR.V = overflow;
2534         if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
2535             return false;
2536 
2537     }
2538     return true;
2539 }
2540 
2541 // This instruction adds an immediate value to a register value, and writes the result to the destination
2542 // register.  It can optionally update the condition flags based on the result.
2543 bool
2544 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding)
2545 {
2546 #if 0
2547     // ARM pseudo code...
2548     if ConditionPassed() then
2549         EncodingSpecificOperations();
2550         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2551         if d == 15 then
2552             ALUWritePC(result); // setflags is always FALSE here
2553         else
2554             R[d] = result;
2555             if setflags then
2556                 APSR.N = result<31>;
2557                 APSR.Z = IsZeroBit(result);
2558                 APSR.C = carry;
2559                 APSR.V = overflow;
2560 #endif
2561 
2562     bool success = false;
2563 
2564     if (ConditionPassed(opcode))
2565     {
2566         uint32_t Rd, Rn;
2567         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
2568         bool setflags;
2569         switch (encoding)
2570         {
2571         case eEncodingA1:
2572             Rd = Bits32(opcode, 15, 12);
2573             Rn = Bits32(opcode, 19, 16);
2574             setflags = BitIsSet(opcode, 20);
2575             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2576             break;
2577         default:
2578             return false;
2579         }
2580 
2581         // Read the first operand.
2582         uint32_t val1 = ReadCoreReg(Rn, &success);
2583         if (!success)
2584             return false;
2585 
2586         AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
2587 
2588         EmulateInstruction::Context context;
2589         context.type = eContextArithmetic;
2590         RegisterInfo dwarf_reg;
2591         GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
2592         context.SetRegisterPlusOffset (dwarf_reg, imm32);
2593 
2594         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2595             return false;
2596     }
2597     return true;
2598 }
2599 
2600 // This instruction adds a register value and an optionally-shifted register value, and writes the result
2601 // to the destination register. It can optionally update the condition flags based on the result.
2602 bool
2603 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding)
2604 {
2605 #if 0
2606     // ARM pseudo code...
2607     if ConditionPassed() then
2608         EncodingSpecificOperations();
2609         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2610         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2611         if d == 15 then
2612             ALUWritePC(result); // setflags is always FALSE here
2613         else
2614             R[d] = result;
2615             if setflags then
2616                 APSR.N = result<31>;
2617                 APSR.Z = IsZeroBit(result);
2618                 APSR.C = carry;
2619                 APSR.V = overflow;
2620 #endif
2621 
2622     bool success = false;
2623 
2624     if (ConditionPassed(opcode))
2625     {
2626         uint32_t Rd, Rn, Rm;
2627         ARM_ShifterType shift_t;
2628         uint32_t shift_n; // the shift applied to the value read from Rm
2629         bool setflags;
2630         switch (encoding)
2631         {
2632         case eEncodingT1:
2633             Rd = Bits32(opcode, 2, 0);
2634             Rn = Bits32(opcode, 5, 3);
2635             Rm = Bits32(opcode, 8, 6);
2636             setflags = !InITBlock();
2637             shift_t = SRType_LSL;
2638             shift_n = 0;
2639             break;
2640         case eEncodingT2:
2641             Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2642             Rm = Bits32(opcode, 6, 3);
2643             setflags = false;
2644             shift_t = SRType_LSL;
2645             shift_n = 0;
2646             if (Rn == 15 && Rm == 15)
2647                 return false;
2648             if (Rd == 15 && InITBlock() && !LastInITBlock())
2649                 return false;
2650             break;
2651         case eEncodingA1:
2652             Rd = Bits32(opcode, 15, 12);
2653             Rn = Bits32(opcode, 19, 16);
2654             Rm = Bits32(opcode, 3, 0);
2655             setflags = BitIsSet(opcode, 20);
2656             shift_n = DecodeImmShiftARM(opcode, shift_t);
2657             break;
2658         default:
2659             return false;
2660         }
2661 
2662         // Read the first operand.
2663         uint32_t val1 = ReadCoreReg(Rn, &success);
2664         if (!success)
2665             return false;
2666 
2667         // Read the second operand.
2668         uint32_t val2 = ReadCoreReg(Rm, &success);
2669         if (!success)
2670             return false;
2671 
2672         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2673         if (!success)
2674             return false;
2675         AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2676 
2677         EmulateInstruction::Context context;
2678         context.type = eContextArithmetic;
2679         RegisterInfo op1_reg;
2680         RegisterInfo op2_reg;
2681         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
2682         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
2683         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
2684 
2685         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2686             return false;
2687     }
2688     return true;
2689 }
2690 
2691 // Compare Negative (immediate) adds a register value and an immediate value.
2692 // It updates the condition flags based on the result, and discards the result.
2693 bool
2694 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding)
2695 {
2696 #if 0
2697     // ARM pseudo code...
2698     if ConditionPassed() then
2699         EncodingSpecificOperations();
2700         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2701         APSR.N = result<31>;
2702         APSR.Z = IsZeroBit(result);
2703         APSR.C = carry;
2704         APSR.V = overflow;
2705 #endif
2706 
2707     bool success = false;
2708 
2709     uint32_t Rn; // the first operand
2710     uint32_t imm32; // the immediate value to be compared with
2711     switch (encoding) {
2712     case eEncodingT1:
2713         Rn = Bits32(opcode, 19, 16);
2714         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2715         if (Rn == 15)
2716             return false;
2717         break;
2718     case eEncodingA1:
2719         Rn = Bits32(opcode, 19, 16);
2720         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2721         break;
2722     default:
2723         return false;
2724     }
2725     // Read the register value from the operand register Rn.
2726     uint32_t reg_val = ReadCoreReg(Rn, &success);
2727     if (!success)
2728         return false;
2729 
2730     AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
2731 
2732     EmulateInstruction::Context context;
2733     context.type = EmulateInstruction::eContextImmediate;
2734     context.SetNoArgs ();
2735     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2736         return false;
2737 
2738     return true;
2739 }
2740 
2741 // Compare Negative (register) adds a register value and an optionally-shifted register value.
2742 // It updates the condition flags based on the result, and discards the result.
2743 bool
2744 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding)
2745 {
2746 #if 0
2747     // ARM pseudo code...
2748     if ConditionPassed() then
2749         EncodingSpecificOperations();
2750         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2751         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2752         APSR.N = result<31>;
2753         APSR.Z = IsZeroBit(result);
2754         APSR.C = carry;
2755         APSR.V = overflow;
2756 #endif
2757 
2758     bool success = false;
2759 
2760     uint32_t Rn; // the first operand
2761     uint32_t Rm; // the second operand
2762     ARM_ShifterType shift_t;
2763     uint32_t shift_n; // the shift applied to the value read from Rm
2764     switch (encoding) {
2765     case eEncodingT1:
2766         Rn = Bits32(opcode, 2, 0);
2767         Rm = Bits32(opcode, 5, 3);
2768         shift_t = SRType_LSL;
2769         shift_n = 0;
2770         break;
2771     case eEncodingT2:
2772         Rn = Bits32(opcode, 19, 16);
2773         Rm = Bits32(opcode, 3, 0);
2774         shift_n = DecodeImmShiftThumb(opcode, shift_t);
2775         // if n == 15 || BadReg(m) then UNPREDICTABLE;
2776         if (Rn == 15 || BadReg(Rm))
2777             return false;
2778         break;
2779     case eEncodingA1:
2780         Rn = Bits32(opcode, 19, 16);
2781         Rm = Bits32(opcode, 3, 0);
2782         shift_n = DecodeImmShiftARM(opcode, shift_t);
2783         break;
2784     default:
2785         return false;
2786     }
2787     // Read the register value from register Rn.
2788     uint32_t val1 = ReadCoreReg(Rn, &success);
2789     if (!success)
2790         return false;
2791 
2792     // Read the register value from register Rm.
2793     uint32_t val2 = ReadCoreReg(Rm, &success);
2794     if (!success)
2795         return false;
2796 
2797     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2798     if (!success)
2799         return false;
2800     AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2801 
2802     EmulateInstruction::Context context;
2803     context.type = EmulateInstruction::eContextImmediate;
2804     context.SetNoArgs();
2805     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2806         return false;
2807 
2808     return true;
2809 }
2810 
2811 // Compare (immediate) subtracts an immediate value from a register value.
2812 // It updates the condition flags based on the result, and discards the result.
2813 bool
2814 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding)
2815 {
2816 #if 0
2817     // ARM pseudo code...
2818     if ConditionPassed() then
2819         EncodingSpecificOperations();
2820         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2821         APSR.N = result<31>;
2822         APSR.Z = IsZeroBit(result);
2823         APSR.C = carry;
2824         APSR.V = overflow;
2825 #endif
2826 
2827     bool success = false;
2828 
2829     uint32_t Rn; // the first operand
2830     uint32_t imm32; // the immediate value to be compared with
2831     switch (encoding) {
2832     case eEncodingT1:
2833         Rn = Bits32(opcode, 10, 8);
2834         imm32 = Bits32(opcode, 7, 0);
2835         break;
2836     case eEncodingT2:
2837         Rn = Bits32(opcode, 19, 16);
2838         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2839         if (Rn == 15)
2840             return false;
2841         break;
2842     case eEncodingA1:
2843         Rn = Bits32(opcode, 19, 16);
2844         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2845         break;
2846     default:
2847         return false;
2848     }
2849     // Read the register value from the operand register Rn.
2850     uint32_t reg_val = ReadCoreReg(Rn, &success);
2851     if (!success)
2852         return false;
2853 
2854     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
2855 
2856     EmulateInstruction::Context context;
2857     context.type = EmulateInstruction::eContextImmediate;
2858     context.SetNoArgs ();
2859     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2860         return false;
2861 
2862     return true;
2863 }
2864 
2865 // Compare (register) subtracts an optionally-shifted register value from a register value.
2866 // It updates the condition flags based on the result, and discards the result.
2867 bool
2868 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding)
2869 {
2870 #if 0
2871     // ARM pseudo code...
2872     if ConditionPassed() then
2873         EncodingSpecificOperations();
2874         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2875         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2876         APSR.N = result<31>;
2877         APSR.Z = IsZeroBit(result);
2878         APSR.C = carry;
2879         APSR.V = overflow;
2880 #endif
2881 
2882     bool success = false;
2883 
2884     uint32_t Rn; // the first operand
2885     uint32_t Rm; // the second operand
2886     ARM_ShifterType shift_t;
2887     uint32_t shift_n; // the shift applied to the value read from Rm
2888     switch (encoding) {
2889     case eEncodingT1:
2890         Rn = Bits32(opcode, 2, 0);
2891         Rm = Bits32(opcode, 5, 3);
2892         shift_t = SRType_LSL;
2893         shift_n = 0;
2894         break;
2895     case eEncodingT2:
2896         Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2897         Rm = Bits32(opcode, 6, 3);
2898         shift_t = SRType_LSL;
2899         shift_n = 0;
2900         if (Rn < 8 && Rm < 8)
2901             return false;
2902         if (Rn == 15 || Rm == 15)
2903             return false;
2904         break;
2905     case eEncodingA1:
2906         Rn = Bits32(opcode, 19, 16);
2907         Rm = Bits32(opcode, 3, 0);
2908         shift_n = DecodeImmShiftARM(opcode, shift_t);
2909         break;
2910     default:
2911         return false;
2912     }
2913     // Read the register value from register Rn.
2914     uint32_t val1 = ReadCoreReg(Rn, &success);
2915     if (!success)
2916         return false;
2917 
2918     // Read the register value from register Rm.
2919     uint32_t val2 = ReadCoreReg(Rm, &success);
2920     if (!success)
2921         return false;
2922 
2923     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2924     if (!success)
2925         return false;
2926     AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
2927 
2928     EmulateInstruction::Context context;
2929     context.type = EmulateInstruction::eContextImmediate;
2930     context.SetNoArgs();
2931     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2932         return false;
2933 
2934     return true;
2935 }
2936 
2937 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
2938 // shifting in copies of its sign bit, and writes the result to the destination register.  It can
2939 // optionally update the condition flags based on the result.
2940 bool
2941 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding)
2942 {
2943 #if 0
2944     // ARM pseudo code...
2945     if ConditionPassed() then
2946         EncodingSpecificOperations();
2947         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2948         if d == 15 then         // Can only occur for ARM encoding
2949             ALUWritePC(result); // setflags is always FALSE here
2950         else
2951             R[d] = result;
2952             if setflags then
2953                 APSR.N = result<31>;
2954                 APSR.Z = IsZeroBit(result);
2955                 APSR.C = carry;
2956                 // APSR.V unchanged
2957 #endif
2958 
2959     return EmulateShiftImm (opcode, encoding, SRType_ASR);
2960 }
2961 
2962 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
2963 // shifting in copies of its sign bit, and writes the result to the destination register.
2964 // The variable number of bits is read from the bottom byte of a register. It can optionally update
2965 // the condition flags based on the result.
2966 bool
2967 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding)
2968 {
2969 #if 0
2970     // ARM pseudo code...
2971     if ConditionPassed() then
2972         EncodingSpecificOperations();
2973         shift_n = UInt(R[m]<7:0>);
2974         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2975         R[d] = result;
2976         if setflags then
2977             APSR.N = result<31>;
2978             APSR.Z = IsZeroBit(result);
2979             APSR.C = carry;
2980             // APSR.V unchanged
2981 #endif
2982 
2983     return EmulateShiftReg (opcode, encoding, SRType_ASR);
2984 }
2985 
2986 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
2987 // shifting in zeros, and writes the result to the destination register.  It can optionally
2988 // update the condition flags based on the result.
2989 bool
2990 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding)
2991 {
2992 #if 0
2993     // ARM pseudo code...
2994     if ConditionPassed() then
2995         EncodingSpecificOperations();
2996         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
2997         if d == 15 then         // Can only occur for ARM encoding
2998             ALUWritePC(result); // setflags is always FALSE here
2999         else
3000             R[d] = result;
3001             if setflags then
3002                 APSR.N = result<31>;
3003                 APSR.Z = IsZeroBit(result);
3004                 APSR.C = carry;
3005                 // APSR.V unchanged
3006 #endif
3007 
3008     return EmulateShiftImm (opcode, encoding, SRType_LSL);
3009 }
3010 
3011 // Logical Shift Left (register) shifts a register value left by a variable number of bits,
3012 // shifting in zeros, and writes the result to the destination register.  The variable number
3013 // of bits is read from the bottom byte of a register. It can optionally update the condition
3014 // flags based on the result.
3015 bool
3016 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding)
3017 {
3018 #if 0
3019     // ARM pseudo code...
3020     if ConditionPassed() then
3021         EncodingSpecificOperations();
3022         shift_n = UInt(R[m]<7:0>);
3023         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3024         R[d] = result;
3025         if setflags then
3026             APSR.N = result<31>;
3027             APSR.Z = IsZeroBit(result);
3028             APSR.C = carry;
3029             // APSR.V unchanged
3030 #endif
3031 
3032     return EmulateShiftReg (opcode, encoding, SRType_LSL);
3033 }
3034 
3035 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
3036 // shifting in zeros, and writes the result to the destination register.  It can optionally
3037 // update the condition flags based on the result.
3038 bool
3039 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding)
3040 {
3041 #if 0
3042     // ARM pseudo code...
3043     if ConditionPassed() then
3044         EncodingSpecificOperations();
3045         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3046         if d == 15 then         // Can only occur for ARM encoding
3047             ALUWritePC(result); // setflags is always FALSE here
3048         else
3049             R[d] = result;
3050             if setflags then
3051                 APSR.N = result<31>;
3052                 APSR.Z = IsZeroBit(result);
3053                 APSR.C = carry;
3054                 // APSR.V unchanged
3055 #endif
3056 
3057     return EmulateShiftImm (opcode, encoding, SRType_LSR);
3058 }
3059 
3060 // Logical Shift Right (register) shifts a register value right by a variable number of bits,
3061 // shifting in zeros, and writes the result to the destination register.  The variable number
3062 // of bits is read from the bottom byte of a register. It can optionally update the condition
3063 // flags based on the result.
3064 bool
3065 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding)
3066 {
3067 #if 0
3068     // ARM pseudo code...
3069     if ConditionPassed() then
3070         EncodingSpecificOperations();
3071         shift_n = UInt(R[m]<7:0>);
3072         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3073         R[d] = result;
3074         if setflags then
3075             APSR.N = result<31>;
3076             APSR.Z = IsZeroBit(result);
3077             APSR.C = carry;
3078             // APSR.V unchanged
3079 #endif
3080 
3081     return EmulateShiftReg (opcode, encoding, SRType_LSR);
3082 }
3083 
3084 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
3085 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3086 // It can optionally update the condition flags based on the result.
3087 bool
3088 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding)
3089 {
3090 #if 0
3091     // ARM pseudo code...
3092     if ConditionPassed() then
3093         EncodingSpecificOperations();
3094         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3095         if d == 15 then         // Can only occur for ARM encoding
3096             ALUWritePC(result); // setflags is always FALSE here
3097         else
3098             R[d] = result;
3099             if setflags then
3100                 APSR.N = result<31>;
3101                 APSR.Z = IsZeroBit(result);
3102                 APSR.C = carry;
3103                 // APSR.V unchanged
3104 #endif
3105 
3106     return EmulateShiftImm (opcode, encoding, SRType_ROR);
3107 }
3108 
3109 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
3110 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3111 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
3112 // flags based on the result.
3113 bool
3114 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding)
3115 {
3116 #if 0
3117     // ARM pseudo code...
3118     if ConditionPassed() then
3119         EncodingSpecificOperations();
3120         shift_n = UInt(R[m]<7:0>);
3121         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3122         R[d] = result;
3123         if setflags then
3124             APSR.N = result<31>;
3125             APSR.Z = IsZeroBit(result);
3126             APSR.C = carry;
3127             // APSR.V unchanged
3128 #endif
3129 
3130     return EmulateShiftReg (opcode, encoding, SRType_ROR);
3131 }
3132 
3133 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
3134 // with the carry flag shifted into bit [31].
3135 //
3136 // RRX can optionally update the condition flags based on the result.
3137 // In that case, bit [0] is shifted into the carry flag.
3138 bool
3139 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding)
3140 {
3141 #if 0
3142     // ARM pseudo code...
3143     if ConditionPassed() then
3144         EncodingSpecificOperations();
3145         (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3146         if d == 15 then         // Can only occur for ARM encoding
3147             ALUWritePC(result); // setflags is always FALSE here
3148         else
3149             R[d] = result;
3150             if setflags then
3151                 APSR.N = result<31>;
3152                 APSR.Z = IsZeroBit(result);
3153                 APSR.C = carry;
3154                 // APSR.V unchanged
3155 #endif
3156 
3157     return EmulateShiftImm (opcode, encoding, SRType_RRX);
3158 }
3159 
3160 bool
3161 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3162 {
3163 //    assert(shift_type == SRType_ASR
3164 //           || shift_type == SRType_LSL
3165 //           || shift_type == SRType_LSR
3166 //           || shift_type == SRType_ROR
3167 //           || shift_type == SRType_RRX);
3168 
3169     bool success = false;
3170 
3171     if (ConditionPassed(opcode))
3172     {
3173         uint32_t Rd;    // the destination register
3174         uint32_t Rm;    // the first operand register
3175         uint32_t imm5;  // encoding for the shift amount
3176         uint32_t carry; // the carry bit after the shift operation
3177         bool setflags;
3178 
3179         // Special case handling!
3180         // A8.6.139 ROR (immediate) -- Encoding T1
3181         ARMEncoding use_encoding = encoding;
3182         if (shift_type == SRType_ROR && use_encoding == eEncodingT1)
3183         {
3184             // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
3185             // have the same decoding of bit fields as the other Thumb2 shift operations.
3186             use_encoding = eEncodingT2;
3187         }
3188 
3189         switch (use_encoding) {
3190         case eEncodingT1:
3191             // Due to the above special case handling!
3192             if (shift_type == SRType_ROR)
3193                 return false;
3194 
3195             Rd = Bits32(opcode, 2, 0);
3196             Rm = Bits32(opcode, 5, 3);
3197             setflags = !InITBlock();
3198             imm5 = Bits32(opcode, 10, 6);
3199             break;
3200         case eEncodingT2:
3201             // A8.6.141 RRX
3202             // There's no imm form of RRX instructions.
3203             if (shift_type == SRType_RRX)
3204                 return false;
3205 
3206             Rd = Bits32(opcode, 11, 8);
3207             Rm = Bits32(opcode, 3, 0);
3208             setflags = BitIsSet(opcode, 20);
3209             imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3210             if (BadReg(Rd) || BadReg(Rm))
3211                 return false;
3212             break;
3213         case eEncodingA1:
3214             Rd = Bits32(opcode, 15, 12);
3215             Rm = Bits32(opcode, 3, 0);
3216             setflags = BitIsSet(opcode, 20);
3217             imm5 = Bits32(opcode, 11, 7);
3218             break;
3219         default:
3220             return false;
3221         }
3222 
3223         // A8.6.139 ROR (immediate)
3224         if (shift_type == SRType_ROR && imm5 == 0)
3225             shift_type = SRType_RRX;
3226 
3227         // Get the first operand.
3228         uint32_t value = ReadCoreReg (Rm, &success);
3229         if (!success)
3230             return false;
3231 
3232         // Decode the shift amount if not RRX.
3233         uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3234 
3235         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3236         if (!success)
3237             return false;
3238 
3239         // The context specifies that an immediate is to be moved into Rd.
3240         EmulateInstruction::Context context;
3241         context.type = EmulateInstruction::eContextImmediate;
3242         context.SetNoArgs ();
3243 
3244         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3245             return false;
3246     }
3247     return true;
3248 }
3249 
3250 bool
3251 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3252 {
3253     // assert(shift_type == SRType_ASR
3254     //        || shift_type == SRType_LSL
3255     //        || shift_type == SRType_LSR
3256     //        || shift_type == SRType_ROR);
3257 
3258     bool success = false;
3259 
3260     if (ConditionPassed(opcode))
3261     {
3262         uint32_t Rd;    // the destination register
3263         uint32_t Rn;    // the first operand register
3264         uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
3265         uint32_t carry; // the carry bit after the shift operation
3266         bool setflags;
3267         switch (encoding) {
3268         case eEncodingT1:
3269             Rd = Bits32(opcode, 2, 0);
3270             Rn = Rd;
3271             Rm = Bits32(opcode, 5, 3);
3272             setflags = !InITBlock();
3273             break;
3274         case eEncodingT2:
3275             Rd = Bits32(opcode, 11, 8);
3276             Rn = Bits32(opcode, 19, 16);
3277             Rm = Bits32(opcode, 3, 0);
3278             setflags = BitIsSet(opcode, 20);
3279             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3280                 return false;
3281             break;
3282         case eEncodingA1:
3283             Rd = Bits32(opcode, 15, 12);
3284             Rn = Bits32(opcode, 3, 0);
3285             Rm = Bits32(opcode, 11, 8);
3286             setflags = BitIsSet(opcode, 20);
3287             if (Rd == 15 || Rn == 15 || Rm == 15)
3288                 return false;
3289             break;
3290         default:
3291             return false;
3292         }
3293 
3294         // Get the first operand.
3295         uint32_t value = ReadCoreReg (Rn, &success);
3296         if (!success)
3297             return false;
3298         // Get the Rm register content.
3299         uint32_t val = ReadCoreReg (Rm, &success);
3300         if (!success)
3301             return false;
3302 
3303         // Get the shift amount.
3304         uint32_t amt = Bits32(val, 7, 0);
3305 
3306         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3307         if (!success)
3308             return false;
3309 
3310         // The context specifies that an immediate is to be moved into Rd.
3311         EmulateInstruction::Context context;
3312         context.type = EmulateInstruction::eContextImmediate;
3313         context.SetNoArgs ();
3314 
3315         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3316             return false;
3317     }
3318     return true;
3319 }
3320 
3321 // LDM loads multiple registers from consecutive memory locations, using an
3322 // address from a base register.  Optionally the address just above the highest of those locations
3323 // can be written back to the base register.
3324 bool
3325 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding)
3326 {
3327 #if 0
3328     // ARM pseudo code...
3329     if ConditionPassed()
3330         EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3331         address = R[n];
3332 
3333         for i = 0 to 14
3334             if registers<i> == '1' then
3335                 R[i] = MemA[address, 4]; address = address + 4;
3336         if registers<15> == '1' then
3337             LoadWritePC (MemA[address, 4]);
3338 
3339         if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3340         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3341 
3342 #endif
3343 
3344     bool success = false;
3345     bool conditional = false;
3346     if (ConditionPassed(opcode, &conditional))
3347     {
3348         uint32_t n;
3349         uint32_t registers = 0;
3350         bool wback;
3351         const uint32_t addr_byte_size = GetAddressByteSize();
3352         switch (encoding)
3353         {
3354             case eEncodingT1:
3355                 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0');
3356                 n = Bits32 (opcode, 10, 8);
3357                 registers = Bits32 (opcode, 7, 0);
3358                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3359                 wback = BitIsClear (registers, n);
3360                 // if BitCount(registers) < 1 then UNPREDICTABLE;
3361                 if (BitCount(registers) < 1)
3362                     return false;
3363                 break;
3364             case eEncodingT2:
3365                 // if W == '1' && Rn == '1101' then SEE POP;
3366                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3367                 n = Bits32 (opcode, 19, 16);
3368                 registers = Bits32 (opcode, 15, 0);
3369                 registers = registers & 0xdfff; // Make sure bit 13 is zero.
3370                 wback = BitIsSet (opcode, 21);
3371 
3372                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3373                 if ((n == 15)
3374                     || (BitCount (registers) < 2)
3375                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3376                     return false;
3377 
3378                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3379                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3380                     return false;
3381 
3382                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3383                 if (wback
3384                     && BitIsSet (registers, n))
3385                     return false;
3386                 break;
3387 
3388             case eEncodingA1:
3389                 n = Bits32 (opcode, 19, 16);
3390                 registers = Bits32 (opcode, 15, 0);
3391                 wback = BitIsSet (opcode, 21);
3392                 if ((n == 15)
3393                     || (BitCount (registers) < 1))
3394                     return false;
3395                 break;
3396             default:
3397                 return false;
3398         }
3399 
3400         int32_t offset = 0;
3401         const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3402         if (!success)
3403             return false;
3404 
3405         EmulateInstruction::Context context;
3406         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3407         RegisterInfo dwarf_reg;
3408         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3409         context.SetRegisterPlusOffset (dwarf_reg, offset);
3410 
3411         for (int i = 0; i < 14; ++i)
3412         {
3413             if (BitIsSet (registers, i))
3414             {
3415                 context.type = EmulateInstruction::eContextRegisterPlusOffset;
3416                 context.SetRegisterPlusOffset (dwarf_reg, offset);
3417                 if (wback && (n == 13)) // Pop Instruction
3418                 {
3419                     if (conditional)
3420                         context.type = EmulateInstruction::eContextRegisterLoad;
3421                     else
3422                         context.type = EmulateInstruction::eContextPopRegisterOffStack;
3423                 }
3424 
3425                 // R[i] = MemA [address, 4]; address = address + 4;
3426                 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3427                 if (!success)
3428                     return false;
3429 
3430                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3431                     return false;
3432 
3433                 offset += addr_byte_size;
3434             }
3435         }
3436 
3437         if (BitIsSet (registers, 15))
3438         {
3439             //LoadWritePC (MemA [address, 4]);
3440             context.type = EmulateInstruction::eContextRegisterPlusOffset;
3441             context.SetRegisterPlusOffset (dwarf_reg, offset);
3442             uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3443             if (!success)
3444                 return false;
3445             // In ARMv5T and above, this is an interworking branch.
3446             if (!LoadWritePC(context, data))
3447                 return false;
3448         }
3449 
3450         if (wback && BitIsClear (registers, n))
3451         {
3452             // R[n] = R[n] + 4 * BitCount (registers)
3453             int32_t offset = addr_byte_size * BitCount (registers);
3454             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3455             context.SetRegisterPlusOffset (dwarf_reg, offset);
3456 
3457             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
3458                 return false;
3459         }
3460         if (wback && BitIsSet (registers, n))
3461             // R[n] bits(32) UNKNOWN;
3462             return WriteBits32Unknown (n);
3463     }
3464     return true;
3465 }
3466 
3467 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register.
3468 // The consecutive memory locations end at this address and the address just below the lowest of those locations
3469 // can optionally be written back to the base register.
3470 bool
3471 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding)
3472 {
3473 #if 0
3474     // ARM pseudo code...
3475     if ConditionPassed() then
3476         EncodingSpecificOperations();
3477         address = R[n] - 4*BitCount(registers) + 4;
3478 
3479         for i = 0 to 14
3480             if registers<i> == '1' then
3481                   R[i] = MemA[address,4]; address = address + 4;
3482 
3483         if registers<15> == '1' then
3484             LoadWritePC(MemA[address,4]);
3485 
3486         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3487         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3488 #endif
3489 
3490     bool success = false;
3491 
3492     if (ConditionPassed(opcode))
3493     {
3494         uint32_t n;
3495         uint32_t registers = 0;
3496         bool wback;
3497         const uint32_t addr_byte_size = GetAddressByteSize();
3498 
3499         // EncodingSpecificOperations();
3500         switch (encoding)
3501         {
3502             case eEncodingA1:
3503                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3504                 n = Bits32 (opcode, 19, 16);
3505                 registers = Bits32 (opcode, 15, 0);
3506                 wback = BitIsSet (opcode, 21);
3507 
3508                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3509                 if ((n == 15) || (BitCount (registers) < 1))
3510                     return false;
3511 
3512                 break;
3513 
3514             default:
3515                 return false;
3516         }
3517         // address = R[n] - 4*BitCount(registers) + 4;
3518 
3519         int32_t offset = 0;
3520         addr_t Rn = ReadCoreReg (n, &success);
3521 
3522         if (!success)
3523             return false;
3524 
3525         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size;
3526 
3527         EmulateInstruction::Context context;
3528         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3529         RegisterInfo dwarf_reg;
3530         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3531         context.SetRegisterPlusOffset (dwarf_reg, offset);
3532 
3533         // for i = 0 to 14
3534         for (int i = 0; i < 14; ++i)
3535         {
3536             // if registers<i> == '1' then
3537             if (BitIsSet (registers, i))
3538             {
3539                   // R[i] = MemA[address,4]; address = address + 4;
3540                   context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3541                   uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3542                   if (!success)
3543                       return false;
3544                   if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3545                       return false;
3546                   offset += addr_byte_size;
3547             }
3548         }
3549 
3550         // if registers<15> == '1' then
3551         //     LoadWritePC(MemA[address,4]);
3552         if (BitIsSet (registers, 15))
3553         {
3554             context.SetRegisterPlusOffset (dwarf_reg, offset);
3555             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3556             if (!success)
3557                 return false;
3558             // In ARMv5T and above, this is an interworking branch.
3559             if (!LoadWritePC(context, data))
3560                 return false;
3561         }
3562 
3563         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3564         if (wback && BitIsClear (registers, n))
3565         {
3566             if (!success)
3567                 return false;
3568 
3569             offset = (addr_byte_size * BitCount (registers)) * -1;
3570             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3571             context.SetImmediateSigned (offset);
3572             addr_t addr = Rn + offset;
3573             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3574                 return false;
3575         }
3576 
3577         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3578         if (wback && BitIsSet (registers, n))
3579             return WriteBits32Unknown (n);
3580     }
3581     return true;
3582 }
3583 
3584 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
3585 // consecutive memory lcoations end just below this address, and the address of the lowest of those locations can
3586 // be optionally written back to the base register.
3587 bool
3588 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding)
3589 {
3590 #if 0
3591     // ARM pseudo code...
3592     if ConditionPassed() then
3593         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3594         address = R[n] - 4*BitCount(registers);
3595 
3596         for i = 0 to 14
3597             if registers<i> == '1' then
3598                   R[i] = MemA[address,4]; address = address + 4;
3599         if registers<15> == '1' then
3600                   LoadWritePC(MemA[address,4]);
3601 
3602         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3603         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3604 #endif
3605 
3606     bool success = false;
3607 
3608     if (ConditionPassed(opcode))
3609     {
3610         uint32_t n;
3611         uint32_t registers = 0;
3612         bool wback;
3613         const uint32_t addr_byte_size = GetAddressByteSize();
3614         switch (encoding)
3615         {
3616             case eEncodingT1:
3617                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3618                 n = Bits32 (opcode, 19, 16);
3619                 registers = Bits32 (opcode, 15, 0);
3620                 registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
3621                 wback = BitIsSet (opcode, 21);
3622 
3623                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3624                 if ((n == 15)
3625                     || (BitCount (registers) < 2)
3626                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3627                     return false;
3628 
3629                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3630                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3631                     return false;
3632 
3633                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3634                 if (wback && BitIsSet (registers, n))
3635                     return false;
3636 
3637                 break;
3638 
3639             case eEncodingA1:
3640                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3641                 n = Bits32 (opcode, 19, 16);
3642                 registers = Bits32 (opcode, 15, 0);
3643                 wback = BitIsSet (opcode, 21);
3644 
3645                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3646                 if ((n == 15) || (BitCount (registers) < 1))
3647                     return false;
3648 
3649                 break;
3650 
3651             default:
3652                 return false;
3653         }
3654 
3655         // address = R[n] - 4*BitCount(registers);
3656 
3657         int32_t offset = 0;
3658         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3659 
3660         if (!success)
3661             return false;
3662 
3663         addr_t address = Rn - (addr_byte_size * BitCount (registers));
3664         EmulateInstruction::Context context;
3665         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3666         RegisterInfo dwarf_reg;
3667         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3668         context.SetRegisterPlusOffset (dwarf_reg, Rn - address);
3669 
3670         for (int i = 0; i < 14; ++i)
3671         {
3672             if (BitIsSet (registers, i))
3673             {
3674                 // R[i] = MemA[address,4]; address = address + 4;
3675                 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3676                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3677                 if (!success)
3678                     return false;
3679 
3680                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3681                     return false;
3682 
3683                 offset += addr_byte_size;
3684             }
3685         }
3686 
3687         // if registers<15> == '1' then
3688         //     LoadWritePC(MemA[address,4]);
3689         if (BitIsSet (registers, 15))
3690         {
3691             context.SetRegisterPlusOffset (dwarf_reg, offset);
3692             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3693             if (!success)
3694                 return false;
3695             // In ARMv5T and above, this is an interworking branch.
3696             if (!LoadWritePC(context, data))
3697                 return false;
3698         }
3699 
3700         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3701         if (wback && BitIsClear (registers, n))
3702         {
3703             if (!success)
3704                 return false;
3705 
3706             offset = (addr_byte_size * BitCount (registers)) * -1;
3707             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3708             context.SetImmediateSigned (offset);
3709             addr_t addr = Rn + offset;
3710             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3711                 return false;
3712         }
3713 
3714         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3715         if (wback && BitIsSet (registers, n))
3716             return WriteBits32Unknown (n);
3717     }
3718     return true;
3719 }
3720 
3721 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
3722 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can
3723 // optinoally be written back to the base register.
3724 bool
3725 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding)
3726 {
3727 #if 0
3728     if ConditionPassed() then
3729         EncodingSpecificOperations();
3730         address = R[n] + 4;
3731 
3732         for i = 0 to 14
3733             if registers<i> == '1' then
3734                   R[i] = MemA[address,4]; address = address + 4;
3735         if registers<15> == '1' then
3736             LoadWritePC(MemA[address,4]);
3737 
3738         if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3739         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3740 #endif
3741 
3742     bool success = false;
3743 
3744     if (ConditionPassed(opcode))
3745     {
3746         uint32_t n;
3747         uint32_t registers = 0;
3748         bool wback;
3749         const uint32_t addr_byte_size = GetAddressByteSize();
3750         switch (encoding)
3751         {
3752             case eEncodingA1:
3753                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3754                 n = Bits32 (opcode, 19, 16);
3755                 registers = Bits32 (opcode, 15, 0);
3756                 wback = BitIsSet (opcode, 21);
3757 
3758                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3759                 if ((n == 15) || (BitCount (registers) < 1))
3760                     return false;
3761 
3762                 break;
3763             default:
3764                 return false;
3765         }
3766         // address = R[n] + 4;
3767 
3768         int32_t offset = 0;
3769         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3770 
3771         if (!success)
3772             return false;
3773 
3774         addr_t address = Rn + addr_byte_size;
3775 
3776         EmulateInstruction::Context context;
3777         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3778         RegisterInfo dwarf_reg;
3779         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3780         context.SetRegisterPlusOffset (dwarf_reg, offset);
3781 
3782         for (int i = 0; i < 14; ++i)
3783         {
3784             if (BitIsSet (registers, i))
3785             {
3786                 // R[i] = MemA[address,4]; address = address + 4;
3787 
3788                 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size);
3789                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3790                 if (!success)
3791                     return false;
3792 
3793                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3794                     return false;
3795 
3796                 offset += addr_byte_size;
3797             }
3798         }
3799 
3800         // if registers<15> == '1' then
3801         //     LoadWritePC(MemA[address,4]);
3802         if (BitIsSet (registers, 15))
3803         {
3804             context.SetRegisterPlusOffset (dwarf_reg, offset);
3805             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3806             if (!success)
3807                 return false;
3808             // In ARMv5T and above, this is an interworking branch.
3809             if (!LoadWritePC(context, data))
3810                 return false;
3811         }
3812 
3813         // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3814         if (wback && BitIsClear (registers, n))
3815         {
3816             if (!success)
3817                 return false;
3818 
3819             offset = addr_byte_size * BitCount (registers);
3820             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3821             context.SetImmediateSigned (offset);
3822             addr_t addr = Rn + offset;
3823             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3824                 return false;
3825         }
3826 
3827         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3828         if (wback && BitIsSet (registers, n))
3829             return WriteBits32Unknown (n);
3830     }
3831     return true;
3832 }
3833 
3834 // Load Register (immediate) calculates an address from a base register value and
3835 // an immediate offset, loads a word from memory, and writes to a register.
3836 // LDR (immediate, Thumb)
3837 bool
3838 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding)
3839 {
3840 #if 0
3841     // ARM pseudo code...
3842     if (ConditionPassed())
3843     {
3844         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3845         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3846         address = if index then offset_addr else R[n];
3847         data = MemU[address,4];
3848         if wback then R[n] = offset_addr;
3849         if t == 15 then
3850             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3851         elsif UnalignedSupport() || address<1:0> = '00' then
3852             R[t] = data;
3853         else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3854     }
3855 #endif
3856 
3857     bool success = false;
3858 
3859     if (ConditionPassed(opcode))
3860     {
3861         uint32_t Rt; // the destination register
3862         uint32_t Rn; // the base register
3863         uint32_t imm32; // the immediate offset used to form the address
3864         addr_t offset_addr; // the offset address
3865         addr_t address; // the calculated address
3866         uint32_t data; // the literal data value from memory load
3867         bool add, index, wback;
3868         switch (encoding) {
3869             case eEncodingT1:
3870                 Rt = Bits32(opcode, 2, 0);
3871                 Rn = Bits32(opcode, 5, 3);
3872                 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3873                 // index = TRUE; add = TRUE; wback = FALSE
3874                 add = true;
3875                 index = true;
3876                 wback = false;
3877 
3878                 break;
3879 
3880             case eEncodingT2:
3881                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
3882                 Rt = Bits32 (opcode, 10, 8);
3883                 Rn = 13;
3884                 imm32 = Bits32 (opcode, 7, 0) << 2;
3885 
3886                 // index = TRUE; add = TRUE; wback = FALSE;
3887                 index = true;
3888                 add = true;
3889                 wback = false;
3890 
3891                 break;
3892 
3893             case eEncodingT3:
3894                 // if Rn == '1111' then SEE LDR (literal);
3895                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
3896                 Rt = Bits32 (opcode, 15, 12);
3897                 Rn = Bits32 (opcode, 19, 16);
3898                 imm32 = Bits32 (opcode, 11, 0);
3899 
3900                 // index = TRUE; add = TRUE; wback = FALSE;
3901                 index = true;
3902                 add = true;
3903                 wback = false;
3904 
3905                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3906                 if ((Rt == 15) && InITBlock() && !LastInITBlock())
3907                     return false;
3908 
3909                 break;
3910 
3911             case eEncodingT4:
3912                 // if Rn == '1111' then SEE LDR (literal);
3913                 // if P == '1' && U == '1' && W == '0' then SEE LDRT;
3914                 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
3915                 // if P == '0' && W == '0' then UNDEFINED;
3916                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
3917                     return false;
3918 
3919                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
3920                 Rt = Bits32 (opcode, 15, 12);
3921                 Rn = Bits32 (opcode, 19, 16);
3922                 imm32 = Bits32 (opcode, 7, 0);
3923 
3924                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
3925                 index = BitIsSet (opcode, 10);
3926                 add = BitIsSet (opcode, 9);
3927                 wback = BitIsSet (opcode, 8);
3928 
3929                 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
3930                 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock()))
3931                     return false;
3932 
3933                 break;
3934 
3935             default:
3936                 return false;
3937         }
3938         uint32_t base = ReadCoreReg (Rn, &success);
3939         if (!success)
3940             return false;
3941         if (add)
3942             offset_addr = base + imm32;
3943         else
3944             offset_addr = base - imm32;
3945 
3946         address = (index ? offset_addr : base);
3947 
3948         RegisterInfo base_reg;
3949         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
3950         if (wback)
3951         {
3952             EmulateInstruction::Context ctx;
3953             ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
3954             ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3955 
3956             if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
3957                 return false;
3958         }
3959 
3960         // Prepare to write to the Rt register.
3961         EmulateInstruction::Context context;
3962         context.type = EmulateInstruction::eContextRegisterLoad;
3963         context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3964 
3965         // Read memory from the address.
3966         data = MemURead(context, address, 4, 0, &success);
3967         if (!success)
3968             return false;
3969 
3970         if (Rt == 15)
3971         {
3972             if (Bits32(address, 1, 0) == 0)
3973             {
3974                 if (!LoadWritePC(context, data))
3975                     return false;
3976             }
3977             else
3978                 return false;
3979         }
3980         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
3981         {
3982             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
3983                 return false;
3984         }
3985         else
3986             WriteBits32Unknown (Rt);
3987     }
3988     return true;
3989 }
3990 
3991 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
3992 // from a base register.  The consecutive memory locations start at this address, and teh address just above the last
3993 // of those locations can optionally be written back to the base register.
3994 bool
3995 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding)
3996 {
3997 #if 0
3998     if ConditionPassed() then
3999         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4000         address = R[n];
4001 
4002         for i = 0 to 14
4003             if registers<i> == '1' then
4004                 if i == n && wback && i != LowestSetBit(registers) then
4005                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4006                 else
4007                     MemA[address,4] = R[i];
4008                 address = address + 4;
4009 
4010         if registers<15> == '1' then // Only possible for encoding A1
4011             MemA[address,4] = PCStoreValue();
4012         if wback then R[n] = R[n] + 4*BitCount(registers);
4013 #endif
4014 
4015     bool success = false;
4016 
4017     if (ConditionPassed(opcode))
4018     {
4019         uint32_t n;
4020         uint32_t registers = 0;
4021         bool wback;
4022         const uint32_t addr_byte_size = GetAddressByteSize();
4023 
4024         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4025         switch (encoding)
4026         {
4027             case eEncodingT1:
4028                 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4029                 n = Bits32 (opcode, 10, 8);
4030                 registers = Bits32 (opcode, 7, 0);
4031                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
4032                 wback = true;
4033 
4034                 // if BitCount(registers) < 1 then UNPREDICTABLE;
4035                 if (BitCount (registers) < 1)
4036                     return false;
4037 
4038                 break;
4039 
4040             case eEncodingT2:
4041                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4042                 n = Bits32 (opcode, 19, 16);
4043                 registers = Bits32 (opcode, 15, 0);
4044                 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4045                 wback = BitIsSet (opcode, 21);
4046 
4047                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4048                 if ((n == 15) || (BitCount (registers) < 2))
4049                     return false;
4050 
4051                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4052                 if (wback && BitIsSet (registers, n))
4053                     return false;
4054 
4055                 break;
4056 
4057             case eEncodingA1:
4058                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4059                 n = Bits32 (opcode, 19, 16);
4060                 registers = Bits32 (opcode, 15, 0);
4061                 wback = BitIsSet (opcode, 21);
4062 
4063                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4064                 if ((n == 15) || (BitCount (registers) < 1))
4065                     return false;
4066 
4067                 break;
4068 
4069             default:
4070                 return false;
4071         }
4072 
4073         // address = R[n];
4074         int32_t offset = 0;
4075         const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4076         if (!success)
4077             return false;
4078 
4079         EmulateInstruction::Context context;
4080         context.type = EmulateInstruction::eContextRegisterStore;
4081         RegisterInfo base_reg;
4082         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4083 
4084         // for i = 0 to 14
4085         int lowest_set_bit = 14;
4086         for (int i = 0; i < 14; ++i)
4087         {
4088             // if registers<i> == '1' then
4089             if (BitIsSet (registers, i))
4090             {
4091                   if (i < lowest_set_bit)
4092                       lowest_set_bit = i;
4093                   // if i == n && wback && i != LowestSetBit(registers) then
4094                   if ((i == n) && wback && (i != lowest_set_bit))
4095                       // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4096                       WriteBits32UnknownToMemory (address + offset);
4097                   else
4098                   {
4099                      // MemA[address,4] = R[i];
4100                       uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4101                       if (!success)
4102                           return false;
4103 
4104                       RegisterInfo data_reg;
4105                       GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4106                       context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4107                       if (!MemAWrite (context, address + offset, data, addr_byte_size))
4108                           return false;
4109                   }
4110 
4111                   // address = address + 4;
4112                   offset += addr_byte_size;
4113             }
4114         }
4115 
4116         // if registers<15> == '1' then // Only possible for encoding A1
4117         //     MemA[address,4] = PCStoreValue();
4118         if (BitIsSet (registers, 15))
4119         {
4120             RegisterInfo pc_reg;
4121             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4122             context.SetRegisterPlusOffset (pc_reg, 8);
4123             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4124             if (!success)
4125                 return false;
4126 
4127             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4128                 return false;
4129         }
4130 
4131         // if wback then R[n] = R[n] + 4*BitCount(registers);
4132         if (wback)
4133         {
4134             offset = addr_byte_size * BitCount (registers);
4135             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4136             context.SetImmediateSigned (offset);
4137             addr_t data = address + offset;
4138             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4139                 return false;
4140         }
4141     }
4142     return true;
4143 }
4144 
4145 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
4146 // from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
4147 // of those locations can optionally be written back to the base register.
4148 bool
4149 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding)
4150 {
4151 #if 0
4152     if ConditionPassed() then
4153         EncodingSpecificOperations();
4154         address = R[n] - 4*BitCount(registers) + 4;
4155 
4156         for i = 0 to 14
4157             if registers<i> == '1' then
4158                 if i == n && wback && i != LowestSetBit(registers) then
4159                     MemA[address,4] = bits(32) UNKNOWN;
4160                 else
4161                     MemA[address,4] = R[i];
4162                 address = address + 4;
4163 
4164         if registers<15> == '1' then
4165             MemA[address,4] = PCStoreValue();
4166 
4167         if wback then R[n] = R[n] - 4*BitCount(registers);
4168 #endif
4169 
4170     bool success = false;
4171 
4172     if (ConditionPassed(opcode))
4173     {
4174         uint32_t n;
4175         uint32_t registers = 0;
4176         bool wback;
4177         const uint32_t addr_byte_size = GetAddressByteSize();
4178 
4179         // EncodingSpecificOperations();
4180         switch (encoding)
4181         {
4182             case eEncodingA1:
4183                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4184                 n = Bits32 (opcode, 19, 16);
4185                 registers = Bits32 (opcode, 15, 0);
4186                 wback = BitIsSet (opcode, 21);
4187 
4188                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4189                 if ((n == 15) || (BitCount (registers) < 1))
4190                     return false;
4191                 break;
4192             default:
4193                 return false;
4194         }
4195 
4196         // address = R[n] - 4*BitCount(registers) + 4;
4197         int32_t offset = 0;
4198         addr_t Rn = ReadCoreReg (n, &success);
4199         if (!success)
4200             return false;
4201 
4202         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4;
4203 
4204         EmulateInstruction::Context context;
4205         context.type = EmulateInstruction::eContextRegisterStore;
4206         RegisterInfo base_reg;
4207         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4208 
4209         // for i = 0 to 14
4210         int lowest_bit_set = 14;
4211         for (int i = 0; i < 14; ++i)
4212         {
4213             // if registers<i> == '1' then
4214             if (BitIsSet (registers, i))
4215             {
4216                 if (i < lowest_bit_set)
4217                     lowest_bit_set = i;
4218                 //if i == n && wback && i != LowestSetBit(registers) then
4219                 if ((i == n) && wback && (i != lowest_bit_set))
4220                     // MemA[address,4] = bits(32) UNKNOWN;
4221                     WriteBits32UnknownToMemory (address + offset);
4222                 else
4223                 {
4224                     // MemA[address,4] = R[i];
4225                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4226                     if (!success)
4227                         return false;
4228 
4229                     RegisterInfo data_reg;
4230                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4231                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4232                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4233                         return false;
4234                 }
4235 
4236                 // address = address + 4;
4237                 offset += addr_byte_size;
4238             }
4239         }
4240 
4241         // if registers<15> == '1' then
4242         //    MemA[address,4] = PCStoreValue();
4243         if (BitIsSet (registers, 15))
4244         {
4245             RegisterInfo pc_reg;
4246             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4247             context.SetRegisterPlusOffset (pc_reg, 8);
4248             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4249             if (!success)
4250                 return false;
4251 
4252             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4253                 return false;
4254         }
4255 
4256         // if wback then R[n] = R[n] - 4*BitCount(registers);
4257         if (wback)
4258         {
4259             offset = (addr_byte_size * BitCount (registers)) * -1;
4260             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4261             context.SetImmediateSigned (offset);
4262             addr_t data = Rn + offset;
4263             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4264                 return false;
4265         }
4266     }
4267     return true;
4268 }
4269 
4270 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
4271 // from a base register.  The consecutive memory locations end just below this address, and the address of the first of
4272 // those locations can optionally be written back to the base register.
4273 bool
4274 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding)
4275 {
4276 #if 0
4277     if ConditionPassed() then
4278         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4279         address = R[n] - 4*BitCount(registers);
4280 
4281         for i = 0 to 14
4282             if registers<i> == '1' then
4283                 if i == n && wback && i != LowestSetBit(registers) then
4284                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4285                 else
4286                     MemA[address,4] = R[i];
4287                 address = address + 4;
4288 
4289         if registers<15> == '1' then // Only possible for encoding A1
4290             MemA[address,4] = PCStoreValue();
4291 
4292         if wback then R[n] = R[n] - 4*BitCount(registers);
4293 #endif
4294 
4295 
4296     bool success = false;
4297 
4298     if (ConditionPassed(opcode))
4299     {
4300         uint32_t n;
4301         uint32_t registers = 0;
4302         bool wback;
4303         const uint32_t addr_byte_size = GetAddressByteSize();
4304 
4305         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4306         switch (encoding)
4307         {
4308             case eEncodingT1:
4309                 // if W == '1' && Rn == '1101' then SEE PUSH;
4310                 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
4311                 {
4312                     // See PUSH
4313                 }
4314                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4315                 n = Bits32 (opcode, 19, 16);
4316                 registers = Bits32 (opcode, 15, 0);
4317                 registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
4318                 wback = BitIsSet (opcode, 21);
4319                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4320                 if ((n == 15) || BitCount (registers) < 2)
4321                     return false;
4322                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4323                 if (wback && BitIsSet (registers, n))
4324                     return false;
4325                 break;
4326 
4327             case eEncodingA1:
4328                 // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH;
4329                 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
4330                 {
4331                     // See Push
4332                 }
4333                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4334                 n = Bits32 (opcode, 19, 16);
4335                 registers = Bits32 (opcode, 15, 0);
4336                 wback = BitIsSet (opcode, 21);
4337                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4338                 if ((n == 15) || BitCount (registers) < 1)
4339                     return false;
4340                 break;
4341 
4342             default:
4343                 return false;
4344         }
4345 
4346         // address = R[n] - 4*BitCount(registers);
4347 
4348         int32_t offset = 0;
4349         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4350         if (!success)
4351         return false;
4352 
4353         addr_t address = Rn - (addr_byte_size * BitCount (registers));
4354 
4355         EmulateInstruction::Context context;
4356         context.type = EmulateInstruction::eContextRegisterStore;
4357         RegisterInfo base_reg;
4358         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4359 
4360         // for i = 0 to 14
4361         uint32_t lowest_set_bit = 14;
4362         for (int i = 0; i < 14; ++i)
4363         {
4364             // if registers<i> == '1' then
4365             if (BitIsSet (registers, i))
4366             {
4367                 if (i < lowest_set_bit)
4368                     lowest_set_bit = i;
4369                 // if i == n && wback && i != LowestSetBit(registers) then
4370                 if ((i == n) && wback && (i != lowest_set_bit))
4371                     // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4372                     WriteBits32UnknownToMemory (address + offset);
4373                 else
4374                 {
4375                     // MemA[address,4] = R[i];
4376                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4377                     if (!success)
4378                         return false;
4379 
4380                     RegisterInfo data_reg;
4381                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4382                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4383                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4384                         return false;
4385                 }
4386 
4387                 // address = address + 4;
4388                 offset += addr_byte_size;
4389             }
4390         }
4391 
4392         // if registers<15> == '1' then // Only possible for encoding A1
4393         //     MemA[address,4] = PCStoreValue();
4394         if (BitIsSet (registers, 15))
4395         {
4396             RegisterInfo pc_reg;
4397             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4398             context.SetRegisterPlusOffset (pc_reg, 8);
4399             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4400             if (!success)
4401                 return false;
4402 
4403             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4404                 return false;
4405         }
4406 
4407         // if wback then R[n] = R[n] - 4*BitCount(registers);
4408         if (wback)
4409         {
4410             offset = (addr_byte_size * BitCount (registers)) * -1;
4411             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4412             context.SetImmediateSigned (offset);
4413             addr_t data = Rn + offset;
4414             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4415                 return false;
4416         }
4417     }
4418     return true;
4419 }
4420 
4421 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
4422 // from a base register.  The consecutive memory locations start just above this address, and the address of the last
4423 // of those locations can optionally be written back to the base register.
4424 bool
4425 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding)
4426 {
4427 #if 0
4428     if ConditionPassed() then
4429         EncodingSpecificOperations();
4430         address = R[n] + 4;
4431 
4432         for i = 0 to 14
4433             if registers<i> == '1' then
4434                 if i == n && wback && i != LowestSetBit(registers) then
4435                     MemA[address,4] = bits(32) UNKNOWN;
4436                 else
4437                     MemA[address,4] = R[i];
4438                 address = address + 4;
4439 
4440         if registers<15> == '1' then
4441             MemA[address,4] = PCStoreValue();
4442 
4443         if wback then R[n] = R[n] + 4*BitCount(registers);
4444 #endif
4445 
4446     bool success = false;
4447 
4448     if (ConditionPassed(opcode))
4449     {
4450         uint32_t n;
4451         uint32_t registers = 0;
4452         bool wback;
4453         const uint32_t addr_byte_size = GetAddressByteSize();
4454 
4455         // EncodingSpecificOperations();
4456         switch (encoding)
4457         {
4458             case eEncodingA1:
4459                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4460                 n = Bits32 (opcode, 19, 16);
4461                 registers = Bits32 (opcode, 15, 0);
4462                 wback = BitIsSet (opcode, 21);
4463 
4464                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4465                 if ((n == 15) && (BitCount (registers) < 1))
4466                     return false;
4467                 break;
4468             default:
4469                 return false;
4470         }
4471         // address = R[n] + 4;
4472 
4473         int32_t offset = 0;
4474         addr_t Rn = ReadCoreReg (n, &success);
4475         if (!success)
4476             return false;
4477 
4478         addr_t address = Rn + addr_byte_size;
4479 
4480         EmulateInstruction::Context context;
4481         context.type = EmulateInstruction::eContextRegisterStore;
4482         RegisterInfo base_reg;
4483         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4484 
4485         uint32_t lowest_set_bit = 14;
4486         // for i = 0 to 14
4487         for (int i = 0; i < 14; ++i)
4488         {
4489             // if registers<i> == '1' then
4490             if (BitIsSet (registers, i))
4491             {
4492                 if (i < lowest_set_bit)
4493                     lowest_set_bit = i;
4494                 // if i == n && wback && i != LowestSetBit(registers) then
4495                 if ((i == n) && wback && (i != lowest_set_bit))
4496                     // MemA[address,4] = bits(32) UNKNOWN;
4497                     WriteBits32UnknownToMemory (address + offset);
4498                 // else
4499                 else
4500                 {
4501                     // MemA[address,4] = R[i];
4502                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4503                     if (!success)
4504                         return false;
4505 
4506                     RegisterInfo data_reg;
4507                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4508                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size);
4509                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4510                         return false;
4511                 }
4512 
4513                 // address = address + 4;
4514                 offset += addr_byte_size;
4515             }
4516         }
4517 
4518         // if registers<15> == '1' then
4519             // MemA[address,4] = PCStoreValue();
4520         if (BitIsSet (registers, 15))
4521         {
4522             RegisterInfo pc_reg;
4523             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4524             context.SetRegisterPlusOffset (pc_reg, 8);
4525             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4526             if (!success)
4527             return false;
4528 
4529             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4530                 return false;
4531         }
4532 
4533         // if wback then R[n] = R[n] + 4*BitCount(registers);
4534         if (wback)
4535         {
4536             offset = addr_byte_size * BitCount (registers);
4537             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4538             context.SetImmediateSigned (offset);
4539             addr_t data = Rn + offset;
4540             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4541                 return false;
4542         }
4543     }
4544     return true;
4545 }
4546 
4547 // STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word
4548 // from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
4549 bool
4550 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding)
4551 {
4552 #if 0
4553     if ConditionPassed() then
4554         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4555         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4556         address = if index then offset_addr else R[n];
4557         if UnalignedSupport() || address<1:0> == '00' then
4558             MemU[address,4] = R[t];
4559         else // Can only occur before ARMv7
4560             MemU[address,4] = bits(32) UNKNOWN;
4561         if wback then R[n] = offset_addr;
4562 #endif
4563 
4564     bool success = false;
4565 
4566     if (ConditionPassed(opcode))
4567     {
4568         const uint32_t addr_byte_size = GetAddressByteSize();
4569 
4570         uint32_t t;
4571         uint32_t n;
4572         uint32_t imm32;
4573         bool index;
4574         bool add;
4575         bool wback;
4576         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4577         switch (encoding)
4578         {
4579             case eEncodingT1:
4580                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
4581                 t = Bits32 (opcode, 2, 0);
4582                 n = Bits32 (opcode, 5, 3);
4583                 imm32 = Bits32 (opcode, 10, 6) << 2;
4584 
4585                 // index = TRUE; add = TRUE; wback = FALSE;
4586                 index = true;
4587                 add = false;
4588                 wback = false;
4589                 break;
4590 
4591             case eEncodingT2:
4592                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4593                 t = Bits32 (opcode, 10, 8);
4594                 n = 13;
4595                 imm32 = Bits32 (opcode, 7, 0) << 2;
4596 
4597                 // index = TRUE; add = TRUE; wback = FALSE;
4598                 index = true;
4599                 add = true;
4600                 wback = false;
4601                 break;
4602 
4603             case eEncodingT3:
4604                 // if Rn == '1111' then UNDEFINED;
4605                 if (Bits32 (opcode, 19, 16) == 15)
4606                     return false;
4607 
4608                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4609                 t = Bits32 (opcode, 15, 12);
4610                 n = Bits32 (opcode, 19, 16);
4611                 imm32 = Bits32 (opcode, 11, 0);
4612 
4613                 // index = TRUE; add = TRUE; wback = FALSE;
4614                 index = true;
4615                 add = true;
4616                 wback = false;
4617 
4618                 // if t == 15 then UNPREDICTABLE;
4619                 if (t == 15)
4620                     return false;
4621                 break;
4622 
4623             case eEncodingT4:
4624                 // if P == '1' && U == '1' && W == '0' then SEE STRT;
4625                 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH;
4626                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4627                 if ((Bits32 (opcode, 19, 16) == 15)
4628                       || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
4629                     return false;
4630 
4631                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4632                 t = Bits32 (opcode, 15, 12);
4633                 n = Bits32 (opcode, 19, 16);
4634                 imm32 = Bits32 (opcode, 7, 0);
4635 
4636                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4637                 index = BitIsSet (opcode, 10);
4638                 add = BitIsSet (opcode, 9);
4639                 wback = BitIsSet (opcode, 8);
4640 
4641                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
4642                 if ((t == 15) || (wback && (n == t)))
4643                     return false;
4644                 break;
4645 
4646             default:
4647                 return false;
4648         }
4649 
4650         addr_t offset_addr;
4651         addr_t address;
4652 
4653         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4654         uint32_t base_address = ReadCoreReg (n, &success);
4655         if (!success)
4656             return false;
4657 
4658         if (add)
4659             offset_addr = base_address + imm32;
4660         else
4661             offset_addr = base_address - imm32;
4662 
4663         // address = if index then offset_addr else R[n];
4664         if (index)
4665             address = offset_addr;
4666         else
4667             address = base_address;
4668 
4669         EmulateInstruction::Context context;
4670         context.type = eContextRegisterStore;
4671         RegisterInfo base_reg;
4672         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4673 
4674         // if UnalignedSupport() || address<1:0> == '00' then
4675         if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
4676         {
4677             // MemU[address,4] = R[t];
4678             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4679             if (!success)
4680                 return false;
4681 
4682             RegisterInfo data_reg;
4683             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4684             int32_t offset = address - base_address;
4685             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4686             if (!MemUWrite (context, address, data, addr_byte_size))
4687                 return false;
4688         }
4689         else
4690         {
4691             // MemU[address,4] = bits(32) UNKNOWN;
4692             WriteBits32UnknownToMemory (address);
4693         }
4694 
4695         // if wback then R[n] = offset_addr;
4696         if (wback)
4697         {
4698             context.type = eContextRegisterLoad;
4699             context.SetAddress (offset_addr);
4700             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4701                 return false;
4702         }
4703     }
4704     return true;
4705 }
4706 
4707 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a
4708 // word from a register to memory.   The offset register value can optionally be shifted.
4709 bool
4710 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding)
4711 {
4712 #if 0
4713     if ConditionPassed() then
4714         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4715         offset = Shift(R[m], shift_t, shift_n, APSR.C);
4716         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4717         address = if index then offset_addr else R[n];
4718         if t == 15 then // Only possible for encoding A1
4719             data = PCStoreValue();
4720         else
4721             data = R[t];
4722         if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4723             MemU[address,4] = data;
4724         else // Can only occur before ARMv7
4725             MemU[address,4] = bits(32) UNKNOWN;
4726         if wback then R[n] = offset_addr;
4727 #endif
4728 
4729     bool success = false;
4730 
4731     if (ConditionPassed(opcode))
4732     {
4733         const uint32_t addr_byte_size = GetAddressByteSize();
4734 
4735         uint32_t t;
4736         uint32_t n;
4737         uint32_t m;
4738         ARM_ShifterType shift_t;
4739         uint32_t shift_n;
4740         bool index;
4741         bool add;
4742         bool wback;
4743 
4744         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4745         switch (encoding)
4746         {
4747             case eEncodingT1:
4748                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4749                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4750                 t = Bits32 (opcode, 2, 0);
4751                 n = Bits32 (opcode, 5, 3);
4752                 m = Bits32 (opcode, 8, 6);
4753 
4754                 // index = TRUE; add = TRUE; wback = FALSE;
4755                 index = true;
4756                 add = true;
4757                 wback = false;
4758 
4759                 // (shift_t, shift_n) = (SRType_LSL, 0);
4760                 shift_t = SRType_LSL;
4761                 shift_n = 0;
4762                 break;
4763 
4764             case eEncodingT2:
4765                 // if Rn == '1111' then UNDEFINED;
4766                 if (Bits32 (opcode, 19, 16) == 15)
4767                     return false;
4768 
4769                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4770                 t = Bits32 (opcode, 15, 12);
4771                 n = Bits32 (opcode, 19, 16);
4772                 m = Bits32 (opcode, 3, 0);
4773 
4774                 // index = TRUE; add = TRUE; wback = FALSE;
4775                 index = true;
4776                 add = true;
4777                 wback = false;
4778 
4779                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4780                 shift_t = SRType_LSL;
4781                 shift_n = Bits32 (opcode, 5, 4);
4782 
4783                 // if t == 15 || BadReg(m) then UNPREDICTABLE;
4784                 if ((t == 15) || (BadReg (m)))
4785                     return false;
4786                 break;
4787 
4788             case eEncodingA1:
4789             {
4790                 // if P == '0' && W == '1' then SEE STRT;
4791                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4792                 t = Bits32 (opcode, 15, 12);
4793                 n = Bits32 (opcode, 19, 16);
4794                 m = Bits32 (opcode, 3, 0);
4795 
4796                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
4797                 index = BitIsSet (opcode, 24);
4798                 add = BitIsSet (opcode, 23);
4799                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
4800 
4801                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
4802                 uint32_t typ = Bits32 (opcode, 6, 5);
4803                 uint32_t imm5 = Bits32 (opcode, 11, 7);
4804                 shift_n = DecodeImmShift(typ, imm5, shift_t);
4805 
4806                 // if m == 15 then UNPREDICTABLE;
4807                 if (m == 15)
4808                     return false;
4809 
4810                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
4811                 if (wback && ((n == 15) || (n == t)))
4812                     return false;
4813 
4814                 break;
4815             }
4816             default:
4817                 return false;
4818         }
4819 
4820         addr_t offset_addr;
4821         addr_t address;
4822         int32_t offset = 0;
4823 
4824         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4825         if (!success)
4826             return false;
4827 
4828         uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
4829         if (!success)
4830             return false;
4831 
4832         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4833         offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success);
4834         if (!success)
4835             return false;
4836 
4837         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4838         if (add)
4839             offset_addr = base_address + offset;
4840         else
4841             offset_addr = base_address - offset;
4842 
4843         // address = if index then offset_addr else R[n];
4844         if (index)
4845             address = offset_addr;
4846         else
4847             address = base_address;
4848 
4849         uint32_t data;
4850         // if t == 15 then // Only possible for encoding A1
4851         if (t == 15)
4852             // data = PCStoreValue();
4853             data = ReadCoreReg (PC_REG, &success);
4854         else
4855             // data = R[t];
4856             data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4857 
4858         if (!success)
4859             return false;
4860 
4861         EmulateInstruction::Context context;
4862         context.type = eContextRegisterStore;
4863 
4864         // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4865         if (UnalignedSupport ()
4866             || (BitIsClear (address, 1) && BitIsClear (address, 0))
4867             || CurrentInstrSet() == eModeARM)
4868         {
4869             // MemU[address,4] = data;
4870 
4871             RegisterInfo base_reg;
4872             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 +  n, base_reg);
4873 
4874             RegisterInfo data_reg;
4875             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4876 
4877             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4878             if (!MemUWrite (context, address, data, addr_byte_size))
4879                 return false;
4880 
4881         }
4882         else
4883             // MemU[address,4] = bits(32) UNKNOWN;
4884             WriteBits32UnknownToMemory (address);
4885 
4886         // if wback then R[n] = offset_addr;
4887         if (wback)
4888         {
4889             context.type = eContextRegisterLoad;
4890             context.SetAddress (offset_addr);
4891             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4892                 return false;
4893         }
4894 
4895     }
4896     return true;
4897 }
4898 
4899 bool
4900 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding)
4901 {
4902 #if 0
4903     if ConditionPassed() then
4904         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4905         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4906         address = if index then offset_addr else R[n];
4907         MemU[address,1] = R[t]<7:0>;
4908         if wback then R[n] = offset_addr;
4909 #endif
4910 
4911 
4912     bool success = false;
4913 
4914     if (ConditionPassed(opcode))
4915     {
4916         uint32_t t;
4917         uint32_t n;
4918         uint32_t imm32;
4919         bool index;
4920         bool add;
4921         bool wback;
4922         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4923         switch (encoding)
4924         {
4925             case eEncodingT1:
4926                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
4927                 t = Bits32 (opcode, 2, 0);
4928                 n = Bits32 (opcode, 5, 3);
4929                 imm32 = Bits32 (opcode, 10, 6);
4930 
4931                 // index = TRUE; add = TRUE; wback = FALSE;
4932                 index = true;
4933                 add = true;
4934                 wback = false;
4935                 break;
4936 
4937             case eEncodingT2:
4938                 // if Rn == '1111' then UNDEFINED;
4939                 if (Bits32 (opcode, 19, 16) == 15)
4940                     return false;
4941 
4942                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4943                 t = Bits32 (opcode, 15, 12);
4944                 n = Bits32 (opcode, 19, 16);
4945                 imm32 = Bits32 (opcode, 11, 0);
4946 
4947                 // index = TRUE; add = TRUE; wback = FALSE;
4948                 index = true;
4949                 add = true;
4950                 wback = false;
4951 
4952                 // if BadReg(t) then UNPREDICTABLE;
4953                 if (BadReg (t))
4954                     return false;
4955                 break;
4956 
4957             case eEncodingT3:
4958                 // if P == '1' && U == '1' && W == '0' then SEE STRBT;
4959                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4960                 if (Bits32 (opcode, 19, 16) == 15)
4961                     return false;
4962 
4963                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4964                 t = Bits32 (opcode, 15, 12);
4965                 n = Bits32 (opcode, 19, 16);
4966                 imm32 = Bits32 (opcode, 7, 0);
4967 
4968                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4969                 index = BitIsSet (opcode, 10);
4970                 add = BitIsSet (opcode, 9);
4971                 wback = BitIsSet (opcode, 8);
4972 
4973                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
4974                 if ((BadReg (t)) || (wback && (n == t)))
4975                     return false;
4976                 break;
4977 
4978             default:
4979                 return false;
4980         }
4981 
4982         addr_t offset_addr;
4983         addr_t address;
4984         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4985         if (!success)
4986             return false;
4987 
4988         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4989         if (add)
4990             offset_addr = base_address + imm32;
4991         else
4992             offset_addr = base_address - imm32;
4993 
4994         // address = if index then offset_addr else R[n];
4995         if (index)
4996             address = offset_addr;
4997         else
4998             address = base_address;
4999 
5000         // MemU[address,1] = R[t]<7:0>
5001         RegisterInfo base_reg;
5002         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5003 
5004         RegisterInfo data_reg;
5005         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5006 
5007         EmulateInstruction::Context context;
5008         context.type = eContextRegisterStore;
5009         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
5010 
5011         uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5012         if (!success)
5013             return false;
5014 
5015         data = Bits32 (data, 7, 0);
5016 
5017         if (!MemUWrite (context, address, data, 1))
5018             return false;
5019 
5020         // if wback then R[n] = offset_addr;
5021         if (wback)
5022         {
5023             context.type = eContextRegisterLoad;
5024             context.SetAddress (offset_addr);
5025             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5026                 return false;
5027         }
5028 
5029     }
5030 
5031     return true;
5032 }
5033 
5034 // STRH (register) calculates an address from a base register value and an offset register value, and stores a
5035 // halfword from a register to memory.  The offset register alue can be shifted left by 0, 1, 2, or 3 bits.
5036 bool
5037 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding)
5038 {
5039 #if 0
5040     if ConditionPassed() then
5041         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5042         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5043         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5044         address = if index then offset_addr else R[n];
5045         if UnalignedSupport() || address<0> == '0' then
5046             MemU[address,2] = R[t]<15:0>;
5047         else // Can only occur before ARMv7
5048             MemU[address,2] = bits(16) UNKNOWN;
5049         if wback then R[n] = offset_addr;
5050 #endif
5051 
5052     bool success = false;
5053 
5054     if (ConditionPassed(opcode))
5055     {
5056         uint32_t t;
5057         uint32_t n;
5058         uint32_t m;
5059         bool index;
5060         bool add;
5061         bool wback;
5062         ARM_ShifterType shift_t;
5063         uint32_t shift_n;
5064 
5065         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5066         switch (encoding)
5067         {
5068             case eEncodingT1:
5069                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5070                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5071                 t = Bits32 (opcode, 2, 0);
5072                 n = Bits32 (opcode, 5, 3);
5073                 m = Bits32 (opcode, 8, 6);
5074 
5075                 // index = TRUE; add = TRUE; wback = FALSE;
5076                 index = true;
5077                 add = true;
5078                 wback = false;
5079 
5080                 // (shift_t, shift_n) = (SRType_LSL, 0);
5081                 shift_t = SRType_LSL;
5082                 shift_n = 0;
5083 
5084                 break;
5085 
5086             case eEncodingT2:
5087                 // if Rn == '1111' then UNDEFINED;
5088                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5089                 t = Bits32 (opcode, 15, 12);
5090                 n = Bits32 (opcode, 19, 16);
5091                 m = Bits32 (opcode, 3, 0);
5092                 if (n == 15)
5093                     return false;
5094 
5095                 // index = TRUE; add = TRUE; wback = FALSE;
5096                 index = true;
5097                 add = true;
5098                 wback = false;
5099 
5100                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5101                 shift_t = SRType_LSL;
5102                 shift_n = Bits32 (opcode, 5, 4);
5103 
5104                 // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5105                 if (BadReg (t) || BadReg (m))
5106                     return false;
5107 
5108                 break;
5109 
5110             case eEncodingA1:
5111                 // if P == '0' && W == '1' then SEE STRHT;
5112                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5113                 t = Bits32 (opcode, 15, 12);
5114                 n = Bits32 (opcode, 19, 16);
5115                 m = Bits32 (opcode, 3, 0);
5116 
5117                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5118                 index = BitIsSet (opcode, 24);
5119                 add = BitIsSet (opcode, 23);
5120                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5121 
5122                 // (shift_t, shift_n) = (SRType_LSL, 0);
5123                 shift_t = SRType_LSL;
5124                 shift_n = 0;
5125 
5126                 // if t == 15 || m == 15 then UNPREDICTABLE;
5127                 if ((t == 15) || (m == 15))
5128                     return false;
5129 
5130                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5131                 if (wback && ((n == 15) || (n == t)))
5132                     return false;
5133 
5134                 break;
5135 
5136             default:
5137                 return false;
5138         }
5139 
5140         uint32_t Rm = ReadCoreReg (m, &success);
5141         if (!success)
5142             return false;
5143 
5144         uint32_t Rn = ReadCoreReg (n, &success);
5145         if (!success)
5146             return false;
5147 
5148         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5149         uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
5150         if (!success)
5151             return false;
5152 
5153         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5154         addr_t offset_addr;
5155         if (add)
5156             offset_addr = Rn + offset;
5157         else
5158             offset_addr = Rn - offset;
5159 
5160         // address = if index then offset_addr else R[n];
5161         addr_t address;
5162         if (index)
5163             address = offset_addr;
5164         else
5165             address = Rn;
5166 
5167         EmulateInstruction::Context context;
5168         context.type = eContextRegisterStore;
5169         RegisterInfo base_reg;
5170         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5171         RegisterInfo offset_reg;
5172         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5173 
5174         // if UnalignedSupport() || address<0> == '0' then
5175         if (UnalignedSupport() || BitIsClear (address, 0))
5176         {
5177             // MemU[address,2] = R[t]<15:0>;
5178             uint32_t Rt = ReadCoreReg (t, &success);
5179             if (!success)
5180                 return false;
5181 
5182             EmulateInstruction::Context context;
5183             context.type = eContextRegisterStore;
5184             RegisterInfo base_reg;
5185             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5186             RegisterInfo offset_reg;
5187             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5188             RegisterInfo data_reg;
5189             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5190             context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
5191 
5192             if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2))
5193                 return false;
5194         }
5195         else // Can only occur before ARMv7
5196         {
5197             // MemU[address,2] = bits(16) UNKNOWN;
5198         }
5199 
5200         // if wback then R[n] = offset_addr;
5201         if (wback)
5202         {
5203             context.type = eContextAdjustBaseRegister;
5204             context.SetAddress (offset_addr);
5205             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5206                 return false;
5207         }
5208     }
5209 
5210     return true;
5211 }
5212 
5213 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value,
5214 // and writes the result to the destination register.  It can optionally update the condition flags
5215 // based on the result.
5216 bool
5217 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding)
5218 {
5219 #if 0
5220     // ARM pseudo code...
5221     if ConditionPassed() then
5222         EncodingSpecificOperations();
5223         (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5224         if d == 15 then         // Can only occur for ARM encoding
5225             ALUWritePC(result); // setflags is always FALSE here
5226         else
5227             R[d] = result;
5228             if setflags then
5229                 APSR.N = result<31>;
5230                 APSR.Z = IsZeroBit(result);
5231                 APSR.C = carry;
5232                 APSR.V = overflow;
5233 #endif
5234 
5235     bool success = false;
5236 
5237     if (ConditionPassed(opcode))
5238     {
5239         uint32_t Rd, Rn;
5240         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
5241         bool setflags;
5242         switch (encoding)
5243         {
5244         case eEncodingT1:
5245             Rd = Bits32(opcode, 11, 8);
5246             Rn = Bits32(opcode, 19, 16);
5247             setflags = BitIsSet(opcode, 20);
5248             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5249             if (BadReg(Rd) || BadReg(Rn))
5250                 return false;
5251             break;
5252         case eEncodingA1:
5253             Rd = Bits32(opcode, 15, 12);
5254             Rn = Bits32(opcode, 19, 16);
5255             setflags = BitIsSet(opcode, 20);
5256             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5257 
5258             if (Rd == 15 && setflags)
5259                 return EmulateSUBSPcLrEtc (opcode, encoding);
5260             break;
5261         default:
5262             return false;
5263         }
5264 
5265         // Read the first operand.
5266         int32_t val1 = ReadCoreReg(Rn, &success);
5267         if (!success)
5268             return false;
5269 
5270         AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5271 
5272         EmulateInstruction::Context context;
5273         context.type = EmulateInstruction::eContextImmediate;
5274         context.SetNoArgs ();
5275 
5276         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5277             return false;
5278     }
5279     return true;
5280 }
5281 
5282 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted
5283 // register value, and writes the result to the destination register.  It can optionally update the
5284 // condition flags based on the result.
5285 bool
5286 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding)
5287 {
5288 #if 0
5289     // ARM pseudo code...
5290     if ConditionPassed() then
5291         EncodingSpecificOperations();
5292         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5293         (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5294         if d == 15 then         // Can only occur for ARM encoding
5295             ALUWritePC(result); // setflags is always FALSE here
5296         else
5297             R[d] = result;
5298             if setflags then
5299                 APSR.N = result<31>;
5300                 APSR.Z = IsZeroBit(result);
5301                 APSR.C = carry;
5302                 APSR.V = overflow;
5303 #endif
5304 
5305     bool success = false;
5306 
5307     if (ConditionPassed(opcode))
5308     {
5309         uint32_t Rd, Rn, Rm;
5310         ARM_ShifterType shift_t;
5311         uint32_t shift_n; // the shift applied to the value read from Rm
5312         bool setflags;
5313         switch (encoding)
5314         {
5315         case eEncodingT1:
5316             Rd = Rn = Bits32(opcode, 2, 0);
5317             Rm = Bits32(opcode, 5, 3);
5318             setflags = !InITBlock();
5319             shift_t = SRType_LSL;
5320             shift_n = 0;
5321             break;
5322         case eEncodingT2:
5323             Rd = Bits32(opcode, 11, 8);
5324             Rn = Bits32(opcode, 19, 16);
5325             Rm = Bits32(opcode, 3, 0);
5326             setflags = BitIsSet(opcode, 20);
5327             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5328             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5329                 return false;
5330             break;
5331         case eEncodingA1:
5332             Rd = Bits32(opcode, 15, 12);
5333             Rn = Bits32(opcode, 19, 16);
5334             Rm = Bits32(opcode, 3, 0);
5335             setflags = BitIsSet(opcode, 20);
5336             shift_n = DecodeImmShiftARM(opcode, shift_t);
5337 
5338             if (Rd == 15 && setflags)
5339                 return EmulateSUBSPcLrEtc (opcode, encoding);
5340             break;
5341         default:
5342             return false;
5343         }
5344 
5345         // Read the first operand.
5346         int32_t val1 = ReadCoreReg(Rn, &success);
5347         if (!success)
5348             return false;
5349 
5350         // Read the second operand.
5351         int32_t val2 = ReadCoreReg(Rm, &success);
5352         if (!success)
5353             return false;
5354 
5355         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5356         if (!success)
5357             return false;
5358         AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5359 
5360         EmulateInstruction::Context context;
5361         context.type = EmulateInstruction::eContextImmediate;
5362         context.SetNoArgs ();
5363 
5364         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5365             return false;
5366     }
5367     return true;
5368 }
5369 
5370 // This instruction adds an immediate value to the PC value to form a PC-relative address,
5371 // and writes the result to the destination register.
5372 bool
5373 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding)
5374 {
5375 #if 0
5376     // ARM pseudo code...
5377     if ConditionPassed() then
5378         EncodingSpecificOperations();
5379         result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5380         if d == 15 then         // Can only occur for ARM encodings
5381             ALUWritePC(result);
5382         else
5383             R[d] = result;
5384 #endif
5385 
5386     bool success = false;
5387 
5388     if (ConditionPassed(opcode))
5389     {
5390         uint32_t Rd;
5391         uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5392         bool add;
5393         switch (encoding)
5394         {
5395         case eEncodingT1:
5396             Rd = Bits32(opcode, 10, 8);
5397             imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5398             break;
5399         case eEncodingT2:
5400         case eEncodingT3:
5401             Rd = Bits32(opcode, 11, 8);
5402             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5403             add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5404             if (BadReg(Rd))
5405                 return false;
5406             break;
5407         case eEncodingA1:
5408         case eEncodingA2:
5409             Rd = Bits32(opcode, 15, 12);
5410             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5411             add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5412             break;
5413         default:
5414             return false;
5415         }
5416 
5417         // Read the PC value.
5418         uint32_t pc = ReadCoreReg(PC_REG, &success);
5419         if (!success)
5420             return false;
5421 
5422         uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5423 
5424         EmulateInstruction::Context context;
5425         context.type = EmulateInstruction::eContextImmediate;
5426         context.SetNoArgs ();
5427 
5428         if (!WriteCoreReg(context, result, Rd))
5429             return false;
5430     }
5431     return true;
5432 }
5433 
5434 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result
5435 // to the destination register.  It can optionally update the condition flags based on the result.
5436 bool
5437 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding)
5438 {
5439 #if 0
5440     // ARM pseudo code...
5441     if ConditionPassed() then
5442         EncodingSpecificOperations();
5443         result = R[n] AND imm32;
5444         if d == 15 then         // Can only occur for ARM encoding
5445             ALUWritePC(result); // setflags is always FALSE here
5446         else
5447             R[d] = result;
5448             if setflags then
5449                 APSR.N = result<31>;
5450                 APSR.Z = IsZeroBit(result);
5451                 APSR.C = carry;
5452                 // APSR.V unchanged
5453 #endif
5454 
5455     bool success = false;
5456 
5457     if (ConditionPassed(opcode))
5458     {
5459         uint32_t Rd, Rn;
5460         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
5461         bool setflags;
5462         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5463         switch (encoding)
5464         {
5465         case eEncodingT1:
5466             Rd = Bits32(opcode, 11, 8);
5467             Rn = Bits32(opcode, 19, 16);
5468             setflags = BitIsSet(opcode, 20);
5469             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5470             // if Rd == '1111' && S == '1' then SEE TST (immediate);
5471             if (Rd == 15 && setflags)
5472                 return EmulateTSTImm(opcode, eEncodingT1);
5473             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
5474                 return false;
5475             break;
5476         case eEncodingA1:
5477             Rd = Bits32(opcode, 15, 12);
5478             Rn = Bits32(opcode, 19, 16);
5479             setflags = BitIsSet(opcode, 20);
5480             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5481 
5482             if (Rd == 15 && setflags)
5483                 return EmulateSUBSPcLrEtc (opcode, encoding);
5484             break;
5485         default:
5486             return false;
5487         }
5488 
5489         // Read the first operand.
5490         uint32_t val1 = ReadCoreReg(Rn, &success);
5491         if (!success)
5492             return false;
5493 
5494         uint32_t result = val1 & imm32;
5495 
5496         EmulateInstruction::Context context;
5497         context.type = EmulateInstruction::eContextImmediate;
5498         context.SetNoArgs ();
5499 
5500         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5501             return false;
5502     }
5503     return true;
5504 }
5505 
5506 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value,
5507 // and writes the result to the destination register.  It can optionally update the condition flags
5508 // based on the result.
5509 bool
5510 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding)
5511 {
5512 #if 0
5513     // ARM pseudo code...
5514     if ConditionPassed() then
5515         EncodingSpecificOperations();
5516         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5517         result = R[n] AND shifted;
5518         if d == 15 then         // Can only occur for ARM encoding
5519             ALUWritePC(result); // setflags is always FALSE here
5520         else
5521             R[d] = result;
5522             if setflags then
5523                 APSR.N = result<31>;
5524                 APSR.Z = IsZeroBit(result);
5525                 APSR.C = carry;
5526                 // APSR.V unchanged
5527 #endif
5528 
5529     bool success = false;
5530 
5531     if (ConditionPassed(opcode))
5532     {
5533         uint32_t Rd, Rn, Rm;
5534         ARM_ShifterType shift_t;
5535         uint32_t shift_n; // the shift applied to the value read from Rm
5536         bool setflags;
5537         uint32_t carry;
5538         switch (encoding)
5539         {
5540         case eEncodingT1:
5541             Rd = Rn = Bits32(opcode, 2, 0);
5542             Rm = Bits32(opcode, 5, 3);
5543             setflags = !InITBlock();
5544             shift_t = SRType_LSL;
5545             shift_n = 0;
5546             break;
5547         case eEncodingT2:
5548             Rd = Bits32(opcode, 11, 8);
5549             Rn = Bits32(opcode, 19, 16);
5550             Rm = Bits32(opcode, 3, 0);
5551             setflags = BitIsSet(opcode, 20);
5552             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5553             // if Rd == '1111' && S == '1' then SEE TST (register);
5554             if (Rd == 15 && setflags)
5555                 return EmulateTSTReg(opcode, eEncodingT2);
5556             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
5557                 return false;
5558             break;
5559         case eEncodingA1:
5560             Rd = Bits32(opcode, 15, 12);
5561             Rn = Bits32(opcode, 19, 16);
5562             Rm = Bits32(opcode, 3, 0);
5563             setflags = BitIsSet(opcode, 20);
5564             shift_n = DecodeImmShiftARM(opcode, shift_t);
5565 
5566             if (Rd == 15 && setflags)
5567                 return EmulateSUBSPcLrEtc (opcode, encoding);
5568             break;
5569         default:
5570             return false;
5571         }
5572 
5573         // Read the first operand.
5574         uint32_t val1 = ReadCoreReg(Rn, &success);
5575         if (!success)
5576             return false;
5577 
5578         // Read the second operand.
5579         uint32_t val2 = ReadCoreReg(Rm, &success);
5580         if (!success)
5581             return false;
5582 
5583         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5584         if (!success)
5585             return false;
5586         uint32_t result = val1 & shifted;
5587 
5588         EmulateInstruction::Context context;
5589         context.type = EmulateInstruction::eContextImmediate;
5590         context.SetNoArgs ();
5591 
5592         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5593             return false;
5594     }
5595     return true;
5596 }
5597 
5598 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an
5599 // immediate value, and writes the result to the destination register.  It can optionally update the
5600 // condition flags based on the result.
5601 bool
5602 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding)
5603 {
5604 #if 0
5605     // ARM pseudo code...
5606     if ConditionPassed() then
5607         EncodingSpecificOperations();
5608         result = R[n] AND NOT(imm32);
5609         if d == 15 then         // Can only occur for ARM encoding
5610             ALUWritePC(result); // setflags is always FALSE here
5611         else
5612             R[d] = result;
5613             if setflags then
5614                 APSR.N = result<31>;
5615                 APSR.Z = IsZeroBit(result);
5616                 APSR.C = carry;
5617                 // APSR.V unchanged
5618 #endif
5619 
5620     bool success = false;
5621 
5622     if (ConditionPassed(opcode))
5623     {
5624         uint32_t Rd, Rn;
5625         uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn
5626         bool setflags;
5627         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5628         switch (encoding)
5629         {
5630         case eEncodingT1:
5631             Rd = Bits32(opcode, 11, 8);
5632             Rn = Bits32(opcode, 19, 16);
5633             setflags = BitIsSet(opcode, 20);
5634             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5635             if (BadReg(Rd) || BadReg(Rn))
5636                 return false;
5637             break;
5638         case eEncodingA1:
5639             Rd = Bits32(opcode, 15, 12);
5640             Rn = Bits32(opcode, 19, 16);
5641             setflags = BitIsSet(opcode, 20);
5642             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5643 
5644             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5645             if (Rd == 15 && setflags)
5646                 return EmulateSUBSPcLrEtc (opcode, encoding);
5647             break;
5648         default:
5649             return false;
5650         }
5651 
5652         // Read the first operand.
5653         uint32_t val1 = ReadCoreReg(Rn, &success);
5654         if (!success)
5655             return false;
5656 
5657         uint32_t result = val1 & ~imm32;
5658 
5659         EmulateInstruction::Context context;
5660         context.type = EmulateInstruction::eContextImmediate;
5661         context.SetNoArgs ();
5662 
5663         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5664             return false;
5665     }
5666     return true;
5667 }
5668 
5669 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an
5670 // optionally-shifted register value, and writes the result to the destination register.
5671 // It can optionally update the condition flags based on the result.
5672 bool
5673 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding)
5674 {
5675 #if 0
5676     // ARM pseudo code...
5677     if ConditionPassed() then
5678         EncodingSpecificOperations();
5679         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5680         result = R[n] AND NOT(shifted);
5681         if d == 15 then         // Can only occur for ARM encoding
5682             ALUWritePC(result); // setflags is always FALSE here
5683         else
5684             R[d] = result;
5685             if setflags then
5686                 APSR.N = result<31>;
5687                 APSR.Z = IsZeroBit(result);
5688                 APSR.C = carry;
5689                 // APSR.V unchanged
5690 #endif
5691 
5692     bool success = false;
5693 
5694     if (ConditionPassed(opcode))
5695     {
5696         uint32_t Rd, Rn, Rm;
5697         ARM_ShifterType shift_t;
5698         uint32_t shift_n; // the shift applied to the value read from Rm
5699         bool setflags;
5700         uint32_t carry;
5701         switch (encoding)
5702         {
5703         case eEncodingT1:
5704             Rd = Rn = Bits32(opcode, 2, 0);
5705             Rm = Bits32(opcode, 5, 3);
5706             setflags = !InITBlock();
5707             shift_t = SRType_LSL;
5708             shift_n = 0;
5709             break;
5710         case eEncodingT2:
5711             Rd = Bits32(opcode, 11, 8);
5712             Rn = Bits32(opcode, 19, 16);
5713             Rm = Bits32(opcode, 3, 0);
5714             setflags = BitIsSet(opcode, 20);
5715             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5716             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5717                 return false;
5718             break;
5719         case eEncodingA1:
5720             Rd = Bits32(opcode, 15, 12);
5721             Rn = Bits32(opcode, 19, 16);
5722             Rm = Bits32(opcode, 3, 0);
5723             setflags = BitIsSet(opcode, 20);
5724             shift_n = DecodeImmShiftARM(opcode, shift_t);
5725 
5726             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5727             if (Rd == 15 && setflags)
5728                 return EmulateSUBSPcLrEtc (opcode, encoding);
5729             break;
5730         default:
5731             return false;
5732         }
5733 
5734         // Read the first operand.
5735         uint32_t val1 = ReadCoreReg(Rn, &success);
5736         if (!success)
5737             return false;
5738 
5739         // Read the second operand.
5740         uint32_t val2 = ReadCoreReg(Rm, &success);
5741         if (!success)
5742             return false;
5743 
5744         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5745         if (!success)
5746             return false;
5747         uint32_t result = val1 & ~shifted;
5748 
5749         EmulateInstruction::Context context;
5750         context.type = EmulateInstruction::eContextImmediate;
5751         context.SetNoArgs ();
5752 
5753         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5754             return false;
5755     }
5756     return true;
5757 }
5758 
5759 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
5760 // from memory, and writes it to a register.  It can use offset, post-indexed, or pre-indexed addressing.
5761 bool
5762 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding)
5763 {
5764 #if 0
5765     if ConditionPassed() then
5766         EncodingSpecificOperations();
5767         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5768         address = if index then offset_addr else R[n];
5769         data = MemU[address,4];
5770         if wback then R[n] = offset_addr;
5771         if t == 15 then
5772             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5773         elsif UnalignedSupport() || address<1:0> = '00' then
5774             R[t] = data;
5775         else // Can only apply before ARMv7
5776             R[t] = ROR(data, 8*UInt(address<1:0>));
5777 #endif
5778 
5779     bool success = false;
5780 
5781     if (ConditionPassed(opcode))
5782     {
5783         const uint32_t addr_byte_size = GetAddressByteSize();
5784 
5785         uint32_t t;
5786         uint32_t n;
5787         uint32_t imm32;
5788         bool index;
5789         bool add;
5790         bool wback;
5791 
5792         switch (encoding)
5793         {
5794             case eEncodingA1:
5795                 // if Rn == '1111' then SEE LDR (literal);
5796                 // if P == '0' && W == '1' then SEE LDRT;
5797                 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP;
5798                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5799                 t = Bits32 (opcode, 15, 12);
5800                 n = Bits32 (opcode, 19, 16);
5801                 imm32 = Bits32 (opcode, 11, 0);
5802 
5803                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5804                 index = BitIsSet (opcode, 24);
5805                 add = BitIsSet (opcode, 23);
5806                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5807 
5808                 // if wback && n == t then UNPREDICTABLE;
5809                 if (wback && (n == t))
5810                     return false;
5811 
5812                 break;
5813 
5814             default:
5815                 return false;
5816         }
5817 
5818         addr_t address;
5819         addr_t offset_addr;
5820         addr_t base_address = ReadCoreReg (n, &success);
5821         if (!success)
5822             return false;
5823 
5824         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5825         if (add)
5826             offset_addr = base_address + imm32;
5827         else
5828             offset_addr = base_address - imm32;
5829 
5830         // address = if index then offset_addr else R[n];
5831         if (index)
5832             address = offset_addr;
5833         else
5834             address = base_address;
5835 
5836         // data = MemU[address,4];
5837 
5838         RegisterInfo base_reg;
5839         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5840 
5841         EmulateInstruction::Context context;
5842         context.type = eContextRegisterLoad;
5843         context.SetRegisterPlusOffset (base_reg, address - base_address);
5844 
5845         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5846         if (!success)
5847             return false;
5848 
5849         // if wback then R[n] = offset_addr;
5850         if (wback)
5851         {
5852             context.type = eContextAdjustBaseRegister;
5853             context.SetAddress (offset_addr);
5854             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5855                 return false;
5856         }
5857 
5858         // if t == 15 then
5859         if (t == 15)
5860         {
5861             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5862             if (BitIsClear (address, 1) && BitIsClear (address, 0))
5863             {
5864                 // LoadWritePC (data);
5865                 context.type = eContextRegisterLoad;
5866                 context.SetRegisterPlusOffset (base_reg, address - base_address);
5867                 LoadWritePC (context, data);
5868             }
5869             else
5870                   return false;
5871         }
5872         // elsif UnalignedSupport() || address<1:0> = '00' then
5873         else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5874         {
5875             // R[t] = data;
5876             context.type = eContextRegisterLoad;
5877             context.SetRegisterPlusOffset (base_reg, address - base_address);
5878             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5879                 return false;
5880         }
5881         // else // Can only apply before ARMv7
5882         else
5883         {
5884             // R[t] = ROR(data, 8*UInt(address<1:0>));
5885             data = ROR (data, Bits32 (address, 1, 0), &success);
5886             if (!success)
5887                 return false;
5888             context.type = eContextRegisterLoad;
5889             context.SetImmediate (data);
5890             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5891                 return false;
5892         }
5893 
5894     }
5895     return true;
5896 }
5897 
5898 // LDR (register) calculates an address from a base register value and an offset register value, loads a word
5899 // from memory, and writes it to a resgister.  The offset register value can optionally be shifted.
5900 bool
5901 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding)
5902 {
5903 #if 0
5904     if ConditionPassed() then
5905         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5906         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5907         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5908         address = if index then offset_addr else R[n];
5909         data = MemU[address,4];
5910         if wback then R[n] = offset_addr;
5911         if t == 15 then
5912             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5913         elsif UnalignedSupport() || address<1:0> = '00' then
5914             R[t] = data;
5915         else // Can only apply before ARMv7
5916             if CurrentInstrSet() == InstrSet_ARM then
5917                 R[t] = ROR(data, 8*UInt(address<1:0>));
5918             else
5919                 R[t] = bits(32) UNKNOWN;
5920 #endif
5921 
5922     bool success = false;
5923 
5924     if (ConditionPassed(opcode))
5925     {
5926         const uint32_t addr_byte_size = GetAddressByteSize();
5927 
5928         uint32_t t;
5929         uint32_t n;
5930         uint32_t m;
5931         bool index;
5932         bool add;
5933         bool wback;
5934         ARM_ShifterType shift_t;
5935         uint32_t shift_n;
5936 
5937         switch (encoding)
5938         {
5939             case eEncodingT1:
5940                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5941                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5942                 t = Bits32 (opcode, 2, 0);
5943                 n = Bits32 (opcode, 5, 3);
5944                 m = Bits32 (opcode, 8, 6);
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, 0);
5952                 shift_t = SRType_LSL;
5953                 shift_n = 0;
5954 
5955                 break;
5956 
5957             case eEncodingT2:
5958                 // if Rn == '1111' then SEE LDR (literal);
5959                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5960                 t = Bits32 (opcode, 15, 12);
5961                 n = Bits32 (opcode, 19, 16);
5962                 m = Bits32 (opcode, 3, 0);
5963 
5964                 // index = TRUE; add = TRUE; wback = FALSE;
5965                 index = true;
5966                 add = true;
5967                 wback = false;
5968 
5969                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5970                 shift_t = SRType_LSL;
5971                 shift_n = Bits32 (opcode, 5, 4);
5972 
5973                 // if BadReg(m) then UNPREDICTABLE;
5974                 if (BadReg (m))
5975                     return false;
5976 
5977                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
5978                 if ((t == 15) && InITBlock() && !LastInITBlock())
5979                     return false;
5980 
5981                 break;
5982 
5983             case eEncodingA1:
5984             {
5985                 // if P == '0' && W == '1' then SEE LDRT;
5986                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5987                 t = Bits32 (opcode, 15, 12);
5988                 n = Bits32 (opcode, 19, 16);
5989                 m = Bits32 (opcode, 3, 0);
5990 
5991                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5992                 index = BitIsSet (opcode, 24);
5993                 add = BitIsSet (opcode, 23);
5994                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5995 
5996                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
5997                 uint32_t type = Bits32 (opcode, 6, 5);
5998                 uint32_t imm5 = Bits32 (opcode, 11, 7);
5999                 shift_n = DecodeImmShift (type, imm5, shift_t);
6000 
6001                 // if m == 15 then UNPREDICTABLE;
6002                 if (m == 15)
6003                     return false;
6004 
6005                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6006                 if (wback && ((n == 15) || (n == t)))
6007                     return false;
6008             }
6009                 break;
6010 
6011 
6012             default:
6013                 return false;
6014         }
6015 
6016         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6017         if (!success)
6018             return false;
6019 
6020         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6021         if (!success)
6022             return false;
6023 
6024         addr_t offset_addr;
6025         addr_t address;
6026 
6027         // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an application level alias for the CPSR".
6028         addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success);
6029         if (!success)
6030             return false;
6031 
6032         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6033         if (add)
6034             offset_addr = Rn + offset;
6035         else
6036             offset_addr = Rn - offset;
6037 
6038         // address = if index then offset_addr else R[n];
6039             if (index)
6040                 address = offset_addr;
6041             else
6042                 address = Rn;
6043 
6044         // data = MemU[address,4];
6045         RegisterInfo base_reg;
6046         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6047 
6048         EmulateInstruction::Context context;
6049         context.type = eContextRegisterLoad;
6050         context.SetRegisterPlusOffset (base_reg, address - Rn);
6051 
6052         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
6053         if (!success)
6054             return false;
6055 
6056         // if wback then R[n] = offset_addr;
6057         if (wback)
6058         {
6059             context.type = eContextAdjustBaseRegister;
6060             context.SetAddress (offset_addr);
6061             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6062                 return false;
6063         }
6064 
6065         // if t == 15 then
6066         if (t == 15)
6067         {
6068             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6069             if (BitIsClear (address, 1) && BitIsClear (address, 0))
6070             {
6071                 context.type = eContextRegisterLoad;
6072                 context.SetRegisterPlusOffset (base_reg, address - Rn);
6073                 LoadWritePC (context, data);
6074             }
6075             else
6076                 return false;
6077         }
6078         // elsif UnalignedSupport() || address<1:0> = '00' then
6079         else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
6080         {
6081             // R[t] = data;
6082             context.type = eContextRegisterLoad;
6083             context.SetRegisterPlusOffset (base_reg, address - Rn);
6084             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6085                 return false;
6086         }
6087         else // Can only apply before ARMv7
6088         {
6089             // if CurrentInstrSet() == InstrSet_ARM then
6090             if (CurrentInstrSet () == eModeARM)
6091             {
6092                 // R[t] = ROR(data, 8*UInt(address<1:0>));
6093                 data = ROR (data, Bits32 (address, 1, 0), &success);
6094                 if (!success)
6095                     return false;
6096                 context.type = eContextRegisterLoad;
6097                 context.SetImmediate (data);
6098                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6099                     return false;
6100             }
6101             else
6102             {
6103                 // R[t] = bits(32) UNKNOWN;
6104                 WriteBits32Unknown (t);
6105             }
6106         }
6107     }
6108     return true;
6109 }
6110 
6111 // LDRB (immediate, Thumb)
6112 bool
6113 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6114 {
6115 #if 0
6116     if ConditionPassed() then
6117         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6118         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6119         address = if index then offset_addr else R[n];
6120         R[t] = ZeroExtend(MemU[address,1], 32);
6121         if wback then R[n] = offset_addr;
6122 #endif
6123 
6124     bool success = false;
6125 
6126     if (ConditionPassed(opcode))
6127     {
6128         uint32_t t;
6129         uint32_t n;
6130         uint32_t imm32;
6131         bool index;
6132         bool add;
6133         bool wback;
6134 
6135         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6136         switch (encoding)
6137         {
6138             case eEncodingT1:
6139                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6140                 t = Bits32 (opcode, 2, 0);
6141                 n = Bits32 (opcode, 5, 3);
6142                 imm32 = Bits32 (opcode, 10, 6);
6143 
6144                 // index = TRUE; add = TRUE; wback = FALSE;
6145                 index = true;
6146                 add = true;
6147                 wback= false;
6148 
6149                 break;
6150 
6151             case eEncodingT2:
6152                 // if Rt == '1111' then SEE PLD;
6153                 // if Rn == '1111' then SEE LDRB (literal);
6154                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6155                 t = Bits32 (opcode, 15, 12);
6156                 n = Bits32 (opcode, 19, 16);
6157                 imm32 = Bits32 (opcode, 11, 0);
6158 
6159                 // index = TRUE; add = TRUE; wback = FALSE;
6160                 index = true;
6161                 add = true;
6162                 wback = false;
6163 
6164                 // if t == 13 then UNPREDICTABLE;
6165                 if (t == 13)
6166                     return false;
6167 
6168                 break;
6169 
6170             case eEncodingT3:
6171                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6172                 // if Rn == '1111' then SEE LDRB (literal);
6173                 // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6174                 // if P == '0' && W == '0' then UNDEFINED;
6175                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6176                     return false;
6177 
6178                   // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6179                 t = Bits32 (opcode, 15, 12);
6180                 n = Bits32 (opcode, 19, 16);
6181                 imm32 = Bits32 (opcode, 7, 0);
6182 
6183                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6184                 index = BitIsSet (opcode, 10);
6185                 add = BitIsSet (opcode, 9);
6186                 wback = BitIsSet (opcode, 8);
6187 
6188                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6189                 if (BadReg (t) || (wback && (n == t)))
6190                     return false;
6191 
6192                 break;
6193 
6194             default:
6195                 return false;
6196         }
6197 
6198         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6199         if (!success)
6200             return false;
6201 
6202         addr_t address;
6203         addr_t offset_addr;
6204 
6205         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6206         if (add)
6207             offset_addr = Rn + imm32;
6208         else
6209             offset_addr = Rn - imm32;
6210 
6211         // address = if index then offset_addr else R[n];
6212         if (index)
6213             address = offset_addr;
6214         else
6215             address = Rn;
6216 
6217         // R[t] = ZeroExtend(MemU[address,1], 32);
6218         RegisterInfo base_reg;
6219         RegisterInfo data_reg;
6220         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6221         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6222 
6223         EmulateInstruction::Context context;
6224         context.type = eContextRegisterLoad;
6225         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
6226 
6227         uint64_t data = MemURead (context, address, 1, 0, &success);
6228         if (!success)
6229             return false;
6230 
6231         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6232             return false;
6233 
6234         // if wback then R[n] = offset_addr;
6235         if (wback)
6236         {
6237             context.type = eContextAdjustBaseRegister;
6238             context.SetAddress (offset_addr);
6239             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6240                 return false;
6241         }
6242     }
6243     return true;
6244 }
6245 
6246 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6247 // zero-extends it to form a 32-bit word and writes it to a register.
6248 bool
6249 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6250 {
6251 #if 0
6252     if ConditionPassed() then
6253         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6254         base = Align(PC,4);
6255         address = if add then (base + imm32) else (base - imm32);
6256         R[t] = ZeroExtend(MemU[address,1], 32);
6257 #endif
6258 
6259     bool success = false;
6260 
6261     if (ConditionPassed(opcode))
6262     {
6263         uint32_t t;
6264         uint32_t imm32;
6265         bool add;
6266         switch (encoding)
6267         {
6268             case eEncodingT1:
6269                 // if Rt == '1111' then SEE PLD;
6270                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6271                 t = Bits32 (opcode, 15, 12);
6272                 imm32 = Bits32 (opcode, 11, 0);
6273                 add = BitIsSet (opcode, 23);
6274 
6275                 // if t == 13 then UNPREDICTABLE;
6276                 if (t == 13)
6277                     return false;
6278 
6279                 break;
6280 
6281             case eEncodingA1:
6282                 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6283                 t = Bits32 (opcode, 15, 12);
6284                 imm32 = Bits32 (opcode, 11, 0);
6285                 add = BitIsSet (opcode, 23);
6286 
6287                 // if t == 15 then UNPREDICTABLE;
6288                 if (t == 15)
6289                     return false;
6290                 break;
6291 
6292             default:
6293                 return false;
6294         }
6295 
6296         // base = Align(PC,4);
6297         uint32_t pc_val = ReadCoreReg (PC_REG, &success);
6298         if (!success)
6299             return false;
6300 
6301         uint32_t base = AlignPC (pc_val);
6302 
6303         addr_t address;
6304         // address = if add then (base + imm32) else (base - imm32);
6305         if (add)
6306             address = base + imm32;
6307         else
6308             address = base - imm32;
6309 
6310         // R[t] = ZeroExtend(MemU[address,1], 32);
6311         EmulateInstruction::Context context;
6312         context.type = eContextRelativeBranchImmediate;
6313         context.SetImmediate (address - base);
6314 
6315         uint64_t data = MemURead (context, address, 1, 0, &success);
6316         if (!success)
6317             return false;
6318 
6319         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6320             return false;
6321     }
6322     return true;
6323 }
6324 
6325 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from
6326 // memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6327 // optionally be shifted.
6328 bool
6329 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding)
6330 {
6331 #if 0
6332     if ConditionPassed() then
6333         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6334         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6335         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6336         address = if index then offset_addr else R[n];
6337         R[t] = ZeroExtend(MemU[address,1],32);
6338         if wback then R[n] = offset_addr;
6339 #endif
6340 
6341     bool success = false;
6342 
6343     if (ConditionPassed(opcode))
6344     {
6345         uint32_t t;
6346         uint32_t n;
6347         uint32_t m;
6348         bool index;
6349         bool add;
6350         bool wback;
6351         ARM_ShifterType shift_t;
6352         uint32_t shift_n;
6353 
6354         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6355         switch (encoding)
6356         {
6357             case eEncodingT1:
6358                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6359                 t = Bits32 (opcode, 2, 0);
6360                 n = Bits32 (opcode, 5, 3);
6361                 m = Bits32 (opcode, 8, 6);
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, 0);
6369                 shift_t = SRType_LSL;
6370                 shift_n = 0;
6371                 break;
6372 
6373             case eEncodingT2:
6374                 // if Rt == '1111' then SEE PLD;
6375                 // if Rn == '1111' then SEE LDRB (literal);
6376                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6377                 t = Bits32 (opcode, 15, 12);
6378                 n = Bits32 (opcode, 19, 16);
6379                 m = Bits32 (opcode, 3, 0);
6380 
6381                 // index = TRUE; add = TRUE; wback = FALSE;
6382                 index = true;
6383                 add = true;
6384                 wback = false;
6385 
6386                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6387                 shift_t = SRType_LSL;
6388                 shift_n = Bits32 (opcode, 5, 4);
6389 
6390                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6391                 if ((t == 13) || BadReg (m))
6392                     return false;
6393                 break;
6394 
6395             case eEncodingA1:
6396             {
6397                 // if P == '0' && W == '1' then SEE LDRBT;
6398                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6399                 t = Bits32 (opcode, 15, 12);
6400                 n = Bits32 (opcode, 19, 16);
6401                 m = Bits32 (opcode, 3, 0);
6402 
6403                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6404                 index = BitIsSet (opcode, 24);
6405                 add = BitIsSet (opcode, 23);
6406                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6407 
6408                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6409                 uint32_t type = Bits32 (opcode, 6, 5);
6410                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6411                 shift_n = DecodeImmShift (type, imm5, shift_t);
6412 
6413                 // if t == 15 || m == 15 then UNPREDICTABLE;
6414                 if ((t == 15) || (m == 15))
6415                     return false;
6416 
6417                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6418                 if (wback && ((n == 15) || (n == t)))
6419                     return false;
6420             }
6421                 break;
6422 
6423             default:
6424                 return false;
6425         }
6426 
6427         addr_t offset_addr;
6428         addr_t address;
6429 
6430         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6431         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6432         if (!success)
6433             return false;
6434 
6435         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6436         if (!success)
6437             return false;
6438 
6439         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6440         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6441         if (!success)
6442             return false;
6443 
6444         if (add)
6445             offset_addr = Rn + offset;
6446         else
6447             offset_addr = Rn - offset;
6448 
6449         // address = if index then offset_addr else R[n];
6450         if (index)
6451             address = offset_addr;
6452         else
6453             address = Rn;
6454 
6455         // R[t] = ZeroExtend(MemU[address,1],32);
6456         RegisterInfo base_reg;
6457         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6458 
6459         EmulateInstruction::Context context;
6460         context.type = eContextRegisterLoad;
6461         context.SetRegisterPlusOffset (base_reg, address - Rn);
6462 
6463         uint64_t data = MemURead (context, address, 1, 0, &success);
6464         if (!success)
6465             return false;
6466 
6467         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6468             return false;
6469 
6470         // if wback then R[n] = offset_addr;
6471         if (wback)
6472         {
6473             context.type = eContextAdjustBaseRegister;
6474             context.SetAddress (offset_addr);
6475             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6476                 return false;
6477         }
6478     }
6479     return true;
6480 }
6481 
6482 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a
6483 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register.  It can use offset,
6484 // post-indexed, or pre-indexed addressing.
6485 bool
6486 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding)
6487 {
6488 #if 0
6489     if ConditionPassed() then
6490         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6491         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6492         address = if index then offset_addr else R[n];
6493         data = MemU[address,2];
6494         if wback then R[n] = offset_addr;
6495         if UnalignedSupport() || address<0> = '0' then
6496             R[t] = ZeroExtend(data, 32);
6497         else // Can only apply before ARMv7
6498             R[t] = bits(32) UNKNOWN;
6499 #endif
6500 
6501 
6502     bool success = false;
6503 
6504     if (ConditionPassed(opcode))
6505     {
6506         uint32_t t;
6507         uint32_t n;
6508         uint32_t imm32;
6509         bool index;
6510         bool add;
6511         bool wback;
6512 
6513         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6514         switch (encoding)
6515         {
6516             case eEncodingT1:
6517                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
6518                 t = Bits32 (opcode, 2, 0);
6519                 n = Bits32 (opcode, 5, 3);
6520                 imm32 = Bits32 (opcode, 10, 6) << 1;
6521 
6522                 // index = TRUE; add = TRUE; wback = FALSE;
6523                 index = true;
6524                 add = true;
6525                 wback = false;
6526 
6527                 break;
6528 
6529             case eEncodingT2:
6530                 // if Rt == '1111' then SEE "Unallocated memory hints";
6531                 // if Rn == '1111' then SEE LDRH (literal);
6532                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6533                 t = Bits32 (opcode, 15, 12);
6534                 n = Bits32 (opcode, 19, 16);
6535                 imm32 = Bits32 (opcode, 11, 0);
6536 
6537                 // index = TRUE; add = TRUE; wback = FALSE;
6538                 index = true;
6539                 add = true;
6540                 wback = false;
6541 
6542                 // if t == 13 then UNPREDICTABLE;
6543                 if (t == 13)
6544                     return false;
6545                 break;
6546 
6547             case eEncodingT3:
6548                 // if Rn == '1111' then SEE LDRH (literal);
6549                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
6550                 // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
6551                 // if P == '0' && W == '0' then UNDEFINED;
6552                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6553                     return false;
6554 
6555                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6556                 t = Bits32 (opcode, 15, 12);
6557                 n = Bits32 (opcode, 19, 16);
6558                 imm32 = Bits32 (opcode, 7, 0);
6559 
6560                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6561                 index = BitIsSet (opcode, 10);
6562                 add = BitIsSet (opcode, 9);
6563                 wback = BitIsSet (opcode, 8);
6564 
6565                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6566                 if (BadReg (t) || (wback && (n == t)))
6567                     return false;
6568                 break;
6569 
6570             default:
6571                 return false;
6572         }
6573 
6574         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6575         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6576         if (!success)
6577             return false;
6578 
6579         addr_t offset_addr;
6580         addr_t address;
6581 
6582         if (add)
6583             offset_addr = Rn + imm32;
6584         else
6585             offset_addr = Rn - imm32;
6586 
6587         // address = if index then offset_addr else R[n];
6588         if (index)
6589             address = offset_addr;
6590         else
6591             address = Rn;
6592 
6593         // data = MemU[address,2];
6594         RegisterInfo base_reg;
6595         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6596 
6597         EmulateInstruction::Context context;
6598         context.type = eContextRegisterLoad;
6599         context.SetRegisterPlusOffset (base_reg, address - Rn);
6600 
6601         uint64_t data = MemURead (context, address, 2, 0, &success);
6602         if (!success)
6603             return false;
6604 
6605         // if wback then R[n] = offset_addr;
6606         if (wback)
6607         {
6608             context.type = eContextAdjustBaseRegister;
6609             context.SetAddress (offset_addr);
6610             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6611                 return false;
6612         }
6613 
6614         // if UnalignedSupport() || address<0> = '0' then
6615         if (UnalignedSupport () || BitIsClear (address, 0))
6616         {
6617             // R[t] = ZeroExtend(data, 32);
6618             context.type = eContextRegisterLoad;
6619             context.SetRegisterPlusOffset (base_reg, address - Rn);
6620             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6621                 return false;
6622         }
6623         else // Can only apply before ARMv7
6624         {
6625             // R[t] = bits(32) UNKNOWN;
6626             WriteBits32Unknown (t);
6627         }
6628     }
6629     return true;
6630 }
6631 
6632 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory,
6633 // zero-extends it to form a 32-bit word, and writes it to a register.
6634 bool
6635 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding)
6636 {
6637 #if 0
6638     if ConditionPassed() then
6639         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6640         base = Align(PC,4);
6641         address = if add then (base + imm32) else (base - imm32);
6642         data = MemU[address,2];
6643         if UnalignedSupport() || address<0> = '0' then
6644             R[t] = ZeroExtend(data, 32);
6645         else // Can only apply before ARMv7
6646             R[t] = bits(32) UNKNOWN;
6647 #endif
6648 
6649     bool success = false;
6650 
6651     if (ConditionPassed(opcode))
6652     {
6653         uint32_t t;
6654         uint32_t imm32;
6655         bool add;
6656 
6657         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6658         switch (encoding)
6659         {
6660             case eEncodingT1:
6661                 // if Rt == '1111' then SEE "Unallocated memory hints";
6662                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6663                 t = Bits32 (opcode, 15, 12);
6664                 imm32 = Bits32 (opcode, 11, 0);
6665                 add = BitIsSet (opcode, 23);
6666 
6667                 // if t == 13 then UNPREDICTABLE;
6668                 if (t == 13)
6669                     return false;
6670 
6671                 break;
6672 
6673             case eEncodingA1:
6674             {
6675                 uint32_t imm4H = Bits32 (opcode, 11, 8);
6676                 uint32_t imm4L = Bits32 (opcode, 3, 0);
6677 
6678                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6679                 t = Bits32 (opcode, 15, 12);
6680                 imm32 = (imm4H << 4) | imm4L;
6681                 add = BitIsSet (opcode, 23);
6682 
6683                 // if t == 15 then UNPREDICTABLE;
6684                 if (t == 15)
6685                     return false;
6686                 break;
6687             }
6688 
6689             default:
6690                 return false;
6691         }
6692 
6693         // base = Align(PC,4);
6694         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6695         if (!success)
6696             return false;
6697 
6698         addr_t base = AlignPC (pc_value);
6699         addr_t address;
6700 
6701         // address = if add then (base + imm32) else (base - imm32);
6702         if (add)
6703             address = base + imm32;
6704         else
6705             address = base - imm32;
6706 
6707         // data = MemU[address,2];
6708         RegisterInfo base_reg;
6709         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
6710 
6711         EmulateInstruction::Context context;
6712         context.type = eContextRegisterLoad;
6713         context.SetRegisterPlusOffset (base_reg, address - base);
6714 
6715         uint64_t data = MemURead (context, address, 2, 0, &success);
6716         if (!success)
6717             return false;
6718 
6719 
6720         // if UnalignedSupport() || address<0> = '0' then
6721         if (UnalignedSupport () || BitIsClear (address, 0))
6722         {
6723             // R[t] = ZeroExtend(data, 32);
6724             context.type = eContextRegisterLoad;
6725             context.SetRegisterPlusOffset (base_reg, address - base);
6726             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6727                 return false;
6728 
6729         }
6730         else // Can only apply before ARMv7
6731         {
6732             // R[t] = bits(32) UNKNOWN;
6733             WriteBits32Unknown (t);
6734         }
6735     }
6736     return true;
6737 }
6738 
6739 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword
6740 // from memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6741 // be shifted left by 0, 1, 2, or 3 bits.
6742 bool
6743 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding)
6744 {
6745 #if 0
6746     if ConditionPassed() then
6747         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6748         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6749         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6750         address = if index then offset_addr else R[n];
6751         data = MemU[address,2];
6752         if wback then R[n] = offset_addr;
6753         if UnalignedSupport() || address<0> = '0' then
6754             R[t] = ZeroExtend(data, 32);
6755         else // Can only apply before ARMv7
6756             R[t] = bits(32) UNKNOWN;
6757 #endif
6758 
6759     bool success = false;
6760 
6761     if (ConditionPassed(opcode))
6762     {
6763         uint32_t t;
6764         uint32_t n;
6765         uint32_t m;
6766         bool index;
6767         bool add;
6768         bool wback;
6769         ARM_ShifterType shift_t;
6770         uint32_t shift_n;
6771 
6772         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6773         switch (encoding)
6774         {
6775             case eEncodingT1:
6776                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6777                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6778                 t = Bits32 (opcode, 2, 0);
6779                 n = Bits32 (opcode, 5, 3);
6780                 m = Bits32 (opcode, 8, 6);
6781 
6782                 // index = TRUE; add = TRUE; wback = FALSE;
6783                 index = true;
6784                 add = true;
6785                 wback = false;
6786 
6787                 // (shift_t, shift_n) = (SRType_LSL, 0);
6788                 shift_t = SRType_LSL;
6789                 shift_n = 0;
6790 
6791                 break;
6792 
6793             case eEncodingT2:
6794                 // if Rn == '1111' then SEE LDRH (literal);
6795                 // if Rt == '1111' then SEE "Unallocated memory hints";
6796                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6797                 t = Bits32 (opcode, 15, 12);
6798                 n = Bits32 (opcode, 19, 16);
6799                 m = Bits32 (opcode, 3, 0);
6800 
6801                 // index = TRUE; add = TRUE; wback = FALSE;
6802                 index = true;
6803                 add = true;
6804                 wback = false;
6805 
6806                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6807                 shift_t = SRType_LSL;
6808                 shift_n = Bits32 (opcode, 5, 4);
6809 
6810                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6811                 if ((t == 13) || BadReg (m))
6812                     return false;
6813                 break;
6814 
6815             case eEncodingA1:
6816                 // if P == '0' && W == '1' then SEE LDRHT;
6817                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6818                 t = Bits32 (opcode, 15, 12);
6819                 n = Bits32 (opcode, 19, 16);
6820                 m = Bits32 (opcode, 3, 0);
6821 
6822                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6823                 index = BitIsSet (opcode, 24);
6824                 add = BitIsSet (opcode, 23);
6825                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6826 
6827                 // (shift_t, shift_n) = (SRType_LSL, 0);
6828                 shift_t = SRType_LSL;
6829                 shift_n = 0;
6830 
6831                 // if t == 15 || m == 15 then UNPREDICTABLE;
6832                 if ((t == 15) || (m == 15))
6833                     return false;
6834 
6835                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6836                 if (wback && ((n == 15) || (n == t)))
6837                     return false;
6838 
6839                 break;
6840 
6841             default:
6842                 return false;
6843         }
6844 
6845         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6846 
6847         uint64_t Rm  = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6848         if (!success)
6849             return false;
6850 
6851         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6852         if (!success)
6853             return false;
6854 
6855         addr_t offset_addr;
6856         addr_t address;
6857 
6858         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6859         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6860         if (!success)
6861             return false;
6862 
6863         if (add)
6864             offset_addr = Rn + offset;
6865         else
6866             offset_addr = Rn - offset;
6867 
6868         // address = if index then offset_addr else R[n];
6869         if (index)
6870             address = offset_addr;
6871         else
6872             address = Rn;
6873 
6874         // data = MemU[address,2];
6875         RegisterInfo base_reg;
6876         RegisterInfo offset_reg;
6877         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6878         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
6879 
6880         EmulateInstruction::Context context;
6881         context.type = eContextRegisterLoad;
6882         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6883         uint64_t data = MemURead (context, address, 2, 0, &success);
6884         if (!success)
6885             return false;
6886 
6887         // if wback then R[n] = offset_addr;
6888         if (wback)
6889         {
6890             context.type = eContextAdjustBaseRegister;
6891             context.SetAddress (offset_addr);
6892             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6893                 return false;
6894         }
6895 
6896         // if UnalignedSupport() || address<0> = '0' then
6897         if (UnalignedSupport() || BitIsClear (address, 0))
6898         {
6899             // R[t] = ZeroExtend(data, 32);
6900             context.type = eContextRegisterLoad;
6901             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6902             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6903                 return false;
6904         }
6905         else // Can only apply before ARMv7
6906         {
6907             // R[t] = bits(32) UNKNOWN;
6908             WriteBits32Unknown (t);
6909         }
6910     }
6911     return true;
6912 }
6913 
6914 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from
6915 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed,
6916 // or pre-indexed addressing.
6917 bool
6918 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6919 {
6920 #if 0
6921     if ConditionPassed() then
6922         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6923         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6924         address = if index then offset_addr else R[n];
6925         R[t] = SignExtend(MemU[address,1], 32);
6926         if wback then R[n] = offset_addr;
6927 #endif
6928 
6929     bool success = false;
6930 
6931     if (ConditionPassed(opcode))
6932     {
6933         uint32_t t;
6934         uint32_t n;
6935         uint32_t imm32;
6936         bool index;
6937         bool add;
6938         bool wback;
6939 
6940         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6941         switch (encoding)
6942         {
6943             case eEncodingT1:
6944                 // if Rt == '1111' then SEE PLI;
6945                 // if Rn == '1111' then SEE LDRSB (literal);
6946                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6947                 t = Bits32 (opcode, 15, 12);
6948                 n = Bits32 (opcode, 19, 16);
6949                 imm32 = Bits32 (opcode, 11, 0);
6950 
6951                 // index = TRUE; add = TRUE; wback = FALSE;
6952                 index = true;
6953                 add = true;
6954                 wback = false;
6955 
6956                 // if t == 13 then UNPREDICTABLE;
6957                 if (t == 13)
6958                     return false;
6959 
6960                 break;
6961 
6962             case eEncodingT2:
6963                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
6964                 // if Rn == '1111' then SEE LDRSB (literal);
6965                 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
6966                 // if P == '0' && W == '0' then UNDEFINED;
6967                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6968                     return false;
6969 
6970                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6971                 t = Bits32 (opcode, 15, 12);
6972                 n = Bits32 (opcode, 19, 16);
6973                 imm32 = Bits32 (opcode, 7, 0);
6974 
6975                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6976                 index = BitIsSet (opcode, 10);
6977                 add = BitIsSet (opcode, 9);
6978                 wback = BitIsSet (opcode, 8);
6979 
6980                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6981                   if (((t == 13) || ((t == 15)
6982                                      && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8))))
6983                       || (wback && (n == t)))
6984                     return false;
6985 
6986                 break;
6987 
6988             case eEncodingA1:
6989             {
6990                 // if Rn == '1111' then SEE LDRSB (literal);
6991                 // if P == '0' && W == '1' then SEE LDRSBT;
6992                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
6993                 t = Bits32 (opcode, 15, 12);
6994                 n = Bits32 (opcode, 19, 16);
6995 
6996                 uint32_t imm4H = Bits32 (opcode, 11, 8);
6997                 uint32_t imm4L = Bits32 (opcode, 3, 0);
6998                 imm32 = (imm4H << 4) | imm4L;
6999 
7000                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7001                 index = BitIsSet (opcode, 24);
7002                 add = BitIsSet (opcode, 23);
7003                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
7004 
7005                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7006                 if ((t == 15) || (wback && (n == t)))
7007                     return false;
7008 
7009                 break;
7010             }
7011 
7012             default:
7013                 return false;
7014         }
7015 
7016         uint64_t Rn = ReadCoreReg (n, &success);
7017         if (!success)
7018             return false;
7019 
7020         addr_t offset_addr;
7021         addr_t address;
7022 
7023         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7024         if (add)
7025             offset_addr = Rn + imm32;
7026         else
7027             offset_addr = Rn - imm32;
7028 
7029         // address = if index then offset_addr else R[n];
7030         if (index)
7031             address = offset_addr;
7032         else
7033             address = Rn;
7034 
7035         // R[t] = SignExtend(MemU[address,1], 32);
7036         RegisterInfo base_reg;
7037         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7038 
7039         EmulateInstruction::Context context;
7040         context.type = eContextRegisterLoad;
7041         context.SetRegisterPlusOffset (base_reg, address - Rn);
7042 
7043         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7044         if (!success)
7045             return false;
7046 
7047         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7048         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7049             return false;
7050 
7051         // if wback then R[n] = offset_addr;
7052         if (wback)
7053         {
7054             context.type = eContextAdjustBaseRegister;
7055             context.SetAddress (offset_addr);
7056             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7057                 return false;
7058         }
7059     }
7060 
7061     return true;
7062 }
7063 
7064 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
7065 // sign-extends it to form a 32-bit word, and writes tit to a register.
7066 bool
7067 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding)
7068 {
7069 #if 0
7070     if ConditionPassed() then
7071         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7072         base = Align(PC,4);
7073         address = if add then (base + imm32) else (base - imm32);
7074         R[t] = SignExtend(MemU[address,1], 32);
7075 #endif
7076 
7077     bool success = false;
7078 
7079     if (ConditionPassed(opcode))
7080     {
7081         uint32_t t;
7082         uint32_t imm32;
7083         bool add;
7084 
7085         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7086         switch (encoding)
7087         {
7088             case eEncodingT1:
7089                 // if Rt == '1111' then SEE PLI;
7090                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7091                 t = Bits32 (opcode, 15, 12);
7092                 imm32 = Bits32 (opcode, 11, 0);
7093                 add = BitIsSet (opcode, 23);
7094 
7095                 // if t == 13 then UNPREDICTABLE;
7096                 if (t == 13)
7097                     return false;
7098 
7099                 break;
7100 
7101             case eEncodingA1:
7102             {
7103                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7104                 t = Bits32 (opcode, 15, 12);
7105                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7106                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7107                 imm32 = (imm4H << 4) | imm4L;
7108                 add = BitIsSet (opcode, 23);
7109 
7110                 // if t == 15 then UNPREDICTABLE;
7111                 if (t == 15)
7112                     return false;
7113 
7114                 break;
7115             }
7116 
7117             default:
7118                 return false;
7119         }
7120 
7121         // base = Align(PC,4);
7122         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7123         if (!success)
7124             return false;
7125         uint64_t base = AlignPC (pc_value);
7126 
7127         // address = if add then (base + imm32) else (base - imm32);
7128         addr_t address;
7129         if (add)
7130             address = base + imm32;
7131         else
7132             address = base - imm32;
7133 
7134         // R[t] = SignExtend(MemU[address,1], 32);
7135         RegisterInfo base_reg;
7136         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7137 
7138         EmulateInstruction::Context context;
7139         context.type = eContextRegisterLoad;
7140         context.SetRegisterPlusOffset (base_reg, address - base);
7141 
7142         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7143         if (!success)
7144             return false;
7145 
7146         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7147         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7148             return false;
7149     }
7150     return true;
7151 }
7152 
7153 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from
7154 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7155 // shifted left by 0, 1, 2, or 3 bits.
7156 bool
7157 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding)
7158 {
7159 #if 0
7160     if ConditionPassed() then
7161         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7162         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7163         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7164         address = if index then offset_addr else R[n];
7165         R[t] = SignExtend(MemU[address,1], 32);
7166         if wback then R[n] = offset_addr;
7167 #endif
7168 
7169     bool success = false;
7170 
7171     if (ConditionPassed(opcode))
7172     {
7173         uint32_t t;
7174         uint32_t n;
7175         uint32_t m;
7176         bool index;
7177         bool add;
7178         bool wback;
7179         ARM_ShifterType shift_t;
7180         uint32_t shift_n;
7181 
7182         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7183         switch (encoding)
7184         {
7185             case eEncodingT1:
7186                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7187                 t = Bits32 (opcode, 2, 0);
7188                 n = Bits32 (opcode, 5, 3);
7189                 m = Bits32 (opcode, 8, 6);
7190 
7191                 // index = TRUE; add = TRUE; wback = FALSE;
7192                 index = true;
7193                 add = true;
7194                 wback = false;
7195 
7196                 // (shift_t, shift_n) = (SRType_LSL, 0);
7197                 shift_t = SRType_LSL;
7198                 shift_n = 0;
7199 
7200                 break;
7201 
7202             case eEncodingT2:
7203                 // if Rt == '1111' then SEE PLI;
7204                 // if Rn == '1111' then SEE LDRSB (literal);
7205                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7206                 t = Bits32 (opcode, 15, 12);
7207                 n = Bits32 (opcode, 19, 16);
7208                 m = Bits32 (opcode, 3, 0);
7209 
7210                 // index = TRUE; add = TRUE; wback = FALSE;
7211                 index = true;
7212                 add = true;
7213                 wback = false;
7214 
7215                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7216                 shift_t = SRType_LSL;
7217                 shift_n = Bits32 (opcode, 5, 4);
7218 
7219                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7220                 if ((t == 13) || BadReg (m))
7221                     return false;
7222                 break;
7223 
7224             case eEncodingA1:
7225                 // if P == '0' && W == '1' then SEE LDRSBT;
7226                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7227                 t = Bits32 (opcode, 15, 12);
7228                 n = Bits32 (opcode, 19, 16);
7229                 m = Bits32 (opcode, 3, 0);
7230 
7231                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7232                 index = BitIsSet (opcode, 24);
7233                 add = BitIsSet (opcode, 23);
7234                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7235 
7236                 // (shift_t, shift_n) = (SRType_LSL, 0);
7237                 shift_t = SRType_LSL;
7238                 shift_n = 0;
7239 
7240                 // if t == 15 || m == 15 then UNPREDICTABLE;
7241                 if ((t == 15) || (m == 15))
7242                     return false;
7243 
7244                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7245                 if (wback && ((n == 15) || (n == t)))
7246                     return false;
7247                 break;
7248 
7249             default:
7250                 return false;
7251         }
7252 
7253         uint64_t Rm =  ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7254         if (!success)
7255             return false;
7256 
7257         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7258         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7259         if (!success)
7260             return false;
7261 
7262         addr_t offset_addr;
7263         addr_t address;
7264 
7265         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7266         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7267         if (!success)
7268             return false;
7269 
7270         if (add)
7271             offset_addr = Rn + offset;
7272         else
7273             offset_addr = Rn - offset;
7274 
7275         // address = if index then offset_addr else R[n];
7276         if (index)
7277             address = offset_addr;
7278         else
7279             address = Rn;
7280 
7281         // R[t] = SignExtend(MemU[address,1], 32);
7282         RegisterInfo base_reg;
7283         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7284         RegisterInfo offset_reg;
7285         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7286 
7287         EmulateInstruction::Context context;
7288         context.type = eContextRegisterLoad;
7289         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7290 
7291         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7292         if (!success)
7293             return false;
7294 
7295         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7296         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7297             return false;
7298 
7299         // if wback then R[n] = offset_addr;
7300         if (wback)
7301         {
7302             context.type = eContextAdjustBaseRegister;
7303             context.SetAddress (offset_addr);
7304             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7305                 return false;
7306         }
7307     }
7308     return true;
7309 }
7310 
7311 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from
7312 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed, or
7313 // pre-indexed addressing.
7314 bool
7315 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding)
7316 {
7317 #if 0
7318     if ConditionPassed() then
7319         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7320         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7321         address = if index then offset_addr else R[n];
7322         data = MemU[address,2];
7323         if wback then R[n] = offset_addr;
7324         if UnalignedSupport() || address<0> = '0' then
7325             R[t] = SignExtend(data, 32);
7326         else // Can only apply before ARMv7
7327             R[t] = bits(32) UNKNOWN;
7328 #endif
7329 
7330     bool success = false;
7331 
7332     if (ConditionPassed(opcode))
7333     {
7334         uint32_t t;
7335         uint32_t n;
7336         uint32_t imm32;
7337         bool index;
7338         bool add;
7339         bool wback;
7340 
7341         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7342         switch (encoding)
7343         {
7344             case eEncodingT1:
7345                 // if Rn == '1111' then SEE LDRSH (literal);
7346                 // if Rt == '1111' then SEE "Unallocated memory hints";
7347                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7348                 t = Bits32 (opcode, 15, 12);
7349                 n = Bits32 (opcode, 19, 16);
7350                 imm32 = Bits32 (opcode, 11, 0);
7351 
7352                 // index = TRUE; add = TRUE; wback = FALSE;
7353                 index = true;
7354                 add = true;
7355                 wback = false;
7356 
7357                 // if t == 13 then UNPREDICTABLE;
7358                 if (t == 13)
7359                     return false;
7360 
7361                 break;
7362 
7363             case eEncodingT2:
7364                 // if Rn == '1111' then SEE LDRSH (literal);
7365                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
7366                 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7367                 // if P == '0' && W == '0' then UNDEFINED;
7368                   if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7369                   return false;
7370 
7371                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7372                 t = Bits32 (opcode, 15, 12);
7373                 n = Bits32 (opcode, 19, 16);
7374                 imm32 = Bits32 (opcode, 7, 0);
7375 
7376                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7377                 index = BitIsSet (opcode, 10);
7378                 add = BitIsSet (opcode, 9);
7379                 wback = BitIsSet (opcode, 8);
7380 
7381                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7382                 if (BadReg (t) || (wback && (n == t)))
7383                     return false;
7384 
7385                 break;
7386 
7387             case eEncodingA1:
7388             {
7389                 // if Rn == '1111' then SEE LDRSH (literal);
7390                 // if P == '0' && W == '1' then SEE LDRSHT;
7391                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7392                 t = Bits32 (opcode, 15, 12);
7393                 n = Bits32 (opcode, 19, 16);
7394                 uint32_t imm4H = Bits32 (opcode, 11,8);
7395                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7396                 imm32 = (imm4H << 4) | imm4L;
7397 
7398                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7399                 index = BitIsSet (opcode, 24);
7400                 add = BitIsSet (opcode, 23);
7401                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7402 
7403                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7404                 if ((t == 15) || (wback && (n == t)))
7405                     return false;
7406 
7407                 break;
7408             }
7409 
7410             default:
7411                 return false;
7412         }
7413 
7414         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7415         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7416         if (!success)
7417             return false;
7418 
7419         addr_t offset_addr;
7420         if (add)
7421             offset_addr = Rn + imm32;
7422         else
7423             offset_addr = Rn - imm32;
7424 
7425         // address = if index then offset_addr else R[n];
7426         addr_t address;
7427         if (index)
7428             address = offset_addr;
7429         else
7430             address = Rn;
7431 
7432         // data = MemU[address,2];
7433         RegisterInfo base_reg;
7434         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7435 
7436         EmulateInstruction::Context context;
7437         context.type = eContextRegisterLoad;
7438         context.SetRegisterPlusOffset (base_reg, address - Rn);
7439 
7440         uint64_t data = MemURead (context, address, 2, 0, &success);
7441         if (!success)
7442             return false;
7443 
7444         // if wback then R[n] = offset_addr;
7445         if (wback)
7446         {
7447             context.type = eContextAdjustBaseRegister;
7448             context.SetAddress (offset_addr);
7449             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7450                 return false;
7451         }
7452 
7453         // if UnalignedSupport() || address<0> = '0' then
7454         if (UnalignedSupport() || BitIsClear (address, 0))
7455         {
7456             // R[t] = SignExtend(data, 32);
7457             int64_t signed_data = llvm::SignExtend64<16>(data);
7458             context.type = eContextRegisterLoad;
7459             context.SetRegisterPlusOffset (base_reg, address - Rn);
7460             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7461                 return false;
7462         }
7463         else // Can only apply before ARMv7
7464         {
7465             // R[t] = bits(32) UNKNOWN;
7466             WriteBits32Unknown (t);
7467         }
7468     }
7469     return true;
7470 }
7471 
7472 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory,
7473 // sign-extends it to from a 32-bit word, and writes it to a register.
7474 bool
7475 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding)
7476 {
7477 #if 0
7478     if ConditionPassed() then
7479         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7480         base = Align(PC,4);
7481         address = if add then (base + imm32) else (base - imm32);
7482         data = MemU[address,2];
7483         if UnalignedSupport() || address<0> = '0' then
7484             R[t] = SignExtend(data, 32);
7485         else // Can only apply before ARMv7
7486             R[t] = bits(32) UNKNOWN;
7487 #endif
7488 
7489     bool success = false;
7490 
7491     if (ConditionPassed(opcode))
7492     {
7493         uint32_t t;
7494         uint32_t imm32;
7495         bool add;
7496 
7497         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7498         switch (encoding)
7499         {
7500             case eEncodingT1:
7501                 // if Rt == '1111' then SEE "Unallocated memory hints";
7502                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7503                 t = Bits32  (opcode, 15, 12);
7504                 imm32 = Bits32 (opcode, 11, 0);
7505                 add = BitIsSet (opcode, 23);
7506 
7507                 // if t == 13 then UNPREDICTABLE;
7508                 if (t == 13)
7509                     return false;
7510 
7511                 break;
7512 
7513             case eEncodingA1:
7514             {
7515                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7516                 t = Bits32 (opcode, 15, 12);
7517                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7518                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7519                 imm32 = (imm4H << 4) | imm4L;
7520                 add = BitIsSet (opcode, 23);
7521 
7522                 // if t == 15 then UNPREDICTABLE;
7523                 if (t == 15)
7524                     return false;
7525 
7526                 break;
7527             }
7528             default:
7529                 return false;
7530         }
7531 
7532         // base = Align(PC,4);
7533         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7534         if (!success)
7535             return false;
7536 
7537         uint64_t base = AlignPC (pc_value);
7538 
7539         addr_t address;
7540         // address = if add then (base + imm32) else (base - imm32);
7541         if (add)
7542             address = base + imm32;
7543         else
7544             address = base - imm32;
7545 
7546         // data = MemU[address,2];
7547         RegisterInfo base_reg;
7548         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7549 
7550         EmulateInstruction::Context context;
7551         context.type = eContextRegisterLoad;
7552         context.SetRegisterPlusOffset (base_reg, imm32);
7553 
7554         uint64_t data = MemURead (context, address, 2, 0, &success);
7555         if (!success)
7556             return false;
7557 
7558         // if UnalignedSupport() || address<0> = '0' then
7559         if (UnalignedSupport() || BitIsClear (address, 0))
7560         {
7561             // R[t] = SignExtend(data, 32);
7562             int64_t signed_data = llvm::SignExtend64<16>(data);
7563             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7564                 return false;
7565         }
7566         else // Can only apply before ARMv7
7567         {
7568             // R[t] = bits(32) UNKNOWN;
7569             WriteBits32Unknown (t);
7570         }
7571     }
7572     return true;
7573 }
7574 
7575 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword
7576 // from memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7577 // shifted left by 0, 1, 2, or 3 bits.
7578 bool
7579 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding)
7580 {
7581 #if 0
7582     if ConditionPassed() then
7583         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7584         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7585         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7586         address = if index then offset_addr else R[n];
7587         data = MemU[address,2];
7588         if wback then R[n] = offset_addr;
7589         if UnalignedSupport() || address<0> = '0' then
7590             R[t] = SignExtend(data, 32);
7591         else // Can only apply before ARMv7
7592             R[t] = bits(32) UNKNOWN;
7593 #endif
7594 
7595     bool success = false;
7596 
7597     if (ConditionPassed(opcode))
7598     {
7599         uint32_t t;
7600         uint32_t n;
7601         uint32_t m;
7602         bool index;
7603         bool add;
7604         bool wback;
7605         ARM_ShifterType shift_t;
7606         uint32_t shift_n;
7607 
7608         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7609         switch (encoding)
7610         {
7611             case eEncodingT1:
7612                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
7613                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7614                 t = Bits32 (opcode, 2, 0);
7615                 n = Bits32 (opcode, 5, 3);
7616                 m = Bits32 (opcode, 8, 6);
7617 
7618                 // index = TRUE; add = TRUE; wback = FALSE;
7619                 index = true;
7620                 add = true;
7621                 wback = false;
7622 
7623                 // (shift_t, shift_n) = (SRType_LSL, 0);
7624                 shift_t = SRType_LSL;
7625                 shift_n = 0;
7626 
7627                 break;
7628 
7629             case eEncodingT2:
7630                 // if Rn == '1111' then SEE LDRSH (literal);
7631                 // if Rt == '1111' then SEE "Unallocated memory hints";
7632                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7633                 t = Bits32 (opcode, 15, 12);
7634                 n = Bits32 (opcode, 19, 16);
7635                 m = Bits32 (opcode, 3, 0);
7636 
7637                 // index = TRUE; add = TRUE; wback = FALSE;
7638                 index = true;
7639                 add = true;
7640                 wback = false;
7641 
7642                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7643                 shift_t = SRType_LSL;
7644                 shift_n = Bits32 (opcode, 5, 4);
7645 
7646                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7647                 if ((t == 13) || BadReg (m))
7648                     return false;
7649 
7650                 break;
7651 
7652             case eEncodingA1:
7653                 // if P == '0' && W == '1' then SEE LDRSHT;
7654                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7655                 t = Bits32 (opcode, 15, 12);
7656                 n = Bits32 (opcode, 19, 16);
7657                 m = Bits32 (opcode, 3, 0);
7658 
7659                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7660                 index = BitIsSet (opcode, 24);
7661                 add = BitIsSet (opcode, 23);
7662                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7663 
7664                 // (shift_t, shift_n) = (SRType_LSL, 0);
7665                 shift_t = SRType_LSL;
7666                 shift_n = 0;
7667 
7668                 // if t == 15 || m == 15 then UNPREDICTABLE;
7669                 if ((t == 15) || (m == 15))
7670                     return false;
7671 
7672                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7673                 if (wback && ((n == 15) || (n == t)))
7674                     return false;
7675 
7676                 break;
7677 
7678             default:
7679                 return false;
7680         }
7681 
7682         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7683         if (!success)
7684             return false;
7685 
7686         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7687         if (!success)
7688             return false;
7689 
7690         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7691         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7692         if (!success)
7693             return false;
7694 
7695         addr_t offset_addr;
7696         addr_t address;
7697 
7698         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7699         if (add)
7700             offset_addr = Rn + offset;
7701         else
7702             offset_addr = Rn - offset;
7703 
7704         // address = if index then offset_addr else R[n];
7705         if (index)
7706             address = offset_addr;
7707         else
7708             address = Rn;
7709 
7710         // data = MemU[address,2];
7711         RegisterInfo base_reg;
7712         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7713 
7714         RegisterInfo offset_reg;
7715         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7716 
7717         EmulateInstruction::Context context;
7718         context.type = eContextRegisterLoad;
7719         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7720 
7721         uint64_t data = MemURead (context, address, 2, 0, &success);
7722         if (!success)
7723             return false;
7724 
7725         // if wback then R[n] = offset_addr;
7726         if (wback)
7727         {
7728             context.type = eContextAdjustBaseRegister;
7729             context.SetAddress (offset_addr);
7730             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7731                 return false;
7732         }
7733 
7734         // if UnalignedSupport() || address<0> = '0' then
7735         if (UnalignedSupport() || BitIsClear (address, 0))
7736         {
7737             // R[t] = SignExtend(data, 32);
7738             context.type = eContextRegisterLoad;
7739             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7740 
7741             int64_t signed_data = llvm::SignExtend64<16>(data);
7742             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7743                 return false;
7744         }
7745         else // Can only apply before ARMv7
7746         {
7747             // R[t] = bits(32) UNKNOWN;
7748             WriteBits32Unknown (t);
7749         }
7750     }
7751     return true;
7752 }
7753 
7754 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7755 // register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7756 bool
7757 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding)
7758 {
7759 #if 0
7760     if ConditionPassed() then
7761         EncodingSpecificOperations();
7762         rotated = ROR(R[m], rotation);
7763         R[d] = SignExtend(rotated<7:0>, 32);
7764 #endif
7765 
7766     bool success = false;
7767 
7768     if (ConditionPassed(opcode))
7769     {
7770         uint32_t d;
7771         uint32_t m;
7772         uint32_t rotation;
7773 
7774         // EncodingSpecificOperations();
7775         switch (encoding)
7776         {
7777             case eEncodingT1:
7778                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7779                 d = Bits32 (opcode, 2, 0);
7780                 m = Bits32 (opcode, 5, 3);
7781                 rotation = 0;
7782 
7783                 break;
7784 
7785             case eEncodingT2:
7786                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7787                 d = Bits32 (opcode, 11, 8);
7788                 m = Bits32 (opcode, 3, 0);
7789                 rotation = Bits32 (opcode, 5, 4) << 3;
7790 
7791                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7792                 if (BadReg (d) || BadReg (m))
7793                     return false;
7794 
7795                 break;
7796 
7797             case eEncodingA1:
7798                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7799                 d = Bits32 (opcode, 15, 12);
7800                 m = Bits32 (opcode, 3, 0);
7801                 rotation = Bits32 (opcode, 11, 10) << 3;
7802 
7803                 // if d == 15 || m == 15 then UNPREDICTABLE;
7804                 if ((d == 15) || (m == 15))
7805                     return false;
7806 
7807                 break;
7808 
7809             default:
7810                 return false;
7811         }
7812 
7813         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7814         if (!success)
7815             return false;
7816 
7817         // rotated = ROR(R[m], rotation);
7818         uint64_t rotated = ROR (Rm, rotation, &success);
7819         if (!success)
7820             return false;
7821 
7822         // R[d] = SignExtend(rotated<7:0>, 32);
7823         int64_t data = llvm::SignExtend64<8>(rotated);
7824 
7825         RegisterInfo source_reg;
7826         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7827 
7828         EmulateInstruction::Context context;
7829         context.type = eContextRegisterLoad;
7830         context.SetRegister (source_reg);
7831 
7832         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7833             return false;
7834     }
7835     return true;
7836 }
7837 
7838 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7839 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7840 bool
7841 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding)
7842 {
7843 #if 0
7844     if ConditionPassed() then
7845         EncodingSpecificOperations();
7846         rotated = ROR(R[m], rotation);
7847         R[d] = SignExtend(rotated<15:0>, 32);
7848 #endif
7849 
7850     bool success = false;
7851 
7852     if (ConditionPassed(opcode))
7853     {
7854         uint32_t d;
7855         uint32_t m;
7856         uint32_t rotation;
7857 
7858         // EncodingSpecificOperations();
7859         switch (encoding)
7860         {
7861             case eEncodingT1:
7862                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7863                 d = Bits32 (opcode, 2, 0);
7864                 m = Bits32 (opcode, 5, 3);
7865                 rotation = 0;
7866 
7867                 break;
7868 
7869             case eEncodingT2:
7870                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7871                 d = Bits32 (opcode, 11, 8);
7872                 m = Bits32 (opcode, 3, 0);
7873                 rotation = Bits32 (opcode, 5, 4) << 3;
7874 
7875                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7876                 if (BadReg (d) || BadReg (m))
7877                     return false;
7878 
7879                 break;
7880 
7881             case eEncodingA1:
7882                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7883                 d = Bits32 (opcode, 15, 12);
7884                 m = Bits32 (opcode, 3, 0);
7885                 rotation = Bits32 (opcode, 11, 10) << 3;
7886 
7887                 // if d == 15 || m == 15 then UNPREDICTABLE;
7888                 if ((d == 15) || (m == 15))
7889                     return false;
7890 
7891                 break;
7892 
7893             default:
7894                 return false;
7895         }
7896 
7897         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7898         if (!success)
7899             return false;
7900 
7901         // rotated = ROR(R[m], rotation);
7902         uint64_t rotated = ROR (Rm, rotation, &success);
7903         if (!success)
7904             return false;
7905 
7906         // R[d] = SignExtend(rotated<15:0>, 32);
7907         RegisterInfo source_reg;
7908         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7909 
7910         EmulateInstruction::Context context;
7911         context.type = eContextRegisterLoad;
7912         context.SetRegister (source_reg);
7913 
7914         int64_t data = llvm::SignExtend64<16> (rotated);
7915         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7916             return false;
7917     }
7918 
7919     return true;
7920 }
7921 
7922 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination
7923 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7924 bool
7925 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding)
7926 {
7927 #if 0
7928     if ConditionPassed() then
7929         EncodingSpecificOperations();
7930         rotated = ROR(R[m], rotation);
7931         R[d] = ZeroExtend(rotated<7:0>, 32);
7932 #endif
7933 
7934     bool success = false;
7935 
7936     if (ConditionPassed(opcode))
7937     {
7938         uint32_t d;
7939         uint32_t m;
7940         uint32_t rotation;
7941 
7942         // EncodingSpecificOperations();
7943         switch (encoding)
7944         {
7945             case eEncodingT1:
7946                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7947                 d = Bits32 (opcode, 2, 0);
7948                 m = Bits32 (opcode, 5, 3);
7949                 rotation = 0;
7950 
7951                 break;
7952 
7953             case eEncodingT2:
7954                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7955                 d = Bits32 (opcode, 11, 8);
7956                 m = Bits32 (opcode, 3, 0);
7957                   rotation = Bits32 (opcode, 5, 4) << 3;
7958 
7959                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7960                 if (BadReg (d) || BadReg (m))
7961                   return false;
7962 
7963                 break;
7964 
7965             case eEncodingA1:
7966                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7967                 d = Bits32 (opcode, 15, 12);
7968                 m = Bits32 (opcode, 3, 0);
7969                 rotation = Bits32 (opcode, 11, 10) << 3;
7970 
7971                 // if d == 15 || m == 15 then UNPREDICTABLE;
7972                 if ((d == 15) || (m == 15))
7973                     return false;
7974 
7975                 break;
7976 
7977             default:
7978                 return false;
7979         }
7980 
7981         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7982         if (!success)
7983             return false;
7984 
7985         // rotated = ROR(R[m], rotation);
7986         uint64_t rotated = ROR (Rm, rotation, &success);
7987         if (!success)
7988             return false;
7989 
7990         // R[d] = ZeroExtend(rotated<7:0>, 32);
7991         RegisterInfo source_reg;
7992         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7993 
7994         EmulateInstruction::Context context;
7995         context.type = eContextRegisterLoad;
7996         context.SetRegister (source_reg);
7997 
7998         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0)))
7999             return false;
8000     }
8001     return true;
8002 }
8003 
8004 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination
8005 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
8006 bool
8007 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding)
8008 {
8009 #if 0
8010     if ConditionPassed() then
8011         EncodingSpecificOperations();
8012         rotated = ROR(R[m], rotation);
8013         R[d] = ZeroExtend(rotated<15:0>, 32);
8014 #endif
8015 
8016     bool success = false;
8017 
8018     if (ConditionPassed(opcode))
8019     {
8020         uint32_t d;
8021         uint32_t m;
8022         uint32_t rotation;
8023 
8024         switch (encoding)
8025         {
8026             case eEncodingT1:
8027                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8028                 d = Bits32 (opcode, 2, 0);
8029                 m = Bits32 (opcode, 5, 3);
8030                 rotation = 0;
8031 
8032                 break;
8033 
8034             case eEncodingT2:
8035                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8036                 d = Bits32 (opcode, 11, 8);
8037                 m = Bits32 (opcode, 3, 0);
8038                 rotation = Bits32 (opcode, 5, 4) << 3;
8039 
8040                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8041                 if (BadReg (d) || BadReg (m))
8042                   return false;
8043 
8044                 break;
8045 
8046             case eEncodingA1:
8047                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8048                 d = Bits32 (opcode, 15, 12);
8049                 m = Bits32 (opcode, 3, 0);
8050                 rotation = Bits32 (opcode, 11, 10) << 3;
8051 
8052                 // if d == 15 || m == 15 then UNPREDICTABLE;
8053                 if ((d == 15) || (m == 15))
8054                     return false;
8055 
8056                 break;
8057 
8058             default:
8059                 return false;
8060         }
8061 
8062         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8063         if (!success)
8064             return false;
8065 
8066         // rotated = ROR(R[m], rotation);
8067         uint64_t rotated = ROR (Rm, rotation, &success);
8068         if (!success)
8069             return false;
8070 
8071         // R[d] = ZeroExtend(rotated<15:0>, 32);
8072         RegisterInfo source_reg;
8073         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8074 
8075         EmulateInstruction::Context context;
8076         context.type = eContextRegisterLoad;
8077         context.SetRegister (source_reg);
8078 
8079         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0)))
8080             return false;
8081     }
8082     return true;
8083 }
8084 
8085 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following
8086 // word respectively.
8087 bool
8088 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding)
8089 {
8090 #if 0
8091     if ConditionPassed() then
8092         EncodingSpecificOperations();
8093         if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8094             UNPREDICTABLE;
8095         else
8096             address = if increment then R[n] else R[n]-8;
8097             if wordhigher then address = address+4;
8098             CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8099             BranchWritePC(MemA[address,4]);
8100             if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8101 #endif
8102 
8103     bool success = false;
8104 
8105     if (ConditionPassed(opcode))
8106     {
8107         uint32_t n;
8108         bool wback;
8109         bool increment;
8110         bool wordhigher;
8111 
8112         // EncodingSpecificOperations();
8113         switch (encoding)
8114         {
8115             case eEncodingT1:
8116                 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE;
8117                 n = Bits32 (opcode, 19, 16);
8118                 wback = BitIsSet (opcode, 21);
8119                 increment = false;
8120                 wordhigher = false;
8121 
8122                 // if n == 15 then UNPREDICTABLE;
8123                 if (n == 15)
8124                     return false;
8125 
8126                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8127                 if (InITBlock() && !LastInITBlock())
8128                     return false;
8129 
8130                 break;
8131 
8132             case eEncodingT2:
8133                 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8134                 n = Bits32 (opcode, 19, 16);
8135                 wback = BitIsSet (opcode, 21);
8136                 increment = true;
8137                 wordhigher = false;
8138 
8139                 // if n == 15 then UNPREDICTABLE;
8140                 if (n == 15)
8141                     return false;
8142 
8143                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8144                 if (InITBlock() && !LastInITBlock())
8145                     return false;
8146 
8147                 break;
8148 
8149             case eEncodingA1:
8150                 // n = UInt(Rn);
8151                 n = Bits32 (opcode, 19, 16);
8152 
8153                 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8154                 wback = BitIsSet (opcode, 21);
8155                 increment = BitIsSet (opcode, 23);
8156                 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23));
8157 
8158                 // if n == 15 then UNPREDICTABLE;
8159                 if (n == 15)
8160                     return false;
8161 
8162                 break;
8163 
8164             default:
8165                 return false;
8166         }
8167 
8168         // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8169         if (!CurrentModeIsPrivileged ())
8170             // UNPREDICTABLE;
8171             return false;
8172         else
8173         {
8174             uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8175             if (!success)
8176                 return false;
8177 
8178             addr_t address;
8179             // address = if increment then R[n] else R[n]-8;
8180             if (increment)
8181                 address = Rn;
8182             else
8183                 address = Rn - 8;
8184 
8185             // if wordhigher then address = address+4;
8186             if (wordhigher)
8187                 address = address + 4;
8188 
8189             // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8190             RegisterInfo base_reg;
8191             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8192 
8193             EmulateInstruction::Context context;
8194             context.type = eContextReturnFromException;
8195             context.SetRegisterPlusOffset (base_reg, address - Rn);
8196 
8197             uint64_t data = MemARead (context, address + 4, 4, 0, &success);
8198             if (!success)
8199                 return false;
8200 
8201             CPSRWriteByInstr (data, 15, true);
8202 
8203             // BranchWritePC(MemA[address,4]);
8204             uint64_t data2 = MemARead (context, address, 4, 0, &success);
8205             if (!success)
8206                 return false;
8207 
8208             BranchWritePC (context, data2);
8209 
8210             // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8211             if (wback)
8212             {
8213                 context.type = eContextAdjustBaseRegister;
8214                 if (increment)
8215                 {
8216                     context.SetOffset (8);
8217                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8))
8218                         return false;
8219                 }
8220                 else
8221                 {
8222                     context.SetOffset (-8);
8223                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8))
8224                         return false;
8225                 }
8226             } // if wback
8227         }
8228     } // if ConditionPassed()
8229     return true;
8230 }
8231 
8232 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
8233 // and writes the result to the destination register.  It can optionally update the condition flags based on
8234 // the result.
8235 bool
8236 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding)
8237 {
8238 #if 0
8239     // ARM pseudo code...
8240     if ConditionPassed() then
8241         EncodingSpecificOperations();
8242         result = R[n] EOR imm32;
8243         if d == 15 then         // Can only occur for ARM encoding
8244             ALUWritePC(result); // setflags is always FALSE here
8245         else
8246             R[d] = result;
8247             if setflags then
8248                 APSR.N = result<31>;
8249                 APSR.Z = IsZeroBit(result);
8250                 APSR.C = carry;
8251                 // APSR.V unchanged
8252 #endif
8253 
8254     bool success = false;
8255 
8256     if (ConditionPassed(opcode))
8257     {
8258         uint32_t Rd, Rn;
8259         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8260         bool setflags;
8261         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8262         switch (encoding)
8263         {
8264         case eEncodingT1:
8265             Rd = Bits32(opcode, 11, 8);
8266             Rn = Bits32(opcode, 19, 16);
8267             setflags = BitIsSet(opcode, 20);
8268             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8269             // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8270             if (Rd == 15 && setflags)
8271                 return EmulateTEQImm (opcode, eEncodingT1);
8272             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8273                 return false;
8274             break;
8275         case eEncodingA1:
8276             Rd = Bits32(opcode, 15, 12);
8277             Rn = Bits32(opcode, 19, 16);
8278             setflags = BitIsSet(opcode, 20);
8279             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8280 
8281             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8282             if (Rd == 15 && setflags)
8283                 return EmulateSUBSPcLrEtc (opcode, encoding);
8284             break;
8285         default:
8286             return false;
8287         }
8288 
8289         // Read the first operand.
8290         uint32_t val1 = ReadCoreReg(Rn, &success);
8291         if (!success)
8292             return false;
8293 
8294         uint32_t result = val1 ^ imm32;
8295 
8296         EmulateInstruction::Context context;
8297         context.type = EmulateInstruction::eContextImmediate;
8298         context.SetNoArgs ();
8299 
8300         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8301             return false;
8302     }
8303     return true;
8304 }
8305 
8306 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an
8307 // optionally-shifted register value, and writes the result to the destination register.
8308 // It can optionally update the condition flags based on the result.
8309 bool
8310 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding)
8311 {
8312 #if 0
8313     // ARM pseudo code...
8314     if ConditionPassed() then
8315         EncodingSpecificOperations();
8316         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8317         result = R[n] EOR shifted;
8318         if d == 15 then         // Can only occur for ARM encoding
8319             ALUWritePC(result); // setflags is always FALSE here
8320         else
8321             R[d] = result;
8322             if setflags then
8323                 APSR.N = result<31>;
8324                 APSR.Z = IsZeroBit(result);
8325                 APSR.C = carry;
8326                 // APSR.V unchanged
8327 #endif
8328 
8329     bool success = false;
8330 
8331     if (ConditionPassed(opcode))
8332     {
8333         uint32_t Rd, Rn, Rm;
8334         ARM_ShifterType shift_t;
8335         uint32_t shift_n; // the shift applied to the value read from Rm
8336         bool setflags;
8337         uint32_t carry;
8338         switch (encoding)
8339         {
8340         case eEncodingT1:
8341             Rd = Rn = Bits32(opcode, 2, 0);
8342             Rm = Bits32(opcode, 5, 3);
8343             setflags = !InITBlock();
8344             shift_t = SRType_LSL;
8345             shift_n = 0;
8346             break;
8347         case eEncodingT2:
8348             Rd = Bits32(opcode, 11, 8);
8349             Rn = Bits32(opcode, 19, 16);
8350             Rm = Bits32(opcode, 3, 0);
8351             setflags = BitIsSet(opcode, 20);
8352             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8353             // if Rd == '1111' && S == '1' then SEE TEQ (register);
8354             if (Rd == 15 && setflags)
8355                 return EmulateTEQReg (opcode, eEncodingT1);
8356             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8357                 return false;
8358             break;
8359         case eEncodingA1:
8360             Rd = Bits32(opcode, 15, 12);
8361             Rn = Bits32(opcode, 19, 16);
8362             Rm = Bits32(opcode, 3, 0);
8363             setflags = BitIsSet(opcode, 20);
8364             shift_n = DecodeImmShiftARM(opcode, shift_t);
8365 
8366             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8367             if (Rd == 15 && setflags)
8368                 return EmulateSUBSPcLrEtc (opcode, encoding);
8369             break;
8370         default:
8371             return false;
8372         }
8373 
8374         // Read the first operand.
8375         uint32_t val1 = ReadCoreReg(Rn, &success);
8376         if (!success)
8377             return false;
8378 
8379         // Read the second operand.
8380         uint32_t val2 = ReadCoreReg(Rm, &success);
8381         if (!success)
8382             return false;
8383 
8384         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8385         if (!success)
8386             return false;
8387         uint32_t result = val1 ^ shifted;
8388 
8389         EmulateInstruction::Context context;
8390         context.type = EmulateInstruction::eContextImmediate;
8391         context.SetNoArgs ();
8392 
8393         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8394             return false;
8395     }
8396     return true;
8397 }
8398 
8399 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and
8400 // writes the result to the destination register.  It can optionally update the condition flags based
8401 // on the result.
8402 bool
8403 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding)
8404 {
8405 #if 0
8406     // ARM pseudo code...
8407     if ConditionPassed() then
8408         EncodingSpecificOperations();
8409         result = R[n] OR imm32;
8410         if d == 15 then         // Can only occur for ARM encoding
8411             ALUWritePC(result); // setflags is always FALSE here
8412         else
8413             R[d] = result;
8414             if setflags then
8415                 APSR.N = result<31>;
8416                 APSR.Z = IsZeroBit(result);
8417                 APSR.C = carry;
8418                 // APSR.V unchanged
8419 #endif
8420 
8421     bool success = false;
8422 
8423     if (ConditionPassed(opcode))
8424     {
8425         uint32_t Rd, Rn;
8426         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8427         bool setflags;
8428         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8429         switch (encoding)
8430         {
8431         case eEncodingT1:
8432             Rd = Bits32(opcode, 11, 8);
8433             Rn = Bits32(opcode, 19, 16);
8434             setflags = BitIsSet(opcode, 20);
8435             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8436             // if Rn == '1111' then SEE MOV (immediate);
8437             if (Rn == 15)
8438                 return EmulateMOVRdImm (opcode, eEncodingT2);
8439             if (BadReg(Rd) || Rn == 13)
8440                 return false;
8441             break;
8442         case eEncodingA1:
8443             Rd = Bits32(opcode, 15, 12);
8444             Rn = Bits32(opcode, 19, 16);
8445             setflags = BitIsSet(opcode, 20);
8446             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8447 
8448             if (Rd == 15 && setflags)
8449                 return EmulateSUBSPcLrEtc (opcode, encoding);
8450             break;
8451         default:
8452             return false;
8453         }
8454 
8455         // Read the first operand.
8456         uint32_t val1 = ReadCoreReg(Rn, &success);
8457         if (!success)
8458             return false;
8459 
8460         uint32_t result = val1 | imm32;
8461 
8462         EmulateInstruction::Context context;
8463         context.type = EmulateInstruction::eContextImmediate;
8464         context.SetNoArgs ();
8465 
8466         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8467             return false;
8468     }
8469     return true;
8470 }
8471 
8472 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register
8473 // value, and writes the result to the destination register.  It can optionally update the condition flags based
8474 // on the result.
8475 bool
8476 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding)
8477 {
8478 #if 0
8479     // ARM pseudo code...
8480     if ConditionPassed() then
8481         EncodingSpecificOperations();
8482         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8483         result = R[n] OR shifted;
8484         if d == 15 then         // Can only occur for ARM encoding
8485             ALUWritePC(result); // setflags is always FALSE here
8486         else
8487             R[d] = result;
8488             if setflags then
8489                 APSR.N = result<31>;
8490                 APSR.Z = IsZeroBit(result);
8491                 APSR.C = carry;
8492                 // APSR.V unchanged
8493 #endif
8494 
8495     bool success = false;
8496 
8497     if (ConditionPassed(opcode))
8498     {
8499         uint32_t Rd, Rn, Rm;
8500         ARM_ShifterType shift_t;
8501         uint32_t shift_n; // the shift applied to the value read from Rm
8502         bool setflags;
8503         uint32_t carry;
8504         switch (encoding)
8505         {
8506         case eEncodingT1:
8507             Rd = Rn = Bits32(opcode, 2, 0);
8508             Rm = Bits32(opcode, 5, 3);
8509             setflags = !InITBlock();
8510             shift_t = SRType_LSL;
8511             shift_n = 0;
8512             break;
8513         case eEncodingT2:
8514             Rd = Bits32(opcode, 11, 8);
8515             Rn = Bits32(opcode, 19, 16);
8516             Rm = Bits32(opcode, 3, 0);
8517             setflags = BitIsSet(opcode, 20);
8518             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8519             // if Rn == '1111' then SEE MOV (register);
8520             if (Rn == 15)
8521                 return EmulateMOVRdRm (opcode, eEncodingT3);
8522             if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
8523                 return false;
8524             break;
8525         case eEncodingA1:
8526             Rd = Bits32(opcode, 15, 12);
8527             Rn = Bits32(opcode, 19, 16);
8528             Rm = Bits32(opcode, 3, 0);
8529             setflags = BitIsSet(opcode, 20);
8530             shift_n = DecodeImmShiftARM(opcode, shift_t);
8531 
8532             if (Rd == 15 && setflags)
8533                 return EmulateSUBSPcLrEtc (opcode, encoding);
8534             break;
8535         default:
8536             return false;
8537         }
8538 
8539         // Read the first operand.
8540         uint32_t val1 = ReadCoreReg(Rn, &success);
8541         if (!success)
8542             return false;
8543 
8544         // Read the second operand.
8545         uint32_t val2 = ReadCoreReg(Rm, &success);
8546         if (!success)
8547             return false;
8548 
8549         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8550         if (!success)
8551             return false;
8552         uint32_t result = val1 | shifted;
8553 
8554         EmulateInstruction::Context context;
8555         context.type = EmulateInstruction::eContextImmediate;
8556         context.SetNoArgs ();
8557 
8558         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8559             return false;
8560     }
8561     return true;
8562 }
8563 
8564 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to
8565 // the destination register. It can optionally update the condition flags based on the result.
8566 bool
8567 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding)
8568 {
8569 #if 0
8570     // ARM pseudo code...
8571     if ConditionPassed() then
8572         EncodingSpecificOperations();
8573         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
8574         if d == 15 then         // Can only occur for ARM encoding
8575             ALUWritePC(result); // setflags is always FALSE here
8576         else
8577             R[d] = result;
8578             if setflags then
8579                 APSR.N = result<31>;
8580                 APSR.Z = IsZeroBit(result);
8581                 APSR.C = carry;
8582                 APSR.V = overflow;
8583 #endif
8584 
8585     bool success = false;
8586 
8587     uint32_t Rd; // the destination register
8588     uint32_t Rn; // the first operand
8589     bool setflags;
8590     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8591     switch (encoding) {
8592     case eEncodingT1:
8593         Rd = Bits32(opcode, 2, 0);
8594         Rn = Bits32(opcode, 5, 3);
8595         setflags = !InITBlock();
8596         imm32 = 0;
8597         break;
8598     case eEncodingT2:
8599         Rd = Bits32(opcode, 11, 8);
8600         Rn = Bits32(opcode, 19, 16);
8601         setflags = BitIsSet(opcode, 20);
8602         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8603         if (BadReg(Rd) || BadReg(Rn))
8604             return false;
8605         break;
8606     case eEncodingA1:
8607         Rd = Bits32(opcode, 15, 12);
8608         Rn = Bits32(opcode, 19, 16);
8609         setflags = BitIsSet(opcode, 20);
8610         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8611 
8612         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8613         if (Rd == 15 && setflags)
8614             return EmulateSUBSPcLrEtc (opcode, encoding);
8615         break;
8616     default:
8617         return false;
8618     }
8619     // Read the register value from the operand register Rn.
8620     uint32_t reg_val = ReadCoreReg(Rn, &success);
8621     if (!success)
8622         return false;
8623 
8624     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
8625 
8626     EmulateInstruction::Context context;
8627     context.type = EmulateInstruction::eContextImmediate;
8628     context.SetNoArgs ();
8629 
8630     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8631         return false;
8632 
8633     return true;
8634 }
8635 
8636 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the
8637 // result to the destination register. It can optionally update the condition flags based on the result.
8638 bool
8639 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding)
8640 {
8641 #if 0
8642     // ARM pseudo code...
8643     if ConditionPassed() then
8644         EncodingSpecificOperations();
8645         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8646         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
8647         if d == 15 then         // Can only occur for ARM encoding
8648             ALUWritePC(result); // setflags is always FALSE here
8649         else
8650             R[d] = result;
8651             if setflags then
8652                 APSR.N = result<31>;
8653                 APSR.Z = IsZeroBit(result);
8654                 APSR.C = carry;
8655                 APSR.V = overflow;
8656 #endif
8657 
8658     bool success = false;
8659 
8660     uint32_t Rd; // the destination register
8661     uint32_t Rn; // the first operand
8662     uint32_t Rm; // the second operand
8663     bool setflags;
8664     ARM_ShifterType shift_t;
8665     uint32_t shift_n; // the shift applied to the value read from Rm
8666     switch (encoding) {
8667     case eEncodingT1:
8668         Rd = Bits32(opcode, 11, 8);
8669         Rn = Bits32(opcode, 19, 16);
8670         Rm = Bits32(opcode, 3, 0);
8671         setflags = BitIsSet(opcode, 20);
8672         shift_n = DecodeImmShiftThumb(opcode, shift_t);
8673         // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
8674         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8675             return false;
8676         break;
8677     case eEncodingA1:
8678         Rd = Bits32(opcode, 15, 12);
8679         Rn = Bits32(opcode, 19, 16);
8680         Rm = Bits32(opcode, 3, 0);
8681         setflags = BitIsSet(opcode, 20);
8682         shift_n = DecodeImmShiftARM(opcode, shift_t);
8683 
8684         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8685         if (Rd == 15 && setflags)
8686             return EmulateSUBSPcLrEtc (opcode, encoding);
8687         break;
8688     default:
8689         return false;
8690     }
8691     // Read the register value from register Rn.
8692     uint32_t val1 = ReadCoreReg(Rn, &success);
8693     if (!success)
8694         return false;
8695 
8696     // Read the register value from register Rm.
8697     uint32_t val2 = ReadCoreReg(Rm, &success);
8698     if (!success)
8699         return false;
8700 
8701     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8702     if (!success)
8703         return false;
8704     AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
8705 
8706     EmulateInstruction::Context context;
8707     context.type = EmulateInstruction::eContextImmediate;
8708     context.SetNoArgs();
8709     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8710         return false;
8711 
8712     return true;
8713 }
8714 
8715 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from
8716 // an immediate value, and writes the result to the destination register. It can optionally update the condition
8717 // flags based on the result.
8718 bool
8719 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding)
8720 {
8721 #if 0
8722     // ARM pseudo code...
8723     if ConditionPassed() then
8724         EncodingSpecificOperations();
8725         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
8726         if d == 15 then
8727             ALUWritePC(result); // setflags is always FALSE here
8728         else
8729             R[d] = result;
8730             if setflags then
8731                 APSR.N = result<31>;
8732                 APSR.Z = IsZeroBit(result);
8733                 APSR.C = carry;
8734                 APSR.V = overflow;
8735 #endif
8736 
8737     bool success = false;
8738 
8739     uint32_t Rd; // the destination register
8740     uint32_t Rn; // the first operand
8741     bool setflags;
8742     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8743     switch (encoding) {
8744     case eEncodingA1:
8745         Rd = Bits32(opcode, 15, 12);
8746         Rn = Bits32(opcode, 19, 16);
8747         setflags = BitIsSet(opcode, 20);
8748         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8749 
8750         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8751         if (Rd == 15 && setflags)
8752             return EmulateSUBSPcLrEtc  (opcode, encoding);
8753         break;
8754     default:
8755         return false;
8756     }
8757     // Read the register value from the operand register Rn.
8758     uint32_t reg_val = ReadCoreReg(Rn, &success);
8759     if (!success)
8760         return false;
8761 
8762     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
8763 
8764     EmulateInstruction::Context context;
8765     context.type = EmulateInstruction::eContextImmediate;
8766     context.SetNoArgs ();
8767 
8768     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8769         return false;
8770 
8771     return true;
8772 }
8773 
8774 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an
8775 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the
8776 // condition flags based on the result.
8777 bool
8778 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding)
8779 {
8780 #if 0
8781     // ARM pseudo code...
8782     if ConditionPassed() then
8783         EncodingSpecificOperations();
8784         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8785         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
8786         if d == 15 then
8787             ALUWritePC(result); // setflags is always FALSE here
8788         else
8789             R[d] = result;
8790             if setflags then
8791                 APSR.N = result<31>;
8792                 APSR.Z = IsZeroBit(result);
8793                 APSR.C = carry;
8794                 APSR.V = overflow;
8795 #endif
8796 
8797     bool success = false;
8798 
8799     uint32_t Rd; // the destination register
8800     uint32_t Rn; // the first operand
8801     uint32_t Rm; // the second operand
8802     bool setflags;
8803     ARM_ShifterType shift_t;
8804     uint32_t shift_n; // the shift applied to the value read from Rm
8805     switch (encoding) {
8806     case eEncodingA1:
8807         Rd = Bits32(opcode, 15, 12);
8808         Rn = Bits32(opcode, 19, 16);
8809         Rm = Bits32(opcode, 3, 0);
8810         setflags = BitIsSet(opcode, 20);
8811         shift_n = DecodeImmShiftARM(opcode, shift_t);
8812 
8813         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8814         if (Rd == 15 && setflags)
8815             return EmulateSUBSPcLrEtc (opcode, encoding);
8816         break;
8817     default:
8818         return false;
8819     }
8820     // Read the register value from register Rn.
8821     uint32_t val1 = ReadCoreReg(Rn, &success);
8822     if (!success)
8823         return false;
8824 
8825     // Read the register value from register Rm.
8826     uint32_t val2 = ReadCoreReg(Rm, &success);
8827     if (!success)
8828         return false;
8829 
8830     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8831     if (!success)
8832         return false;
8833     AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
8834 
8835     EmulateInstruction::Context context;
8836     context.type = EmulateInstruction::eContextImmediate;
8837     context.SetNoArgs();
8838     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8839         return false;
8840 
8841     return true;
8842 }
8843 
8844 // Subtract with Carry (immediate) subtracts an immediate value and the value of
8845 // NOT (Carry flag) from a register value, and writes the result to the destination register.
8846 // It can optionally update the condition flags based on the result.
8847 bool
8848 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding)
8849 {
8850 #if 0
8851     // ARM pseudo code...
8852     if ConditionPassed() then
8853         EncodingSpecificOperations();
8854         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
8855         if d == 15 then         // Can only occur for ARM encoding
8856             ALUWritePC(result); // setflags is always FALSE here
8857         else
8858             R[d] = result;
8859             if setflags then
8860                 APSR.N = result<31>;
8861                 APSR.Z = IsZeroBit(result);
8862                 APSR.C = carry;
8863                 APSR.V = overflow;
8864 #endif
8865 
8866     bool success = false;
8867 
8868     uint32_t Rd; // the destination register
8869     uint32_t Rn; // the first operand
8870     bool setflags;
8871     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8872     switch (encoding) {
8873     case eEncodingT1:
8874         Rd = Bits32(opcode, 11, 8);
8875         Rn = Bits32(opcode, 19, 16);
8876         setflags = BitIsSet(opcode, 20);
8877         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8878         if (BadReg(Rd) || BadReg(Rn))
8879             return false;
8880         break;
8881     case eEncodingA1:
8882         Rd = Bits32(opcode, 15, 12);
8883         Rn = Bits32(opcode, 19, 16);
8884         setflags = BitIsSet(opcode, 20);
8885         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8886 
8887         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8888         if (Rd == 15 && setflags)
8889             return EmulateSUBSPcLrEtc (opcode, encoding);
8890         break;
8891     default:
8892         return false;
8893     }
8894     // Read the register value from the operand register Rn.
8895     uint32_t reg_val = ReadCoreReg(Rn, &success);
8896     if (!success)
8897         return false;
8898 
8899     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
8900 
8901     EmulateInstruction::Context context;
8902     context.type = EmulateInstruction::eContextImmediate;
8903     context.SetNoArgs ();
8904 
8905     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8906         return false;
8907 
8908     return true;
8909 }
8910 
8911 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of
8912 // NOT (Carry flag) from a register value, and writes the result to the destination register.
8913 // It can optionally update the condition flags based on the result.
8914 bool
8915 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding)
8916 {
8917 #if 0
8918     // ARM pseudo code...
8919     if ConditionPassed() then
8920         EncodingSpecificOperations();
8921         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8922         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
8923         if d == 15 then         // Can only occur for ARM encoding
8924             ALUWritePC(result); // setflags is always FALSE here
8925         else
8926             R[d] = result;
8927             if setflags then
8928                 APSR.N = result<31>;
8929                 APSR.Z = IsZeroBit(result);
8930                 APSR.C = carry;
8931                 APSR.V = overflow;
8932 #endif
8933 
8934     bool success = false;
8935 
8936     uint32_t Rd; // the destination register
8937     uint32_t Rn; // the first operand
8938     uint32_t Rm; // the second operand
8939     bool setflags;
8940     ARM_ShifterType shift_t;
8941     uint32_t shift_n; // the shift applied to the value read from Rm
8942     switch (encoding) {
8943     case eEncodingT1:
8944         Rd = Rn = Bits32(opcode, 2, 0);
8945         Rm = Bits32(opcode, 5, 3);
8946         setflags = !InITBlock();
8947         shift_t = SRType_LSL;
8948         shift_n = 0;
8949         break;
8950     case eEncodingT2:
8951         Rd = Bits32(opcode, 11, 8);
8952         Rn = Bits32(opcode, 19, 16);
8953         Rm = Bits32(opcode, 3, 0);
8954         setflags = BitIsSet(opcode, 20);
8955         shift_n = DecodeImmShiftThumb(opcode, shift_t);
8956         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8957             return false;
8958         break;
8959     case eEncodingA1:
8960         Rd = Bits32(opcode, 15, 12);
8961         Rn = Bits32(opcode, 19, 16);
8962         Rm = Bits32(opcode, 3, 0);
8963         setflags = BitIsSet(opcode, 20);
8964         shift_n = DecodeImmShiftARM(opcode, shift_t);
8965 
8966         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8967         if (Rd == 15 && setflags)
8968             return EmulateSUBSPcLrEtc (opcode, encoding);
8969         break;
8970     default:
8971         return false;
8972     }
8973     // Read the register value from register Rn.
8974     uint32_t val1 = ReadCoreReg(Rn, &success);
8975     if (!success)
8976         return false;
8977 
8978     // Read the register value from register Rm.
8979     uint32_t val2 = ReadCoreReg(Rm, &success);
8980     if (!success)
8981         return false;
8982 
8983     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8984     if (!success)
8985         return false;
8986     AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
8987 
8988     EmulateInstruction::Context context;
8989     context.type = EmulateInstruction::eContextImmediate;
8990     context.SetNoArgs();
8991     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8992         return false;
8993 
8994     return true;
8995 }
8996 
8997 // This instruction subtracts an immediate value from a register value, and writes the result
8998 // to the destination register.  It can optionally update the condition flags based on the result.
8999 bool
9000 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding)
9001 {
9002 #if 0
9003     // ARM pseudo code...
9004     if ConditionPassed() then
9005         EncodingSpecificOperations();
9006         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9007         R[d] = result;
9008         if setflags then
9009             APSR.N = result<31>;
9010             APSR.Z = IsZeroBit(result);
9011             APSR.C = carry;
9012             APSR.V = overflow;
9013 #endif
9014 
9015     bool success = false;
9016 
9017     uint32_t Rd; // the destination register
9018     uint32_t Rn; // the first operand
9019     bool setflags;
9020     uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9021     switch (encoding) {
9022     case eEncodingT1:
9023         Rd = Bits32(opcode, 2, 0);
9024         Rn = Bits32(opcode, 5, 3);
9025         setflags = !InITBlock();
9026         imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9027         break;
9028     case eEncodingT2:
9029         Rd = Rn = Bits32(opcode, 10, 8);
9030         setflags = !InITBlock();
9031         imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9032         break;
9033     case eEncodingT3:
9034         Rd = Bits32(opcode, 11, 8);
9035         Rn = Bits32(opcode, 19, 16);
9036         setflags = BitIsSet(opcode, 20);
9037         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9038 
9039         // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9040         if (Rd == 15 && setflags)
9041             return EmulateCMPImm (opcode, eEncodingT2);
9042 
9043         // if Rn == '1101' then SEE SUB (SP minus immediate);
9044         if (Rn == 13)
9045             return EmulateSUBSPImm (opcode, eEncodingT2);
9046 
9047         // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9048         if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9049             return false;
9050         break;
9051     case eEncodingT4:
9052         Rd = Bits32(opcode, 11, 8);
9053         Rn = Bits32(opcode, 19, 16);
9054         setflags = BitIsSet(opcode, 20);
9055         imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9056 
9057         // if Rn == '1111' then SEE ADR;
9058         if (Rn == 15)
9059             return EmulateADR (opcode, eEncodingT2);
9060 
9061         // if Rn == '1101' then SEE SUB (SP minus immediate);
9062         if (Rn == 13)
9063             return EmulateSUBSPImm (opcode, eEncodingT3);
9064 
9065         if (BadReg(Rd))
9066             return false;
9067         break;
9068     default:
9069         return false;
9070     }
9071     // Read the register value from the operand register Rn.
9072     uint32_t reg_val = ReadCoreReg(Rn, &success);
9073     if (!success)
9074         return false;
9075 
9076     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9077 
9078     EmulateInstruction::Context context;
9079     context.type = EmulateInstruction::eContextImmediate;
9080     context.SetNoArgs ();
9081 
9082     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9083         return false;
9084 
9085     return true;
9086 }
9087 
9088 // This instruction subtracts an immediate value from a register value, and writes the result
9089 // to the destination register.  It can optionally update the condition flags based on the result.
9090 bool
9091 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9092 {
9093 #if 0
9094     // ARM pseudo code...
9095     if ConditionPassed() then
9096         EncodingSpecificOperations();
9097         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9098         if d == 15 then
9099             ALUWritePC(result); // setflags is always FALSE here
9100         else
9101             R[d] = result;
9102             if setflags then
9103                 APSR.N = result<31>;
9104                 APSR.Z = IsZeroBit(result);
9105                 APSR.C = carry;
9106                 APSR.V = overflow;
9107 #endif
9108 
9109     bool success = false;
9110 
9111     uint32_t Rd; // the destination register
9112     uint32_t Rn; // the first operand
9113     bool setflags;
9114     uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9115     switch (encoding) {
9116     case eEncodingA1:
9117         Rd = Bits32(opcode, 15, 12);
9118         Rn = Bits32(opcode, 19, 16);
9119         setflags = BitIsSet(opcode, 20);
9120         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9121 
9122         // if Rn == '1111' && S == '0' then SEE ADR;
9123         if (Rn == 15 && !setflags)
9124             return EmulateADR (opcode, eEncodingA2);
9125 
9126         // if Rn == '1101' then SEE SUB (SP minus immediate);
9127         if (Rn == 13)
9128             return EmulateSUBSPImm (opcode, eEncodingA1);
9129 
9130         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9131         if (Rd == 15 && setflags)
9132             return EmulateSUBSPcLrEtc (opcode, encoding);
9133         break;
9134     default:
9135         return false;
9136     }
9137     // Read the register value from the operand register Rn.
9138     uint32_t reg_val = ReadCoreReg(Rn, &success);
9139     if (!success)
9140         return false;
9141 
9142     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9143 
9144     EmulateInstruction::Context context;
9145     context.type = EmulateInstruction::eContextImmediate;
9146     context.SetNoArgs ();
9147 
9148     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9149         return false;
9150 
9151     return true;
9152 }
9153 
9154 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an
9155 // immediate value.  It updates the condition flags based on the result, and discards the result.
9156 bool
9157 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding)
9158 {
9159 #if 0
9160     // ARM pseudo code...
9161     if ConditionPassed() then
9162         EncodingSpecificOperations();
9163         result = R[n] EOR imm32;
9164         APSR.N = result<31>;
9165         APSR.Z = IsZeroBit(result);
9166         APSR.C = carry;
9167         // APSR.V unchanged
9168 #endif
9169 
9170     bool success = false;
9171 
9172     if (ConditionPassed(opcode))
9173     {
9174         uint32_t Rn;
9175         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9176         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9177         switch (encoding)
9178         {
9179         case eEncodingT1:
9180             Rn = Bits32(opcode, 19, 16);
9181             imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9182             if (BadReg(Rn))
9183                 return false;
9184             break;
9185         case eEncodingA1:
9186             Rn = Bits32(opcode, 19, 16);
9187             imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9188             break;
9189         default:
9190             return false;
9191         }
9192 
9193         // Read the first operand.
9194         uint32_t val1 = ReadCoreReg(Rn, &success);
9195         if (!success)
9196             return false;
9197 
9198         uint32_t result = val1 ^ imm32;
9199 
9200         EmulateInstruction::Context context;
9201         context.type = EmulateInstruction::eContextImmediate;
9202         context.SetNoArgs ();
9203 
9204         if (!WriteFlags(context, result, carry))
9205             return false;
9206     }
9207     return true;
9208 }
9209 
9210 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an
9211 // optionally-shifted register value.  It updates the condition flags based on the result, and discards
9212 // the result.
9213 bool
9214 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding)
9215 {
9216 #if 0
9217     // ARM pseudo code...
9218     if ConditionPassed() then
9219         EncodingSpecificOperations();
9220         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9221         result = R[n] EOR shifted;
9222         APSR.N = result<31>;
9223         APSR.Z = IsZeroBit(result);
9224         APSR.C = carry;
9225         // APSR.V unchanged
9226 #endif
9227 
9228     bool success = false;
9229 
9230     if (ConditionPassed(opcode))
9231     {
9232         uint32_t Rn, Rm;
9233         ARM_ShifterType shift_t;
9234         uint32_t shift_n; // the shift applied to the value read from Rm
9235         uint32_t carry;
9236         switch (encoding)
9237         {
9238         case eEncodingT1:
9239             Rn = Bits32(opcode, 19, 16);
9240             Rm = Bits32(opcode, 3, 0);
9241             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9242             if (BadReg(Rn) || BadReg(Rm))
9243                 return false;
9244             break;
9245         case eEncodingA1:
9246             Rn = Bits32(opcode, 19, 16);
9247             Rm = Bits32(opcode, 3, 0);
9248             shift_n = DecodeImmShiftARM(opcode, shift_t);
9249             break;
9250         default:
9251             return false;
9252         }
9253 
9254         // Read the first operand.
9255         uint32_t val1 = ReadCoreReg(Rn, &success);
9256         if (!success)
9257             return false;
9258 
9259         // Read the second operand.
9260         uint32_t val2 = ReadCoreReg(Rm, &success);
9261         if (!success)
9262             return false;
9263 
9264         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9265         if (!success)
9266             return false;
9267         uint32_t result = val1 ^ shifted;
9268 
9269         EmulateInstruction::Context context;
9270         context.type = EmulateInstruction::eContextImmediate;
9271         context.SetNoArgs ();
9272 
9273         if (!WriteFlags(context, result, carry))
9274             return false;
9275     }
9276     return true;
9277 }
9278 
9279 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value.
9280 // It updates the condition flags based on the result, and discards the result.
9281 bool
9282 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding)
9283 {
9284 #if 0
9285     // ARM pseudo code...
9286     if ConditionPassed() then
9287         EncodingSpecificOperations();
9288         result = R[n] AND imm32;
9289         APSR.N = result<31>;
9290         APSR.Z = IsZeroBit(result);
9291         APSR.C = carry;
9292         // APSR.V unchanged
9293 #endif
9294 
9295     bool success = false;
9296 
9297     if (ConditionPassed(opcode))
9298     {
9299         uint32_t Rn;
9300         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9301         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9302         switch (encoding)
9303         {
9304         case eEncodingT1:
9305             Rn = Bits32(opcode, 19, 16);
9306             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9307             if (BadReg(Rn))
9308                 return false;
9309             break;
9310         case eEncodingA1:
9311             Rn = Bits32(opcode, 19, 16);
9312             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9313             break;
9314         default:
9315             return false;
9316         }
9317 
9318         // Read the first operand.
9319         uint32_t val1 = ReadCoreReg(Rn, &success);
9320         if (!success)
9321             return false;
9322 
9323         uint32_t result = val1 & imm32;
9324 
9325         EmulateInstruction::Context context;
9326         context.type = EmulateInstruction::eContextImmediate;
9327         context.SetNoArgs ();
9328 
9329         if (!WriteFlags(context, result, carry))
9330             return false;
9331     }
9332     return true;
9333 }
9334 
9335 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value.
9336 // It updates the condition flags based on the result, and discards the result.
9337 bool
9338 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding)
9339 {
9340 #if 0
9341     // ARM pseudo code...
9342     if ConditionPassed() then
9343         EncodingSpecificOperations();
9344         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9345         result = R[n] AND shifted;
9346         APSR.N = result<31>;
9347         APSR.Z = IsZeroBit(result);
9348         APSR.C = carry;
9349         // APSR.V unchanged
9350 #endif
9351 
9352     bool success = false;
9353 
9354     if (ConditionPassed(opcode))
9355     {
9356         uint32_t Rn, Rm;
9357         ARM_ShifterType shift_t;
9358         uint32_t shift_n; // the shift applied to the value read from Rm
9359         uint32_t carry;
9360         switch (encoding)
9361         {
9362         case eEncodingT1:
9363             Rn = Bits32(opcode, 2, 0);
9364             Rm = Bits32(opcode, 5, 3);
9365             shift_t = SRType_LSL;
9366             shift_n = 0;
9367             break;
9368         case eEncodingT2:
9369             Rn = Bits32(opcode, 19, 16);
9370             Rm = Bits32(opcode, 3, 0);
9371             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9372             if (BadReg(Rn) || BadReg(Rm))
9373                 return false;
9374             break;
9375         case eEncodingA1:
9376             Rn = Bits32(opcode, 19, 16);
9377             Rm = Bits32(opcode, 3, 0);
9378             shift_n = DecodeImmShiftARM(opcode, shift_t);
9379             break;
9380         default:
9381             return false;
9382         }
9383 
9384         // Read the first operand.
9385         uint32_t val1 = ReadCoreReg(Rn, &success);
9386         if (!success)
9387             return false;
9388 
9389         // Read the second operand.
9390         uint32_t val2 = ReadCoreReg(Rm, &success);
9391         if (!success)
9392             return false;
9393 
9394         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9395         if (!success)
9396             return false;
9397         uint32_t result = val1 & shifted;
9398 
9399         EmulateInstruction::Context context;
9400         context.type = EmulateInstruction::eContextImmediate;
9401         context.SetNoArgs ();
9402 
9403         if (!WriteFlags(context, result, carry))
9404             return false;
9405     }
9406     return true;
9407 }
9408 
9409 // A8.6.216 SUB (SP minus register)
9410 bool
9411 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding)
9412 {
9413 #if 0
9414     if ConditionPassed() then
9415         EncodingSpecificOperations();
9416         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9417         (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9418         if d == 15 then // Can only occur for ARM encoding
9419             ALUWritePC(result); // setflags is always FALSE here
9420         else
9421             R[d] = result;
9422             if setflags then
9423                 APSR.N = result<31>;
9424                 APSR.Z = IsZeroBit(result);
9425                 APSR.C = carry;
9426                 APSR.V = overflow;
9427 #endif
9428 
9429     bool success = false;
9430 
9431     if (ConditionPassed(opcode))
9432     {
9433         uint32_t d;
9434         uint32_t m;
9435         bool setflags;
9436         ARM_ShifterType shift_t;
9437         uint32_t shift_n;
9438 
9439         switch (encoding)
9440         {
9441             case eEncodingT1:
9442                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9443                 d = Bits32 (opcode, 11, 8);
9444                 m = Bits32 (opcode, 3, 0);
9445                 setflags = BitIsSet (opcode, 20);
9446 
9447                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9448                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9449 
9450                 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE;
9451                 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
9452                     return false;
9453 
9454                 // if d == 15 || BadReg(m) then UNPREDICTABLE;
9455                 if ((d == 15) || BadReg (m))
9456                     return false;
9457                 break;
9458 
9459             case eEncodingA1:
9460                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9461                 d = Bits32 (opcode, 15, 12);
9462                 m = Bits32 (opcode, 3, 0);
9463                 setflags = BitIsSet (opcode, 20);
9464 
9465                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9466                 if (d == 15 && setflags)
9467                     EmulateSUBSPcLrEtc (opcode, encoding);
9468 
9469                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9470                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9471                 break;
9472 
9473             default:
9474                 return false;
9475         }
9476 
9477         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9478         uint32_t Rm = ReadCoreReg (m, &success);
9479         if (!success)
9480             return false;
9481 
9482         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9483         if (!success)
9484             return false;
9485 
9486         // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9487         uint32_t sp_val = ReadCoreReg (SP_REG, &success);
9488         if (!success)
9489             return false;
9490 
9491         AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1);
9492 
9493         EmulateInstruction::Context context;
9494         context.type = eContextArithmetic;
9495         RegisterInfo sp_reg;
9496         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
9497         RegisterInfo dwarf_reg;
9498         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
9499         context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
9500 
9501         if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9502             return false;
9503     }
9504     return true;
9505 }
9506 
9507 
9508 // A8.6.7 ADD (register-shifted register)
9509 bool
9510 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding)
9511 {
9512 #if 0
9513     if ConditionPassed() then
9514         EncodingSpecificOperations();
9515         shift_n = UInt(R[s]<7:0>);
9516         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9517         (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9518         R[d] = result;
9519         if setflags then
9520             APSR.N = result<31>;
9521             APSR.Z = IsZeroBit(result);
9522             APSR.C = carry;
9523             APSR.V = overflow;
9524 #endif
9525 
9526     bool success = false;
9527 
9528     if (ConditionPassed(opcode))
9529     {
9530         uint32_t d;
9531         uint32_t n;
9532         uint32_t m;
9533         uint32_t s;
9534         bool setflags;
9535         ARM_ShifterType shift_t;
9536 
9537         switch (encoding)
9538         {
9539             case eEncodingA1:
9540                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
9541                 d = Bits32 (opcode, 15, 12);
9542                 n = Bits32 (opcode, 19, 16);
9543                 m = Bits32 (opcode, 3, 0);
9544                 s = Bits32 (opcode, 11, 8);
9545 
9546                 // setflags = (S == �1�); shift_t = DecodeRegShift(type);
9547                 setflags = BitIsSet (opcode, 20);
9548                 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5));
9549 
9550                 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
9551                 if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
9552                     return false;
9553                 break;
9554 
9555             default:
9556                 return false;
9557         }
9558 
9559         // shift_n = UInt(R[s]<7:0>);
9560         uint32_t Rs = ReadCoreReg (s, &success);
9561         if (!success)
9562             return false;
9563 
9564         uint32_t shift_n = Bits32 (Rs, 7, 0);
9565 
9566         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9567         uint32_t Rm = ReadCoreReg (m, &success);
9568         if (!success)
9569             return false;
9570 
9571         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9572         if (!success)
9573             return false;
9574 
9575         // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9576         uint32_t Rn = ReadCoreReg (n, &success);
9577         if (!success)
9578             return false;
9579 
9580         AddWithCarryResult res = AddWithCarry (Rn, shifted, 0);
9581 
9582         // R[d] = result;
9583         EmulateInstruction::Context context;
9584         context.type = eContextArithmetic;
9585         RegisterInfo reg_n;
9586         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9587         RegisterInfo reg_m;
9588         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9589 
9590         context.SetRegisterRegisterOperands (reg_n, reg_m);
9591 
9592         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result))
9593             return false;
9594 
9595         // if setflags then
9596             // APSR.N = result<31>;
9597             // APSR.Z = IsZeroBit(result);
9598             // APSR.C = carry;
9599             // APSR.V = overflow;
9600         if (setflags)
9601             return WriteFlags (context, res.result, res.carry_out, res.overflow);
9602     }
9603     return true;
9604 }
9605 
9606 // A8.6.213 SUB (register)
9607 bool
9608 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding)
9609 {
9610 #if 0
9611     if ConditionPassed() then
9612         EncodingSpecificOperations();
9613         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9614         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9615         if d == 15 then // Can only occur for ARM encoding
9616             ALUWritePC(result); // setflags is always FALSE here
9617         else
9618             R[d] = result;
9619             if setflags then
9620                 APSR.N = result<31>;
9621                 APSR.Z = IsZeroBit(result);
9622                 APSR.C = carry;
9623                 APSR.V = overflow;
9624 #endif
9625 
9626     bool success = false;
9627 
9628     if (ConditionPassed(opcode))
9629     {
9630         uint32_t d;
9631         uint32_t n;
9632         uint32_t m;
9633         bool setflags;
9634         ARM_ShifterType shift_t;
9635         uint32_t shift_n;
9636 
9637         switch (encoding)
9638         {
9639             case eEncodingT1:
9640                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
9641                 d = Bits32 (opcode, 2, 0);
9642                 n = Bits32 (opcode, 5, 3);
9643                 m = Bits32 (opcode, 8, 6);
9644                 setflags = !InITBlock();
9645 
9646                 // (shift_t, shift_n) = (SRType_LSL, 0);
9647                 shift_t = SRType_LSL;
9648                 shift_n = 0;
9649 
9650                 break;
9651 
9652             case eEncodingT2:
9653                 // if Rd == �1111� && S == �1� then SEE CMP (register);
9654                 // if Rn == �1101� then SEE SUB (SP minus register);
9655                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9656                 d = Bits32 (opcode, 11, 8);
9657                 n = Bits32 (opcode, 19, 16);
9658                 m = Bits32 (opcode, 3, 0);
9659                 setflags = BitIsSet (opcode, 20);
9660 
9661                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9662                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9663 
9664                 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE;
9665                 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m))
9666                     return false;
9667 
9668                 break;
9669 
9670             case eEncodingA1:
9671                 // if Rn == �1101� then SEE SUB (SP minus register);
9672                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9673                 d = Bits32 (opcode, 15, 12);
9674                 n = Bits32 (opcode, 19, 16);
9675                 m = Bits32 (opcode, 3, 0);
9676                 setflags = BitIsSet (opcode, 20);
9677 
9678                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9679                 if ((d == 15) && setflags)
9680                     EmulateSUBSPcLrEtc (opcode, encoding);
9681 
9682                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9683                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9684 
9685                 break;
9686 
9687             default:
9688                 return false;
9689         }
9690 
9691         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9692         uint32_t Rm = ReadCoreReg (m, &success);
9693         if (!success)
9694             return false;
9695 
9696         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9697         if (!success)
9698             return false;
9699 
9700         // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9701         uint32_t Rn = ReadCoreReg (n, &success);
9702         if (!success)
9703             return false;
9704 
9705         AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1);
9706 
9707         // if d == 15 then // Can only occur for ARM encoding
9708             // ALUWritePC(result); // setflags is always FALSE here
9709         // else
9710             // R[d] = result;
9711             // if setflags then
9712                 // APSR.N = result<31>;
9713                 // APSR.Z = IsZeroBit(result);
9714                 // APSR.C = carry;
9715                 // APSR.V = overflow;
9716 
9717         EmulateInstruction::Context context;
9718         context.type = eContextArithmetic;
9719         RegisterInfo reg_n;
9720         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9721         RegisterInfo reg_m;
9722         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9723         context.SetRegisterRegisterOperands (reg_n, reg_m);
9724 
9725         if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9726             return false;
9727     }
9728     return true;
9729 }
9730 
9731 // A8.6.202 STREX
9732 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a
9733 // word from a register to memory if the executing processor has exclusive access to the memory addressed.
9734 bool
9735 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding)
9736 {
9737 #if 0
9738     if ConditionPassed() then
9739         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9740         address = R[n] + imm32;
9741         if ExclusiveMonitorsPass(address,4) then
9742             MemA[address,4] = R[t];
9743             R[d] = 0;
9744         else
9745             R[d] = 1;
9746 #endif
9747 
9748     bool success = false;
9749 
9750     if (ConditionPassed(opcode))
9751     {
9752         uint32_t d;
9753         uint32_t t;
9754         uint32_t n;
9755         uint32_t imm32;
9756         const uint32_t addr_byte_size = GetAddressByteSize();
9757 
9758         switch (encoding)
9759         {
9760             case eEncodingT1:
9761                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
9762                 d = Bits32 (opcode, 11, 8);
9763                 t = Bits32 (opcode, 15, 12);
9764                 n = Bits32 (opcode, 19, 16);
9765                 imm32 = Bits32 (opcode, 7, 0) << 2;
9766 
9767                 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
9768                 if (BadReg (d) || BadReg (t) || (n == 15))
9769                   return false;
9770 
9771                 // if d == n || d == t then UNPREDICTABLE;
9772                 if ((d == n) || (d == t))
9773                   return false;
9774 
9775                 break;
9776 
9777             case eEncodingA1:
9778                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset
9779                 d = Bits32 (opcode, 15, 12);
9780                 t = Bits32 (opcode, 3, 0);
9781                 n = Bits32 (opcode, 19, 16);
9782                 imm32 = 0;
9783 
9784                 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
9785                 if ((d == 15) || (t == 15) || (n == 15))
9786                     return false;
9787 
9788                 // if d == n || d == t then UNPREDICTABLE;
9789                 if ((d == n) || (d == t))
9790                     return false;
9791 
9792                 break;
9793 
9794             default:
9795                 return false;
9796         }
9797 
9798         // address = R[n] + imm32;
9799         uint32_t Rn = ReadCoreReg (n, &success);
9800         if (!success)
9801             return false;
9802 
9803         addr_t address = Rn + imm32;
9804 
9805         RegisterInfo base_reg;
9806         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9807         RegisterInfo data_reg;
9808         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9809         EmulateInstruction::Context context;
9810         context.type = eContextRegisterStore;
9811         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32);
9812 
9813         // if ExclusiveMonitorsPass(address,4) then
9814         // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this
9815         //                                                         always return true.
9816         if (true)
9817         {
9818             // MemA[address,4] = R[t];
9819             uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
9820             if (!success)
9821                 return false;
9822 
9823             if (!MemAWrite (context, address, Rt, addr_byte_size))
9824                 return false;
9825 
9826             // R[d] = 0;
9827             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0))
9828                 return false;
9829         }
9830         else
9831         {
9832             // R[d] = 1;
9833             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
9834                 return false;
9835         }
9836     }
9837     return true;
9838 }
9839 
9840 // A8.6.197 STRB (immediate, ARM)
9841 bool
9842 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9843 {
9844 #if 0
9845     if ConditionPassed() then
9846         EncodingSpecificOperations();
9847         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9848         address = if index then offset_addr else R[n];
9849         MemU[address,1] = R[t]<7:0>;
9850         if wback then R[n] = offset_addr;
9851 #endif
9852 
9853     bool success = false;
9854 
9855     if (ConditionPassed(opcode))
9856     {
9857         uint32_t t;
9858         uint32_t n;
9859         uint32_t imm32;
9860         bool index;
9861         bool add;
9862         bool wback;
9863 
9864         switch (encoding)
9865         {
9866             case eEncodingA1:
9867                 // if P == �0� && W == �1� then SEE STRBT;
9868                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9869                 t = Bits32 (opcode, 15, 12);
9870                 n = Bits32 (opcode, 19, 16);
9871                 imm32 = Bits32 (opcode, 11, 0);
9872 
9873                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9874                 index = BitIsSet (opcode, 24);
9875                 add = BitIsSet (opcode, 23);
9876                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9877 
9878                 // if t == 15 then UNPREDICTABLE;
9879                 if (t == 15)
9880                     return false;
9881 
9882                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9883                 if (wback && ((n == 15) || (n == t)))
9884                     return false;
9885 
9886                 break;
9887 
9888             default:
9889                 return false;
9890         }
9891 
9892         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9893         uint32_t Rn = ReadCoreReg (n, &success);
9894         if (!success)
9895             return false;
9896 
9897         addr_t offset_addr;
9898         if (add)
9899             offset_addr = Rn + imm32;
9900         else
9901             offset_addr = Rn - imm32;
9902 
9903         // address = if index then offset_addr else R[n];
9904         addr_t address;
9905         if (index)
9906             address = offset_addr;
9907         else
9908             address = Rn;
9909 
9910         // MemU[address,1] = R[t]<7:0>;
9911         uint32_t Rt = ReadCoreReg (t, &success);
9912         if (!success)
9913             return false;
9914 
9915         RegisterInfo base_reg;
9916         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9917         RegisterInfo data_reg;
9918         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9919         EmulateInstruction::Context context;
9920         context.type = eContextRegisterStore;
9921         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
9922 
9923         if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1))
9924             return false;
9925 
9926         // if wback then R[n] = offset_addr;
9927         if (wback)
9928         {
9929             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
9930                 return false;
9931         }
9932     }
9933     return true;
9934 }
9935 
9936 // A8.6.194 STR (immediate, ARM)
9937 bool
9938 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding)
9939 {
9940 #if 0
9941     if ConditionPassed() then
9942         EncodingSpecificOperations();
9943         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9944         address = if index then offset_addr else R[n];
9945         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
9946         if wback then R[n] = offset_addr;
9947 #endif
9948 
9949     bool success = false;
9950 
9951     if (ConditionPassed(opcode))
9952     {
9953         uint32_t t;
9954         uint32_t n;
9955         uint32_t imm32;
9956         bool index;
9957         bool add;
9958         bool wback;
9959 
9960         const uint32_t addr_byte_size = GetAddressByteSize();
9961 
9962         switch (encoding)
9963         {
9964             case eEncodingA1:
9965                 // if P == �0� && W == �1� then SEE STRT;
9966                 // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH;
9967                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9968                 t = Bits32 (opcode, 15, 12);
9969                 n = Bits32 (opcode, 19, 16);
9970                 imm32 = Bits32 (opcode, 11, 0);
9971 
9972                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9973                 index = BitIsSet (opcode, 24);
9974                 add = BitIsSet (opcode, 23);
9975                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9976 
9977                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9978                 if (wback && ((n == 15) || (n == t)))
9979                     return false;
9980 
9981                 break;
9982 
9983             default:
9984                 return false;
9985         }
9986 
9987         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9988         uint32_t Rn = ReadCoreReg (n, &success);
9989         if (!success)
9990             return false;
9991 
9992         addr_t offset_addr;
9993         if (add)
9994             offset_addr = Rn + imm32;
9995         else
9996             offset_addr = Rn - imm32;
9997 
9998         // address = if index then offset_addr else R[n];
9999         addr_t address;
10000         if (index)
10001             address = offset_addr;
10002         else
10003             address = Rn;
10004 
10005         RegisterInfo base_reg;
10006         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10007         RegisterInfo data_reg;
10008         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10009         EmulateInstruction::Context context;
10010         context.type = eContextRegisterStore;
10011         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10012 
10013         // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10014         uint32_t Rt = ReadCoreReg (t, &success);
10015         if (!success)
10016             return false;
10017 
10018         if (t == 15)
10019         {
10020             uint32_t pc_value = ReadCoreReg (PC_REG, &success);
10021             if (!success)
10022                 return false;
10023 
10024             if (!MemUWrite (context, address, pc_value, addr_byte_size))
10025                 return false;
10026         }
10027         else
10028         {
10029             if (!MemUWrite (context, address, Rt, addr_byte_size))
10030                   return false;
10031         }
10032 
10033         // if wback then R[n] = offset_addr;
10034         if (wback)
10035         {
10036             context.type = eContextAdjustBaseRegister;
10037             context.SetImmediate (offset_addr);
10038 
10039             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10040                 return false;
10041         }
10042     }
10043     return true;
10044 }
10045 
10046 // A8.6.66 LDRD (immediate)
10047 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two
10048 // words from memory, and writes them to two registers.  It can use offset, post-indexed, or pre-indexed addressing.
10049 bool
10050 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding)
10051 {
10052 #if 0
10053     if ConditionPassed() then
10054         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10055         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10056         address = if index then offset_addr else R[n];
10057         R[t] = MemA[address,4];
10058         R[t2] = MemA[address+4,4];
10059         if wback then R[n] = offset_addr;
10060 #endif
10061 
10062     bool success = false;
10063 
10064     if (ConditionPassed(opcode))
10065     {
10066         uint32_t t;
10067         uint32_t t2;
10068         uint32_t n;
10069         uint32_t imm32;
10070         bool index;
10071         bool add;
10072         bool wback;
10073 
10074         switch (encoding)
10075         {
10076             case eEncodingT1:
10077                 //if P == �0� && W == �0� then SEE �Related encodings�;
10078                 //if Rn == �1111� then SEE LDRD (literal);
10079                 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10080                 t = Bits32 (opcode, 15, 12);
10081                 t2 = Bits32 (opcode, 11, 8);
10082                 n = Bits32 (opcode, 19, 16);
10083                 imm32 = Bits32 (opcode, 7, 0) << 2;
10084 
10085                 //index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10086                 index = BitIsSet (opcode, 24);
10087                 add = BitIsSet (opcode, 23);
10088                 wback = BitIsSet (opcode, 21);
10089 
10090                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10091                 if (wback && ((n == t) || (n == t2)))
10092                     return false;
10093 
10094                 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10095                 if (BadReg (t) || BadReg (t2) || (t == t2))
10096                     return false;
10097 
10098                 break;
10099 
10100             case eEncodingA1:
10101                 //if Rn == �1111� then SEE LDRD (literal);
10102                 //if Rt<0> == �1� then UNPREDICTABLE;
10103                 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10104                 t = Bits32 (opcode, 15, 12);
10105                 if (BitIsSet (t, 0))
10106                     return false;
10107                 t2 = t + 1;
10108                 n = Bits32 (opcode, 19, 16);
10109                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10110 
10111                 //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10112                 index = BitIsSet (opcode, 24);
10113                 add = BitIsSet (opcode, 23);
10114                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10115 
10116                 //if P == �0� && W == �1� then UNPREDICTABLE;
10117                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10118                     return false;
10119 
10120                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10121                 if (wback && ((n == t) || (n == t2)))
10122                     return false;
10123 
10124                 //if t2 == 15 then UNPREDICTABLE;
10125                 if (t2 == 15)
10126                     return false;
10127 
10128                 break;
10129 
10130             default:
10131                 return false;
10132         }
10133 
10134         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10135         uint32_t Rn = ReadCoreReg (n, &success);
10136         if (!success)
10137             return false;
10138 
10139         addr_t offset_addr;
10140         if (add)
10141                   offset_addr = Rn + imm32;
10142         else
10143             offset_addr = Rn - imm32;
10144 
10145         //address = if index then offset_addr else R[n];
10146         addr_t address;
10147         if (index)
10148             address = offset_addr;
10149         else
10150             address = Rn;
10151 
10152         //R[t] = MemA[address,4];
10153         RegisterInfo base_reg;
10154         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10155 
10156         EmulateInstruction::Context context;
10157         context.type = eContextRegisterLoad;
10158         context.SetRegisterPlusOffset (base_reg, address - Rn);
10159 
10160         const uint32_t addr_byte_size = GetAddressByteSize();
10161         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10162         if (!success)
10163             return false;
10164 
10165         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10166             return false;
10167 
10168         //R[t2] = MemA[address+4,4];
10169 
10170         context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10171         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10172         if (!success)
10173             return false;
10174 
10175         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10176             return false;
10177 
10178         //if wback then R[n] = offset_addr;
10179         if (wback)
10180         {
10181             context.type = eContextAdjustBaseRegister;
10182             context.SetAddress (offset_addr);
10183 
10184             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10185                 return false;
10186         }
10187     }
10188     return true;
10189 }
10190 
10191 // A8.6.68 LDRD (register)
10192 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two
10193 // words from memory, and writes them to two registers.  It can use offset, post-indexed or pre-indexed addressing.
10194 bool
10195 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding)
10196 {
10197 #if 0
10198     if ConditionPassed() then
10199         EncodingSpecificOperations();
10200         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10201         address = if index then offset_addr else R[n];
10202         R[t] = MemA[address,4];
10203         R[t2] = MemA[address+4,4];
10204         if wback then R[n] = offset_addr;
10205 #endif
10206 
10207     bool success = false;
10208 
10209     if (ConditionPassed(opcode))
10210     {
10211         uint32_t t;
10212         uint32_t t2;
10213         uint32_t n;
10214         uint32_t m;
10215         bool index;
10216         bool add;
10217         bool wback;
10218 
10219         switch (encoding)
10220         {
10221             case eEncodingA1:
10222                 // if Rt<0> == �1� then UNPREDICTABLE;
10223                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10224                 t = Bits32 (opcode, 15, 12);
10225                 if (BitIsSet (t, 0))
10226                     return false;
10227                 t2 = t + 1;
10228                 n = Bits32 (opcode, 19, 16);
10229                 m = Bits32 (opcode, 3, 0);
10230 
10231                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10232                 index = BitIsSet (opcode, 24);
10233                 add = BitIsSet (opcode, 23);
10234                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10235 
10236                 // if P == �0� && W == �1� then UNPREDICTABLE;
10237                   if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10238                   return false;
10239 
10240                 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10241                   if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10242                   return false;
10243 
10244                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10245                   if (wback && ((n == 15) || (n == t) || (n == t2)))
10246                   return false;
10247 
10248                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10249                 if ((ArchVersion() < 6) && wback && (m == n))
10250                   return false;
10251                 break;
10252 
10253             default:
10254                 return false;
10255         }
10256 
10257         uint32_t Rn = ReadCoreReg (n, &success);
10258         if (!success)
10259             return false;
10260         RegisterInfo base_reg;
10261         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10262 
10263         uint32_t Rm = ReadCoreReg (m, &success);
10264         if (!success)
10265             return false;
10266         RegisterInfo offset_reg;
10267         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10268 
10269         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10270         addr_t offset_addr;
10271         if (add)
10272             offset_addr = Rn + Rm;
10273         else
10274             offset_addr = Rn - Rm;
10275 
10276         // address = if index then offset_addr else R[n];
10277         addr_t address;
10278         if (index)
10279             address = offset_addr;
10280         else
10281             address = Rn;
10282 
10283         EmulateInstruction::Context context;
10284         context.type = eContextRegisterLoad;
10285         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
10286 
10287         // R[t] = MemA[address,4];
10288         const uint32_t addr_byte_size = GetAddressByteSize();
10289         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10290         if (!success)
10291             return false;
10292 
10293         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10294             return false;
10295 
10296         // R[t2] = MemA[address+4,4];
10297 
10298         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10299         if (!success)
10300             return false;
10301 
10302         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10303             return false;
10304 
10305         // if wback then R[n] = offset_addr;
10306         if (wback)
10307         {
10308             context.type = eContextAdjustBaseRegister;
10309             context.SetAddress (offset_addr);
10310 
10311             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10312                 return false;
10313         }
10314     }
10315     return true;
10316 }
10317 
10318 // A8.6.200 STRD (immediate)
10319 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and
10320 // stores two words from two registers to memory.  It can use offset, post-indexed, or pre-indexed addressing.
10321 bool
10322 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding)
10323 {
10324 #if 0
10325     if ConditionPassed() then
10326         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10327         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10328         address = if index then offset_addr else R[n];
10329         MemA[address,4] = R[t];
10330         MemA[address+4,4] = R[t2];
10331         if wback then R[n] = offset_addr;
10332 #endif
10333 
10334     bool success = false;
10335 
10336     if (ConditionPassed(opcode))
10337     {
10338         uint32_t t;
10339         uint32_t t2;
10340         uint32_t n;
10341         uint32_t imm32;
10342         bool index;
10343         bool add;
10344         bool wback;
10345 
10346         switch (encoding)
10347         {
10348             case eEncodingT1:
10349                 // if P == �0� && W == �0� then SEE �Related encodings�;
10350                 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10351                 t = Bits32 (opcode, 15, 12);
10352                 t2 = Bits32 (opcode, 11, 8);
10353                 n = Bits32 (opcode, 19, 16);
10354                 imm32 = Bits32 (opcode, 7, 0) << 2;
10355 
10356                 // index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10357                 index = BitIsSet (opcode, 24);
10358                 add = BitIsSet (opcode, 23);
10359                 wback = BitIsSet (opcode, 21);
10360 
10361                 // if wback && (n == t || n == t2) then UNPREDICTABLE;
10362                 if (wback && ((n == t) || (n == t2)))
10363                     return false;
10364 
10365                 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10366                 if ((n == 15) || BadReg (t) || BadReg (t2))
10367                     return false;
10368 
10369                 break;
10370 
10371             case eEncodingA1:
10372                 // if Rt<0> == �1� then UNPREDICTABLE;
10373                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10374                 t = Bits32 (opcode, 15, 12);
10375                 if (BitIsSet (t, 0))
10376                     return false;
10377 
10378                 t2 = t + 1;
10379                 n = Bits32 (opcode, 19, 16);
10380                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10381 
10382                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10383                 index = BitIsSet (opcode, 24);
10384                 add = BitIsSet (opcode, 23);
10385                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10386 
10387                 // if P == �0� && W == �1� then UNPREDICTABLE;
10388                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10389                     return false;
10390 
10391                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10392                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10393                     return false;
10394 
10395                 // if t2 == 15 then UNPREDICTABLE;
10396                 if (t2 == 15)
10397                     return false;
10398 
10399                 break;
10400 
10401             default:
10402                 return false;
10403         }
10404 
10405         RegisterInfo base_reg;
10406         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10407 
10408         uint32_t Rn = ReadCoreReg (n, &success);
10409         if (!success)
10410             return false;
10411 
10412         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10413         addr_t offset_addr;
10414         if (add)
10415             offset_addr = Rn + imm32;
10416         else
10417             offset_addr = Rn - imm32;
10418 
10419         //address = if index then offset_addr else R[n];
10420         addr_t address;
10421         if (index)
10422             address = offset_addr;
10423         else
10424             address = Rn;
10425 
10426         //MemA[address,4] = R[t];
10427         RegisterInfo data_reg;
10428         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10429 
10430         uint32_t data = ReadCoreReg (t, &success);
10431         if (!success)
10432             return false;
10433 
10434         EmulateInstruction::Context context;
10435         context.type = eContextRegisterStore;
10436         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10437 
10438         const uint32_t addr_byte_size = GetAddressByteSize();
10439 
10440         if (!MemAWrite (context, address, data, addr_byte_size))
10441             return false;
10442 
10443         //MemA[address+4,4] = R[t2];
10444         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10445         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10446 
10447         data = ReadCoreReg (t2, &success);
10448         if (!success)
10449             return false;
10450 
10451         if (!MemAWrite (context, address + 4, data, addr_byte_size))
10452             return false;
10453 
10454         //if wback then R[n] = offset_addr;
10455         if (wback)
10456         {
10457             context.type = eContextAdjustBaseRegister;
10458             context.SetAddress (offset_addr);
10459 
10460             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10461                 return false;
10462         }
10463     }
10464     return true;
10465 }
10466 
10467 
10468 // A8.6.201 STRD (register)
10469 bool
10470 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding)
10471 {
10472 #if 0
10473     if ConditionPassed() then
10474         EncodingSpecificOperations();
10475         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10476         address = if index then offset_addr else R[n];
10477         MemA[address,4] = R[t];
10478         MemA[address+4,4] = R[t2];
10479         if wback then R[n] = offset_addr;
10480 #endif
10481 
10482     bool success = false;
10483 
10484     if (ConditionPassed(opcode))
10485     {
10486         uint32_t t;
10487         uint32_t t2;
10488         uint32_t n;
10489         uint32_t m;
10490         bool index;
10491         bool add;
10492         bool wback;
10493 
10494         switch (encoding)
10495         {
10496             case eEncodingA1:
10497                 // if Rt<0> == �1� then UNPREDICTABLE;
10498                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10499                 t = Bits32 (opcode, 15, 12);
10500                 if (BitIsSet (t, 0))
10501                    return false;
10502 
10503                 t2 = t+1;
10504                 n = Bits32 (opcode, 19, 16);
10505                 m = Bits32 (opcode, 3, 0);
10506 
10507                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10508                 index = BitIsSet (opcode, 24);
10509                 add = BitIsSet (opcode, 23);
10510                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10511 
10512                 // if P == �0� && W == �1� then UNPREDICTABLE;
10513                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10514                    return false;
10515 
10516                 // if t2 == 15 || m == 15 then UNPREDICTABLE;
10517                 if ((t2 == 15) || (m == 15))
10518                    return false;
10519 
10520                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10521                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10522                    return false;
10523 
10524                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10525                 if ((ArchVersion() < 6) && wback && (m == n))
10526                    return false;
10527 
10528                 break;
10529 
10530             default:
10531                 return false;
10532         }
10533 
10534         RegisterInfo base_reg;
10535         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10536         RegisterInfo offset_reg;
10537         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10538         RegisterInfo data_reg;
10539 
10540         uint32_t Rn = ReadCoreReg (n, &success);
10541         if (!success)
10542             return false;
10543 
10544         uint32_t Rm = ReadCoreReg (m, &success);
10545         if (!success)
10546             return false;
10547 
10548         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10549         addr_t offset_addr;
10550         if (add)
10551             offset_addr = Rn + Rm;
10552         else
10553             offset_addr = Rn - Rm;
10554 
10555         // address = if index then offset_addr else R[n];
10556         addr_t address;
10557         if (index)
10558             address = offset_addr;
10559         else
10560             address = Rn;
10561                           // MemA[address,4] = R[t];
10562         uint32_t Rt = ReadCoreReg (t, &success);
10563         if (!success)
10564             return false;
10565 
10566         EmulateInstruction::Context context;
10567         context.type = eContextRegisterStore;
10568         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10569         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10570 
10571         const uint32_t addr_byte_size = GetAddressByteSize();
10572 
10573         if (!MemAWrite (context, address, Rt, addr_byte_size))
10574             return false;
10575 
10576         // MemA[address+4,4] = R[t2];
10577         uint32_t Rt2 = ReadCoreReg (t2, &success);
10578         if (!success)
10579             return false;
10580 
10581         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10582 
10583         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10584 
10585         if (!MemAWrite (context, address + 4, Rt2, addr_byte_size))
10586             return false;
10587 
10588         // if wback then R[n] = offset_addr;
10589         if (wback)
10590         {
10591             context.type = eContextAdjustBaseRegister;
10592             context.SetAddress (offset_addr);
10593 
10594             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10595                 return false;
10596 
10597         }
10598     }
10599     return true;
10600 }
10601 
10602 // A8.6.319 VLDM
10603 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from
10604 // an ARM core register.
10605 bool
10606 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding)
10607 {
10608 #if 0
10609     if ConditionPassed() then
10610         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10611         address = if add then R[n] else R[n]-imm32;
10612         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10613         for r = 0 to regs-1
10614             if single_regs then
10615                 S[d+r] = MemA[address,4]; address = address+4;
10616             else
10617                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10618                 // Combine the word-aligned words in the correct order for current endianness.
10619                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10620 #endif
10621 
10622     bool success = false;
10623 
10624     if (ConditionPassed(opcode))
10625     {
10626         bool single_regs;
10627         bool add;
10628         bool wback;
10629         uint32_t d;
10630         uint32_t n;
10631         uint32_t imm32;
10632         uint32_t regs;
10633 
10634         switch (encoding)
10635         {
10636             case eEncodingT1:
10637             case eEncodingA1:
10638                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10639                 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10640                 // if P == �1� && W == �0� then SEE VLDR;
10641                 // if P == U && W == �1� then UNDEFINED;
10642                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10643                     return false;
10644 
10645                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10646                 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10647                 single_regs = false;
10648                 add = BitIsSet (opcode, 23);
10649                 wback = BitIsSet (opcode, 21);
10650 
10651                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10652                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10653                 n = Bits32 (opcode, 19, 16);
10654                 imm32 = Bits32 (opcode, 7, 0) << 2;
10655 
10656                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�.
10657                 regs = Bits32 (opcode, 7, 0) / 2;
10658 
10659                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10660                 if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
10661                     return false;
10662 
10663                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10664                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10665                     return false;
10666 
10667                 break;
10668 
10669             case eEncodingT2:
10670             case eEncodingA2:
10671                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10672                 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10673                 // if P == �1� && W == �0� then SEE VLDR;
10674                 // if P == U && W == �1� then UNDEFINED;
10675                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10676                     return false;
10677 
10678                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10679                 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10680                 single_regs = true;
10681                 add = BitIsSet (opcode, 23);
10682                 wback = BitIsSet (opcode, 21);
10683                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10684                 n = Bits32 (opcode, 19, 16);
10685 
10686                 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10687                 imm32 = Bits32 (opcode, 7, 0) << 2;
10688                 regs = Bits32 (opcode, 7, 0);
10689 
10690                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10691                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10692                     return false;
10693 
10694                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10695                 if ((regs == 0) || ((d + regs) > 32))
10696                     return false;
10697                 break;
10698 
10699             default:
10700                 return false;
10701         }
10702 
10703         RegisterInfo base_reg;
10704         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10705 
10706         uint32_t Rn = ReadCoreReg (n, &success);
10707         if (!success)
10708             return false;
10709 
10710         // address = if add then R[n] else R[n]-imm32;
10711         addr_t address;
10712         if (add)
10713             address = Rn;
10714         else
10715             address = Rn - imm32;
10716 
10717         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10718         EmulateInstruction::Context context;
10719 
10720         if (wback)
10721         {
10722             uint32_t value;
10723             if (add)
10724                 value = Rn + imm32;
10725             else
10726                 value = Rn - imm32;
10727 
10728             context.type = eContextAdjustBaseRegister;
10729             context.SetImmediateSigned (value - Rn);
10730             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10731                 return false;
10732 
10733         }
10734 
10735         const uint32_t addr_byte_size = GetAddressByteSize();
10736         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10737 
10738         context.type = eContextRegisterLoad;
10739 
10740         // for r = 0 to regs-1
10741         for (uint32_t r = 0; r < regs; ++r)
10742         {
10743             if (single_regs)
10744             {
10745                 // S[d+r] = MemA[address,4]; address = address+4;
10746                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10747 
10748                 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10749                 if (!success)
10750                     return false;
10751 
10752                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10753                     return false;
10754 
10755                 address = address + 4;
10756             }
10757             else
10758             {
10759                 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10760                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10761                 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10762                 if (!success)
10763                     return false;
10764 
10765                 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10766                 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10767                 if (!success)
10768                     return false;
10769 
10770                 address = address + 8;
10771                 // // Combine the word-aligned words in the correct order for current endianness.
10772                 // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10773                 uint64_t data;
10774                 if (GetByteOrder() == eByteOrderBig)
10775                 {
10776                     data = word1;
10777                     data = (data << 32) | word2;
10778                 }
10779                 else
10780                 {
10781                     data = word2;
10782                     data = (data << 32) | word1;
10783                 }
10784 
10785                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10786                     return false;
10787             }
10788         }
10789     }
10790     return true;
10791 }
10792 
10793 // A8.6.399 VSTM
10794 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an
10795 // ARM core register.
10796 bool
10797 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding)
10798 {
10799 #if 0
10800     if ConditionPassed() then
10801         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10802         address = if add then R[n] else R[n]-imm32;
10803         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10804         for r = 0 to regs-1
10805             if single_regs then
10806                 MemA[address,4] = S[d+r]; address = address+4;
10807             else
10808                 // Store as two word-aligned words in the correct order for current endianness.
10809                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10810                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10811                 address = address+8;
10812 #endif
10813 
10814     bool success = false;
10815 
10816     if (ConditionPassed (opcode))
10817     {
10818         bool single_regs;
10819         bool add;
10820         bool wback;
10821         uint32_t d;
10822         uint32_t n;
10823         uint32_t imm32;
10824         uint32_t regs;
10825 
10826         switch (encoding)
10827         {
10828             case eEncodingT1:
10829             case eEncodingA1:
10830                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10831                 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10832                 // if P == �1� && W == �0� then SEE VSTR;
10833                 // if P == U && W == �1� then UNDEFINED;
10834                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10835                     return false;
10836 
10837                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10838                 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10839                 single_regs = false;
10840                 add = BitIsSet (opcode, 23);
10841                 wback = BitIsSet (opcode, 21);
10842 
10843                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10844                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10845                 n = Bits32 (opcode, 19, 16);
10846                 imm32 = Bits32 (opcode, 7, 0) << 2;
10847 
10848                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�.
10849                 regs = Bits32 (opcode, 7, 0) / 2;
10850 
10851                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10852                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10853                     return false;
10854 
10855                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10856                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10857                     return false;
10858 
10859                 break;
10860 
10861             case eEncodingT2:
10862             case eEncodingA2:
10863                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10864                 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10865                 // if P == �1� && W == �0� then SEE VSTR;
10866                 // if P == U && W == �1� then UNDEFINED;
10867                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10868                     return false;
10869 
10870                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10871                 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10872                 single_regs = true;
10873                 add = BitIsSet (opcode, 23);
10874                 wback = BitIsSet (opcode, 21);
10875                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10876                 n = Bits32 (opcode, 19, 16);
10877 
10878                 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10879                 imm32 = Bits32 (opcode, 7, 0) << 2;
10880                 regs = Bits32 (opcode, 7, 0);
10881 
10882                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10883                 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM)))
10884                     return false;
10885 
10886                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10887                 if ((regs == 0) || ((d + regs) > 32))
10888                     return false;
10889 
10890                 break;
10891 
10892             default:
10893                 return false;
10894         }
10895 
10896         RegisterInfo base_reg;
10897         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10898 
10899         uint32_t Rn = ReadCoreReg (n, &success);
10900         if (!success)
10901             return false;
10902 
10903         // address = if add then R[n] else R[n]-imm32;
10904         addr_t address;
10905         if (add)
10906             address = Rn;
10907         else
10908             address = Rn - imm32;
10909 
10910         EmulateInstruction::Context context;
10911         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10912         if (wback)
10913         {
10914             uint32_t value;
10915             if (add)
10916                 value = Rn + imm32;
10917             else
10918                 value = Rn - imm32;
10919 
10920             context.type = eContextAdjustBaseRegister;
10921             context.SetRegisterPlusOffset (base_reg, value - Rn);
10922 
10923             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10924                 return false;
10925         }
10926 
10927         const uint32_t addr_byte_size = GetAddressByteSize();
10928         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10929 
10930         context.type = eContextRegisterStore;
10931         // for r = 0 to regs-1
10932         for (int r = 0; r < regs; ++r)
10933         {
10934 
10935             if (single_regs)
10936             {
10937                 // MemA[address,4] = S[d+r]; address = address+4;
10938                 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10939                 if (!success)
10940                     return false;
10941 
10942                 RegisterInfo data_reg;
10943                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
10944                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10945                 if (!MemAWrite (context, address, data, addr_byte_size))
10946                     return false;
10947 
10948                 address = address + 4;
10949             }
10950             else
10951             {
10952                 // // Store as two word-aligned words in the correct order for current endianness.
10953                 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10954                 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10955                 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10956                 if (!success)
10957                     return false;
10958 
10959                 RegisterInfo data_reg;
10960                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
10961 
10962                 if (GetByteOrder() == eByteOrderBig)
10963                 {
10964                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10965                     if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
10966                         return false;
10967 
10968                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10969                     if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size))
10970                         return false;
10971                 }
10972                 else
10973                 {
10974                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10975                     if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
10976                         return false;
10977 
10978                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10979                     if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
10980                         return false;
10981                 }
10982                 // address = address+8;
10983                 address = address + 8;
10984             }
10985         }
10986     }
10987     return true;
10988 }
10989 
10990 // A8.6.320
10991 // This instruciton loads a single extension register fronm memory, using an address from an ARM core register, with
10992 // an optional offset.
10993 bool
10994 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
10995 {
10996 #if 0
10997     if ConditionPassed() then
10998         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10999         base = if n == 15 then Align(PC,4) else R[n];
11000         address = if add then (base + imm32) else (base - imm32);
11001         if single_reg then
11002             S[d] = MemA[address,4];
11003         else
11004             word1 = MemA[address,4]; word2 = MemA[address+4,4];
11005             // Combine the word-aligned words in the correct order for current endianness.
11006             D[d] = if BigEndian() then word1:word2 else word2:word1;
11007 #endif
11008 
11009     bool success = false;
11010 
11011     if (ConditionPassed (opcode))
11012     {
11013         bool single_reg;
11014         bool add;
11015         uint32_t imm32;
11016         uint32_t d;
11017         uint32_t n;
11018 
11019         switch (encoding)
11020         {
11021             case eEncodingT1:
11022             case eEncodingA1:
11023                 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11024                 single_reg = false;
11025                 add = BitIsSet (opcode, 23);
11026                 imm32 = Bits32 (opcode, 7, 0) << 2;
11027 
11028                 // d = UInt(D:Vd); n = UInt(Rn);
11029                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11030                 n = Bits32 (opcode, 19, 16);
11031 
11032                 break;
11033 
11034             case eEncodingT2:
11035             case eEncodingA2:
11036                 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11037                 single_reg = true;
11038                 add = BitIsSet (opcode, 23);
11039                 imm32 = Bits32 (opcode, 7, 0) << 2;
11040 
11041                 // d = UInt(Vd:D); n = UInt(Rn);
11042                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11043                 n = Bits32 (opcode, 19, 16);
11044 
11045                 break;
11046 
11047             default:
11048                 return false;
11049         }
11050         RegisterInfo base_reg;
11051         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11052 
11053         uint32_t Rn = ReadCoreReg (n, &success);
11054         if (!success)
11055             return false;
11056 
11057         // base = if n == 15 then Align(PC,4) else R[n];
11058         uint32_t base;
11059         if (n == 15)
11060             base = AlignPC (Rn);
11061         else
11062             base = Rn;
11063 
11064         // address = if add then (base + imm32) else (base - imm32);
11065         addr_t address;
11066         if (add)
11067             address = base + imm32;
11068         else
11069             address = base - imm32;
11070 
11071         const uint32_t addr_byte_size = GetAddressByteSize();
11072         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11073 
11074         EmulateInstruction::Context context;
11075         context.type = eContextRegisterLoad;
11076         context.SetRegisterPlusOffset (base_reg, address - base);
11077 
11078         if (single_reg)
11079         {
11080             // S[d] = MemA[address,4];
11081             uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
11082             if (!success)
11083                 return false;
11084 
11085             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data))
11086                 return false;
11087         }
11088         else
11089         {
11090             // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11091             uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
11092             if (!success)
11093                 return false;
11094 
11095             context.SetRegisterPlusOffset (base_reg, (address + 4) - base);
11096             uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
11097             if (!success)
11098                 return false;
11099             // // Combine the word-aligned words in the correct order for current endianness.
11100             // D[d] = if BigEndian() then word1:word2 else word2:word1;
11101             uint64_t data64;
11102             if (GetByteOrder() == eByteOrderBig)
11103             {
11104                 data64 = word1;
11105                 data64 = (data64 << 32) | word2;
11106             }
11107             else
11108             {
11109                 data64 = word2;
11110                 data64 = (data64 << 32) | word1;
11111             }
11112 
11113             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64))
11114                 return false;
11115         }
11116     }
11117     return true;
11118 }
11119 
11120 // A8.6.400 VSTR
11121 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an
11122 // optional offset.
11123 bool
11124 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
11125 {
11126 #if 0
11127     if ConditionPassed() then
11128         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11129         address = if add then (R[n] + imm32) else (R[n] - imm32);
11130         if single_reg then
11131             MemA[address,4] = S[d];
11132         else
11133             // Store as two word-aligned words in the correct order for current endianness.
11134             MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11135             MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11136 #endif
11137 
11138     bool success = false;
11139 
11140     if (ConditionPassed (opcode))
11141     {
11142         bool single_reg;
11143         bool add;
11144         uint32_t imm32;
11145         uint32_t d;
11146         uint32_t n;
11147 
11148         switch (encoding)
11149         {
11150             case eEncodingT1:
11151             case eEncodingA1:
11152                 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11153                 single_reg = false;
11154                 add = BitIsSet (opcode, 23);
11155                 imm32 = Bits32 (opcode, 7, 0) << 2;
11156 
11157                 // d = UInt(D:Vd); n = UInt(Rn);
11158                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11159                 n = Bits32 (opcode, 19, 16);
11160 
11161                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11162                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11163                     return false;
11164 
11165                 break;
11166 
11167             case eEncodingT2:
11168             case eEncodingA2:
11169                 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11170                 single_reg = true;
11171                 add = BitIsSet (opcode, 23);
11172                 imm32 = Bits32 (opcode, 7, 0) << 2;
11173 
11174                 // d = UInt(Vd:D); n = UInt(Rn);
11175                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11176                 n = Bits32 (opcode, 19, 16);
11177 
11178                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11179                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11180                     return false;
11181 
11182                 break;
11183 
11184             default:
11185                 return false;
11186         }
11187 
11188         RegisterInfo base_reg;
11189         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11190 
11191         uint32_t Rn = ReadCoreReg (n, &success);
11192         if (!success)
11193             return false;
11194 
11195         // address = if add then (R[n] + imm32) else (R[n] - imm32);
11196         addr_t address;
11197         if (add)
11198             address = Rn + imm32;
11199         else
11200             address = Rn - imm32;
11201 
11202         const uint32_t addr_byte_size = GetAddressByteSize();
11203         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11204 
11205         RegisterInfo data_reg;
11206         GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg);
11207         EmulateInstruction::Context context;
11208         context.type = eContextRegisterStore;
11209         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11210 
11211         if (single_reg)
11212         {
11213             // MemA[address,4] = S[d];
11214             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11215             if (!success)
11216                 return false;
11217 
11218             if (!MemAWrite (context, address, data, addr_byte_size))
11219                 return false;
11220         }
11221         else
11222         {
11223             // // Store as two word-aligned words in the correct order for current endianness.
11224             // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11225             // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11226             uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11227             if (!success)
11228                 return false;
11229 
11230             if (GetByteOrder() == eByteOrderBig)
11231             {
11232                 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11233                     return false;
11234 
11235                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11236                 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size))
11237                     return false;
11238             }
11239             else
11240             {
11241                 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11242                     return false;
11243 
11244                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11245                 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11246                     return false;
11247             }
11248         }
11249     }
11250     return true;
11251 }
11252 
11253 // A8.6.307 VLDI1 (multiple single elements)
11254 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving.  Every
11255 // element of each register is loaded.
11256 bool
11257 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding)
11258 {
11259 #if 0
11260     if ConditionPassed() then
11261         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11262         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11263         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11264         for r = 0 to regs-1
11265             for e = 0 to elements-1
11266                 Elem[D[d+r],e,esize] = MemU[address,ebytes];
11267                 address = address + ebytes;
11268 #endif
11269 
11270     bool success = false;
11271 
11272     if (ConditionPassed (opcode))
11273     {
11274         uint32_t regs;
11275         uint32_t alignment;
11276         uint32_t ebytes;
11277         uint32_t esize;
11278         uint32_t elements;
11279         uint32_t d;
11280         uint32_t n;
11281         uint32_t m;
11282         bool wback;
11283         bool register_index;
11284 
11285         switch (encoding)
11286         {
11287             case eEncodingT1:
11288             case eEncodingA1:
11289             {
11290                 // case type of
11291                     // when �0111�
11292                         // regs = 1; if align<1> == �1� then UNDEFINED;
11293                     // when �1010�
11294                         // regs = 2; if align == �11� then UNDEFINED;
11295                     // when �0110�
11296                         // regs = 3; if align<1> == �1� then UNDEFINED;
11297                     // when �0010�
11298                         // regs = 4;
11299                     // otherwise
11300                         // SEE �Related encodings�;
11301                 uint32_t type = Bits32 (opcode, 11, 8);
11302                 uint32_t align = Bits32 (opcode, 5, 4);
11303                 if (type == 7) // '0111'
11304                 {
11305                     regs = 1;
11306                     if (BitIsSet (align, 1))
11307                         return false;
11308                 }
11309                 else if (type == 10) // '1010'
11310                 {
11311                     regs = 2;
11312                     if (align == 3)
11313                         return false;
11314 
11315                 }
11316                 else if (type == 6) // '0110'
11317                 {
11318                     regs = 3;
11319                     if (BitIsSet (align, 1))
11320                         return false;
11321                 }
11322                 else if (type == 2) // '0010'
11323                 {
11324                     regs = 4;
11325                 }
11326                 else
11327                     return false;
11328 
11329                 // alignment = if align == �00� then 1 else 4 << UInt(align);
11330                 if (align == 0)
11331                     alignment = 1;
11332                 else
11333                     alignment = 4 << align;
11334 
11335                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11336                 ebytes = 1 << Bits32 (opcode, 7, 6);
11337                 esize = 8 * ebytes;
11338                 elements = 8 / ebytes;
11339 
11340                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11341                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11342                 n = Bits32 (opcode, 19, 15);
11343                 m = Bits32 (opcode, 3, 0);
11344 
11345                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11346                 wback = (m != 15);
11347                 register_index = ((m != 15) && (m != 13));
11348 
11349                 // if d+regs > 32 then UNPREDICTABLE;
11350                 if ((d + regs) > 32)
11351                     return false;
11352             }
11353                 break;
11354 
11355             default:
11356                 return false;
11357         }
11358 
11359         RegisterInfo base_reg;
11360         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11361 
11362         uint32_t Rn = ReadCoreReg (n, &success);
11363         if (!success)
11364             return false;
11365 
11366         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11367         addr_t address = Rn;
11368         if ((address % alignment) != 0)
11369             return false;
11370 
11371         EmulateInstruction::Context context;
11372         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11373         if (wback)
11374         {
11375             uint32_t Rm = ReadCoreReg (m, &success);
11376             if (!success)
11377                 return false;
11378 
11379             uint32_t offset;
11380             if (register_index)
11381                 offset = Rm;
11382             else
11383                 offset = 8 * regs;
11384 
11385             uint32_t value = Rn + offset;
11386             context.type = eContextAdjustBaseRegister;
11387             context.SetRegisterPlusOffset (base_reg, offset);
11388 
11389             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11390                 return false;
11391 
11392         }
11393 
11394         // for r = 0 to regs-1
11395         for (int r = 0; r < regs; ++r)
11396         {
11397             // for e = 0 to elements-1
11398             uint64_t assembled_data = 0;
11399             for (int e = 0; e < elements; ++e)
11400             {
11401                 // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11402                 context.type = eContextRegisterLoad;
11403                 context.SetRegisterPlusOffset (base_reg, address - Rn);
11404                 uint64_t data = MemURead (context, address, ebytes, 0, &success);
11405                 if (!success)
11406                     return false;
11407 
11408                 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data
11409 
11410                 // address = address + ebytes;
11411                 address = address + ebytes;
11412             }
11413             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data))
11414                 return false;
11415         }
11416     }
11417     return true;
11418 }
11419 
11420 // A8.6.308 VLD1 (single element to one lane)
11421 //
11422 bool
11423 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding)
11424 {
11425 #if 0
11426     if ConditionPassed() then
11427         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11428         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11429         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11430         Elem[D[d],index,esize] = MemU[address,ebytes];
11431 #endif
11432 
11433     bool success = false;
11434 
11435     if (ConditionPassed (opcode))
11436     {
11437         uint32_t ebytes;
11438         uint32_t esize;
11439         uint32_t index;
11440         uint32_t alignment;
11441         uint32_t d;
11442         uint32_t n;
11443         uint32_t m;
11444         bool wback;
11445         bool register_index;
11446 
11447         switch (encoding)
11448         {
11449             case eEncodingT1:
11450             case eEncodingA1:
11451             {
11452                 uint32_t size = Bits32 (opcode, 11, 10);
11453                 uint32_t index_align = Bits32 (opcode, 7, 4);
11454                 // if size == �11� then SEE VLD1 (single element to all lanes);
11455                 if (size == 3)
11456                    return EmulateVLD1SingleAll (opcode, encoding);
11457                 // case size of
11458                 if (size == 0) // when '00'
11459                 {
11460                     // if index_align<0> != �0� then UNDEFINED;
11461                     if (BitIsClear (index_align, 0))
11462                         return false;
11463 
11464                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11465                     ebytes = 1;
11466                     esize = 8;
11467                     index = Bits32 (index_align, 3, 1);
11468                     alignment = 1;
11469                 }
11470                 else if (size == 1) // when �01�
11471                 {
11472                     // if index_align<1> != �0� then UNDEFINED;
11473                     if (BitIsClear (index_align, 1))
11474                         return false;
11475 
11476                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11477                     ebytes = 2;
11478                     esize = 16;
11479                     index = Bits32 (index_align, 3, 2);
11480 
11481                     // alignment = if index_align<0> == �0� then 1 else 2;
11482                     if (BitIsClear (index_align, 0))
11483                         alignment = 1;
11484                     else
11485                         alignment = 2;
11486                 }
11487                 else if (size == 2) // when �10�
11488                 {
11489                     // if index_align<2> != �0� then UNDEFINED;
11490                     if (BitIsClear (index_align, 2))
11491                         return false;
11492 
11493                     // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11494                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11495                         return false;
11496 
11497                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11498                     ebytes = 4;
11499                     esize = 32;
11500                     index = Bit32 (index_align, 3);
11501 
11502                     // alignment = if index_align<1:0> == �00� then 1 else 4;
11503                     if (Bits32 (index_align, 1, 0) == 0)
11504                         alignment = 1;
11505                     else
11506                         alignment = 4;
11507                 }
11508                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11509                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11510                 n = Bits32 (opcode, 19, 16);
11511                 m = Bits32 (opcode, 3, 0);
11512 
11513                 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
11514                 wback = (m != 15);
11515                 register_index = ((m != 15) && (m != 13));
11516 
11517                 if (n == 15)
11518                     return false;
11519 
11520             }
11521                 break;
11522 
11523             default:
11524                 return false;
11525         }
11526 
11527         RegisterInfo base_reg;
11528         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11529 
11530         uint32_t Rn = ReadCoreReg (n, &success);
11531         if (!success)
11532             return false;
11533 
11534         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11535         addr_t address = Rn;
11536         if ((address % alignment) != 0)
11537             return false;
11538 
11539         EmulateInstruction::Context context;
11540         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11541         if (wback)
11542         {
11543             uint32_t Rm = ReadCoreReg (m, &success);
11544             if (!success)
11545                 return false;
11546 
11547             uint32_t offset;
11548             if (register_index)
11549                 offset = Rm;
11550             else
11551                 offset = ebytes;
11552 
11553             uint32_t value = Rn + offset;
11554 
11555             context.type = eContextAdjustBaseRegister;
11556             context.SetRegisterPlusOffset (base_reg, offset);
11557 
11558             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11559                 return false;
11560         }
11561 
11562         // Elem[D[d],index,esize] = MemU[address,ebytes];
11563         uint32_t element = MemURead (context, address, esize, 0, &success);
11564         if (!success)
11565             return false;
11566 
11567         element = element << (index * esize);
11568 
11569         uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11570         if (!success)
11571             return false;
11572 
11573         uint64_t all_ones = -1;
11574         uint64_t mask = all_ones << ((index+1) * esize);  // mask is all 1's to left of where 'element' goes, & all 0's
11575                                                           // at element & to the right of element.
11576         if (index > 0)
11577             mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes.
11578                                                                      // now mask should be 0's where element goes & 1's
11579                                                                      // everywhere else.
11580 
11581         uint64_t masked_reg = reg_data & mask;  // Take original reg value & zero out 'element' bits
11582         reg_data = masked_reg & element;        // Put 'element' into those bits in reg_data.
11583 
11584         context.type = eContextRegisterLoad;
11585         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data))
11586             return false;
11587     }
11588     return true;
11589 }
11590 
11591 // A8.6.391 VST1 (multiple single elements)
11592 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four regsiters, without
11593 // interleaving.  Every element of each register is stored.
11594 bool
11595 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding)
11596 {
11597 #if 0
11598     if ConditionPassed() then
11599         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11600         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11601         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11602         for r = 0 to regs-1
11603             for e = 0 to elements-1
11604                 MemU[address,ebytes] = Elem[D[d+r],e,esize];
11605                 address = address + ebytes;
11606 #endif
11607 
11608     bool success = false;
11609 
11610     if (ConditionPassed (opcode))
11611     {
11612         uint32_t regs;
11613         uint32_t alignment;
11614         uint32_t ebytes;
11615         uint32_t esize;
11616         uint32_t elements;
11617         uint32_t d;
11618         uint32_t n;
11619         uint32_t m;
11620         bool wback;
11621         bool register_index;
11622 
11623         switch (encoding)
11624         {
11625             case eEncodingT1:
11626             case eEncodingA1:
11627             {
11628                 uint32_t type = Bits32 (opcode, 11, 8);
11629                 uint32_t align = Bits32 (opcode, 5, 4);
11630 
11631                 // case type of
11632                 if (type == 7)    // when �0111�
11633                 {
11634                     // regs = 1; if align<1> == �1� then UNDEFINED;
11635                     regs = 1;
11636                     if (BitIsSet (align, 1))
11637                         return false;
11638                 }
11639                 else if (type == 10) // when �1010�
11640                 {
11641                     // regs = 2; if align == �11� then UNDEFINED;
11642                     regs = 2;
11643                     if (align == 3)
11644                         return false;
11645                 }
11646                 else if (type == 6) // when �0110�
11647                 {
11648                     // regs = 3; if align<1> == �1� then UNDEFINED;
11649                     regs = 3;
11650                     if (BitIsSet (align, 1))
11651                         return false;
11652                 }
11653                 else if (type == 2) // when �0010�
11654                     // regs = 4;
11655                     regs = 4;
11656                 else // otherwise
11657                     // SEE �Related encodings�;
11658                     return false;
11659 
11660                 // alignment = if align == �00� then 1 else 4 << UInt(align);
11661                 if (align == 0)
11662                     alignment = 1;
11663                 else
11664                     alignment = 4 << align;
11665 
11666                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11667                 ebytes = 1 << Bits32 (opcode,7, 6);
11668                 esize = 8 * ebytes;
11669                 elements = 8 / ebytes;
11670 
11671                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11672                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11673                 n = Bits32 (opcode, 19, 16);
11674                 m = Bits32 (opcode, 3, 0);
11675 
11676                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11677                 wback = (m != 15);
11678                 register_index = ((m != 15) && (m != 13));
11679 
11680                 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11681                 if ((d + regs) > 32)
11682                     return false;
11683 
11684                 if (n == 15)
11685                     return false;
11686 
11687             }
11688                 break;
11689 
11690             default:
11691                 return false;
11692         }
11693 
11694         RegisterInfo base_reg;
11695         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11696 
11697         uint32_t Rn = ReadCoreReg (n, &success);
11698         if (!success)
11699             return false;
11700 
11701         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11702         addr_t address = Rn;
11703         if ((address % alignment) != 0)
11704             return false;
11705 
11706         EmulateInstruction::Context context;
11707         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11708         if (wback)
11709         {
11710             uint32_t Rm = ReadCoreReg (m, &success);
11711             if (!success)
11712                 return false;
11713 
11714             uint32_t offset;
11715             if (register_index)
11716                 offset = Rm;
11717             else
11718                 offset = 8 * regs;
11719 
11720             context.type = eContextAdjustBaseRegister;
11721             context.SetRegisterPlusOffset (base_reg, offset);
11722 
11723             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11724                 return false;
11725         }
11726 
11727         RegisterInfo data_reg;
11728         context.type = eContextRegisterStore;
11729         // for r = 0 to regs-1
11730         for (int r = 0; r < regs; ++r)
11731         {
11732             GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
11733             uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
11734             if (!success)
11735                 return false;
11736 
11737              // for e = 0 to elements-1
11738             for (int e = 0; e < elements; ++e)
11739             {
11740                 // MemU[address,ebytes] = Elem[D[d+r],e,esize];
11741                 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize);
11742 
11743                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11744                 if (!MemUWrite (context, address, word, ebytes))
11745                     return false;
11746 
11747                 // address = address + ebytes;
11748                 address = address + ebytes;
11749             }
11750         }
11751     }
11752     return true;
11753 }
11754 
11755 // A8.6.392 VST1 (single element from one lane)
11756 // This instruction stores one element to memory from one element of a register.
11757 bool
11758 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding)
11759 {
11760 #if 0
11761     if ConditionPassed() then
11762         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11763         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11764         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11765         MemU[address,ebytes] = Elem[D[d],index,esize];
11766 #endif
11767 
11768     bool success = false;
11769 
11770     if (ConditionPassed (opcode))
11771     {
11772         uint32_t ebytes;
11773         uint32_t esize;
11774         uint32_t index;
11775         uint32_t alignment;
11776         uint32_t d;
11777         uint32_t n;
11778         uint32_t m;
11779         bool wback;
11780         bool register_index;
11781 
11782         switch (encoding)
11783         {
11784             case eEncodingT1:
11785             case eEncodingA1:
11786             {
11787                 uint32_t size = Bits32 (opcode, 11, 10);
11788                 uint32_t index_align = Bits32 (opcode, 7, 4);
11789 
11790                 // if size == �11� then UNDEFINED;
11791                 if (size == 3)
11792                     return false;
11793 
11794                 // case size of
11795                 if (size == 0) // when �00�
11796                 {
11797                     // if index_align<0> != �0� then UNDEFINED;
11798                     if (BitIsClear (index_align, 0))
11799                         return false;
11800                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11801                     ebytes = 1;
11802                     esize = 8;
11803                     index = Bits32 (index_align, 3, 1);
11804                     alignment = 1;
11805                 }
11806                 else if (size == 1) // when �01�
11807                 {
11808                     // if index_align<1> != �0� then UNDEFINED;
11809                     if (BitIsClear (index_align, 1))
11810                         return false;
11811 
11812                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11813                     ebytes = 2;
11814                     esize = 16;
11815                     index = Bits32 (index_align, 3, 2);
11816 
11817                     // alignment = if index_align<0> == �0� then 1 else 2;
11818                     if (BitIsClear (index_align, 0))
11819                         alignment = 1;
11820                     else
11821                         alignment = 2;
11822                 }
11823                 else if (size == 2) // when �10�
11824                 {
11825                     // if index_align<2> != �0� then UNDEFINED;
11826                     if (BitIsClear (index_align, 2))
11827                         return false;
11828 
11829                     // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11830                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11831                         return false;
11832 
11833                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11834                     ebytes = 4;
11835                     esize = 32;
11836                     index = Bit32 (index_align, 3);
11837 
11838                     // alignment = if index_align<1:0> == �00� then 1 else 4;
11839                     if (Bits32 (index_align, 1, 0) == 0)
11840                         alignment = 1;
11841                     else
11842                         alignment = 4;
11843                 }
11844                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11845                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11846                 n = Bits32 (opcode, 19, 16);
11847                 m = Bits32 (opcode, 3, 0);
11848 
11849                 // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15 then UNPREDICTABLE;
11850                 wback = (m != 15);
11851                 register_index = ((m != 15) && (m != 13));
11852 
11853                 if (n == 15)
11854                     return false;
11855             }
11856                 break;
11857 
11858             default:
11859                 return false;
11860         }
11861 
11862         RegisterInfo base_reg;
11863         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11864 
11865         uint32_t Rn = ReadCoreReg (n, &success);
11866         if (!success)
11867             return false;
11868 
11869         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11870         addr_t address = Rn;
11871         if ((address % alignment) != 0)
11872             return false;
11873 
11874         EmulateInstruction::Context context;
11875         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11876         if (wback)
11877         {
11878             uint32_t Rm = ReadCoreReg (m, &success);
11879             if (!success)
11880                 return false;
11881 
11882             uint32_t offset;
11883             if (register_index)
11884                 offset = Rm;
11885             else
11886                 offset = ebytes;
11887 
11888             context.type = eContextAdjustBaseRegister;
11889             context.SetRegisterPlusOffset (base_reg, offset);
11890 
11891             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11892                 return false;
11893         }
11894 
11895         // MemU[address,ebytes] = Elem[D[d],index,esize];
11896         uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11897         if (!success)
11898             return false;
11899 
11900         uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1,  index * esize);
11901 
11902         RegisterInfo data_reg;
11903         GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg);
11904         context.type = eContextRegisterStore;
11905         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11906 
11907         if (!MemUWrite (context, address, word, ebytes))
11908             return false;
11909     }
11910     return true;
11911 }
11912 
11913 // A8.6.309 VLD1 (single element to all lanes)
11914 // This instruction loads one element from memory into every element of one or two vectors.
11915 bool
11916 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding)
11917 {
11918 #if 0
11919     if ConditionPassed() then
11920         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11921         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11922         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11923         replicated_element = Replicate(MemU[address,ebytes], elements);
11924         for r = 0 to regs-1
11925             D[d+r] = replicated_element;
11926 #endif
11927 
11928     bool success = false;
11929 
11930     if (ConditionPassed (opcode))
11931     {
11932         uint32_t ebytes;
11933         uint32_t elements;
11934         uint32_t regs;
11935         uint32_t alignment;
11936         uint32_t d;
11937         uint32_t n;
11938         uint32_t m;
11939         bool wback;
11940         bool register_index;
11941 
11942         switch (encoding)
11943         {
11944             case eEncodingT1:
11945             case eEncodingA1:
11946             {
11947                 //if size == �11� || (size == �00� && a == �1�) then UNDEFINED;
11948                 uint32_t size = Bits32 (opcode, 7, 6);
11949                 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4)))
11950                     return false;
11951 
11952                 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2;
11953                 ebytes = 1 << size;
11954                 elements = 8 / ebytes;
11955                 if (BitIsClear (opcode, 5))
11956                     regs = 1;
11957                 else
11958                     regs = 2;
11959 
11960                 //alignment = if a == �0� then 1 else ebytes;
11961                 if (BitIsClear (opcode, 4))
11962                     alignment = 1;
11963                 else
11964                     alignment = ebytes;
11965 
11966                 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11967                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11968                 n = Bits32 (opcode, 19, 16);
11969                 m = Bits32 (opcode, 3, 0);
11970 
11971                 //wback = (m != 15); register_index = (m != 15 && m != 13);
11972                 wback = (m != 15);
11973                 register_index = ((m != 15) && (m != 13));
11974 
11975                 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11976                 if ((d + regs) > 32)
11977                     return false;
11978 
11979                 if (n == 15)
11980                     return false;
11981             }
11982             break;
11983 
11984             default:
11985                 return false;
11986         }
11987 
11988         RegisterInfo base_reg;
11989         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11990 
11991         uint32_t Rn = ReadCoreReg (n, &success);
11992         if (!success)
11993             return false;
11994 
11995         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11996         addr_t address = Rn;
11997         if ((address % alignment) != 0)
11998             return false;
11999 
12000         EmulateInstruction::Context context;
12001         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12002         if (wback)
12003         {
12004             uint32_t Rm = ReadCoreReg (m, &success);
12005             if (!success)
12006                 return false;
12007 
12008             uint32_t offset;
12009             if (register_index)
12010                 offset = Rm;
12011             else
12012                 offset = ebytes;
12013 
12014             context.type = eContextAdjustBaseRegister;
12015             context.SetRegisterPlusOffset (base_reg, offset);
12016 
12017             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
12018                 return false;
12019         }
12020 
12021         // replicated_element = Replicate(MemU[address,ebytes], elements);
12022 
12023         context.type = eContextRegisterLoad;
12024         uint64_t word = MemURead (context, address, ebytes, 0, &success);
12025         if (!success)
12026             return false;
12027 
12028         uint64_t replicated_element = 0;
12029         uint32_t esize = ebytes * 8;
12030         for (int e = 0; e < elements; ++e)
12031             replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0);
12032 
12033         // for r = 0 to regs-1
12034         for (int r = 0; r < regs; ++r)
12035         {
12036             // D[d+r] = replicated_element;
12037             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element))
12038                 return false;
12039         }
12040     }
12041     return true;
12042 }
12043 
12044 // B6.2.13 SUBS PC, LR and related instructions
12045 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack.  It subtracts the
12046 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR.
12047 bool
12048 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding)
12049 {
12050 #if 0
12051     if ConditionPassed() then
12052         EncodingSpecificOperations();
12053         if CurrentInstrSet() == InstrSet_ThumbEE then
12054             UNPREDICTABLE;
12055         operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12056         case opcode of
12057             when �0000� result = R[n] AND operand2; // AND
12058             when �0001� result = R[n] EOR operand2; // EOR
12059             when �0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12060             when �0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12061             when �0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12062             when �0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12063             when �0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12064             when �0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12065             when �1100� result = R[n] OR operand2; // ORR
12066             when �1101� result = operand2; // MOV
12067             when �1110� result = R[n] AND NOT(operand2); // BIC
12068             when �1111� result = NOT(operand2); // MVN
12069         CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12070         BranchWritePC(result);
12071 #endif
12072 
12073     bool success = false;
12074 
12075     if (ConditionPassed (opcode))
12076     {
12077         uint32_t n;
12078         uint32_t m;
12079         uint32_t imm32;
12080         bool register_form;
12081         ARM_ShifterType shift_t;
12082         uint32_t shift_n;
12083         uint32_t code;
12084 
12085         switch (encoding)
12086         {
12087             case eEncodingT1:
12088                 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
12089                 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB
12090                 n = 14;
12091                 imm32 = Bits32 (opcode, 7, 0);
12092                 register_form = false;
12093                 code = 2;
12094 
12095                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12096                 if (InITBlock() && !LastInITBlock())
12097                     return false;
12098 
12099                 break;
12100 
12101             case eEncodingA1:
12102                 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12103                 n = Bits32 (opcode, 19, 16);
12104                 imm32 = ARMExpandImm (opcode);
12105                 register_form = false;
12106                 code = Bits32 (opcode, 24, 21);
12107 
12108                 break;
12109 
12110             case eEncodingA2:
12111                 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12112                 n = Bits32 (opcode, 19, 16);
12113                 m = Bits32 (opcode, 3, 0);
12114                 register_form = true;
12115 
12116                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12117                 shift_n = DecodeImmShiftARM (opcode, shift_t);
12118 
12119                 break;
12120 
12121             default:
12122                 return false;
12123         }
12124 
12125         // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12126         uint32_t operand2;
12127         if (register_form)
12128         {
12129             uint32_t Rm = ReadCoreReg (m, &success);
12130             if (!success)
12131                 return false;
12132 
12133             operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success);
12134             if (!success)
12135                 return false;
12136         }
12137         else
12138         {
12139             operand2 = imm32;
12140         }
12141 
12142         uint32_t Rn = ReadCoreReg (n, &success);
12143         if (!success)
12144             return false;
12145 
12146         AddWithCarryResult result;
12147 
12148         // case opcode of
12149         switch (code)
12150         {
12151             case 0: // when �0000�
12152                 // result = R[n] AND operand2; // AND
12153                 result.result = Rn & operand2;
12154                 break;
12155 
12156             case 1: // when �0001�
12157                 // result = R[n] EOR operand2; // EOR
12158                 result.result = Rn ^ operand2;
12159                 break;
12160 
12161             case 2: // when �0010�
12162                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12163                 result = AddWithCarry (Rn, ~(operand2), 1);
12164                 break;
12165 
12166             case 3: // when �0011�
12167                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12168                 result = AddWithCarry (~(Rn), operand2, 1);
12169                 break;
12170 
12171             case 4: // when �0100�
12172                 // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12173                 result = AddWithCarry (Rn, operand2, 0);
12174                 break;
12175 
12176             case 5: // when �0101�
12177                 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12178                 result = AddWithCarry (Rn, operand2, APSR_C);
12179                 break;
12180 
12181             case 6: // when �0110�
12182                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12183                 result = AddWithCarry (Rn, ~(operand2), APSR_C);
12184                 break;
12185 
12186             case 7: // when �0111�
12187                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12188                 result = AddWithCarry (~(Rn), operand2, APSR_C);
12189                 break;
12190 
12191             case 10: // when �1100�
12192                 // result = R[n] OR operand2; // ORR
12193                 result.result = Rn | operand2;
12194                 break;
12195 
12196             case 11: // when �1101�
12197                 // result = operand2; // MOV
12198                 result.result = operand2;
12199                 break;
12200 
12201             case 12: // when �1110�
12202                 // result = R[n] AND NOT(operand2); // BIC
12203                 result.result = Rn & ~(operand2);
12204                 break;
12205 
12206             case 15: // when �1111�
12207                 // result = NOT(operand2); // MVN
12208                 result.result = ~(operand2);
12209                 break;
12210 
12211             default:
12212                 return false;
12213         }
12214         // CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12215 
12216         // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for
12217         // the best.
12218         uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12219         if (!success)
12220             return false;
12221 
12222         CPSRWriteByInstr (spsr, 15, true);
12223 
12224         // BranchWritePC(result);
12225         EmulateInstruction::Context context;
12226         context.type = eContextAdjustPC;
12227         context.SetImmediate (result.result);
12228 
12229         BranchWritePC (context, result.result);
12230     }
12231     return true;
12232 }
12233 
12234 EmulateInstructionARM::ARMOpcode*
12235 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12236 {
12237     static ARMOpcode
12238     g_arm_opcodes[] =
12239     {
12240         //----------------------------------------------------------------------
12241         // Prologue instructions
12242         //----------------------------------------------------------------------
12243 
12244         // push register(s)
12245         { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12246         { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
12247 
12248         // set r7 to point to a stack offset
12249         { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
12250         { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12251         // copy the stack pointer to ip
12252         { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
12253         { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
12254         { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12255 
12256         // adjust the stack pointer
12257         { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12258         { 0x0fef0010, 0x004d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12259 
12260         // push one register
12261         // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12262         { 0x0e5f0000, 0x040d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
12263 
12264         // vector push consecutive extension register(s)
12265         { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12266         { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12267 
12268         //----------------------------------------------------------------------
12269         // Epilogue instructions
12270         //----------------------------------------------------------------------
12271 
12272         { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12273         { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12274         { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12275         { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12276 
12277         //----------------------------------------------------------------------
12278         // Supervisor Call (previously Software Interrupt)
12279         //----------------------------------------------------------------------
12280         { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12281 
12282         //----------------------------------------------------------------------
12283         // Branch instructions
12284         //----------------------------------------------------------------------
12285         { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
12286         // To resolve ambiguity, "blx <label>" should come before "bl <label>".
12287         { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12288         { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12289         { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12290         // for example, "bx lr"
12291         { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12292         // bxj
12293         { 0x0ffffff0, 0x012fff20, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12294 
12295         //----------------------------------------------------------------------
12296         // Data-processing instructions
12297         //----------------------------------------------------------------------
12298         // adc (immediate)
12299         { 0x0fe00000, 0x02a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12300         // adc (register)
12301         { 0x0fe00010, 0x00a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12302         // add (immediate)
12303         { 0x0fe00000, 0x02800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
12304         // add (register)
12305         { 0x0fe00010, 0x00800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12306         // add (register-shifted register)
12307         { 0x0fe00090, 0x00800010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12308         // adr
12309         { 0x0fff0000, 0x028f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12310         { 0x0fff0000, 0x024f0000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12311         // and (immediate)
12312         { 0x0fe00000, 0x02000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12313         // and (register)
12314         { 0x0fe00010, 0x00000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12315         // bic (immediate)
12316         { 0x0fe00000, 0x03c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12317         // bic (register)
12318         { 0x0fe00010, 0x01c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12319         // eor (immediate)
12320         { 0x0fe00000, 0x02200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12321         // eor (register)
12322         { 0x0fe00010, 0x00200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12323         // orr (immediate)
12324         { 0x0fe00000, 0x03800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12325         // orr (register)
12326         { 0x0fe00010, 0x01800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12327         // rsb (immediate)
12328         { 0x0fe00000, 0x02600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12329         // rsb (register)
12330         { 0x0fe00010, 0x00600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12331         // rsc (immediate)
12332         { 0x0fe00000, 0x02e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12333         // rsc (register)
12334         { 0x0fe00010, 0x00e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12335         // sbc (immediate)
12336         { 0x0fe00000, 0x02c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12337         // sbc (register)
12338         { 0x0fe00010, 0x00c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12339         // sub (immediate, ARM)
12340         { 0x0fe00000, 0x02400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
12341         // sub (sp minus immediate)
12342         { 0x0fef0000, 0x024d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12343         // sub (register)
12344         { 0x0fe00010, 0x00400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12345         // teq (immediate)
12346         { 0x0ff0f000, 0x03300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12347         // teq (register)
12348         { 0x0ff0f010, 0x01300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12349         // tst (immediate)
12350         { 0x0ff0f000, 0x03100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12351         // tst (register)
12352         { 0x0ff0f010, 0x01100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12353 
12354         // mov (immediate)
12355         { 0x0fef0000, 0x03a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12356         { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
12357         // mov (register)
12358         { 0x0fef0ff0, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12359         // mvn (immediate)
12360         { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12361         // mvn (register)
12362         { 0x0fef0010, 0x01e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12363         // cmn (immediate)
12364         { 0x0ff0f000, 0x03700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12365         // cmn (register)
12366         { 0x0ff0f010, 0x01700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12367         // cmp (immediate)
12368         { 0x0ff0f000, 0x03500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
12369         // cmp (register)
12370         { 0x0ff0f010, 0x01500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
12371         // asr (immediate)
12372         { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
12373         // asr (register)
12374         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
12375         // lsl (immediate)
12376         { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
12377         // lsl (register)
12378         { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
12379         // lsr (immediate)
12380         { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
12381         // lsr (register)
12382         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
12383         // rrx is a special case encoding of ror (immediate)
12384         { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
12385         // ror (immediate)
12386         { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
12387         // ror (register)
12388         { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
12389         // mul
12390         { 0x0fe000f0, 0x00000090, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
12391 
12392         // subs pc, lr and related instructions
12393         { 0x0e10f000, 0x0210f000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" },
12394         { 0x0e10f010, 0x0010f000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" },
12395 
12396         //----------------------------------------------------------------------
12397         // Load instructions
12398         //----------------------------------------------------------------------
12399         { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12400         { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
12401         { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12402         { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
12403         { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
12404         { 0x0e500010, 0x06100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
12405         { 0x0e5f0000, 0x045f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
12406         { 0xfe500010, 0x06500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
12407         { 0x0e5f00f0, 0x005f00b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12408         { 0x0e5000f0, 0x001000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"  },
12409         { 0x0e5000f0, 0x005000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
12410         { 0x0e5f00f0, 0x005f00d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
12411         { 0x0e5000f0, 0x001000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12412         { 0x0e5000f0, 0x005000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
12413         { 0x0e5f00f0, 0x005f00f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12414         { 0x0e5000f0, 0x001000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12415         { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
12416         { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12417         { 0x0e100f00, 0x0c100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12418         { 0x0e100f00, 0x0c100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12419         { 0x0f300f00, 0x0d100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12420         { 0x0f300f00, 0x0d100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12421         { 0xffb00000, 0xf4200000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12422         { 0xffb00300, 0xf4a00000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12423         { 0xffb00f00, 0xf4a00c00, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12424 
12425         //----------------------------------------------------------------------
12426         // Store instructions
12427         //----------------------------------------------------------------------
12428         { 0x0fd00000, 0x08800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12429         { 0x0fd00000, 0x08000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
12430         { 0x0fd00000, 0x09000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12431         { 0x0fd00000, 0x09800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
12432         { 0x0e500010, 0x06000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
12433         { 0x0e5000f0, 0x000000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
12434         { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
12435         { 0x0e500000, 0x04400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12436         { 0x0e500000, 0x04000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12437         { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
12438         { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12439         { 0x0e100f00, 0x0c000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12440         { 0x0e100f00, 0x0c000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12441         { 0x0f300f00, 0x0d000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
12442         { 0x0f300f00, 0x0d000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
12443         { 0xffb00000, 0xf4000000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12444         { 0xffb00300, 0xf4800000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12445 
12446         //----------------------------------------------------------------------
12447         // Other instructions
12448         //----------------------------------------------------------------------
12449         { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
12450         { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
12451         { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
12452         { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
12453         { 0xfe500000, 0xf8100000, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
12454 
12455     };
12456     static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode);
12457 
12458     for (size_t i=0; i<k_num_arm_opcodes; ++i)
12459     {
12460         if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
12461             (g_arm_opcodes[i].variants & arm_isa) != 0)
12462             return &g_arm_opcodes[i];
12463     }
12464     return NULL;
12465 }
12466 
12467 
12468 EmulateInstructionARM::ARMOpcode*
12469 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12470 {
12471 
12472     static ARMOpcode
12473     g_thumb_opcodes[] =
12474     {
12475         //----------------------------------------------------------------------
12476         // Prologue instructions
12477         //----------------------------------------------------------------------
12478 
12479         // push register(s)
12480         { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12481         { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
12482         { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
12483 
12484         // set r7 to point to a stack offset
12485         { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
12486         // copy the stack pointer to r7
12487         { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
12488         // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
12489         { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
12490 
12491         // PC-relative load into register (see also EmulateADDSPRm)
12492         { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
12493 
12494         // adjust the stack pointer
12495         { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
12496         { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
12497         { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
12498         { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
12499         { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12500 
12501         // vector push consecutive extension register(s)
12502         { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12503         { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12504 
12505         //----------------------------------------------------------------------
12506         // Epilogue instructions
12507         //----------------------------------------------------------------------
12508 
12509         { 0xfffff800, 0x0000a800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
12510         { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
12511         { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12512         { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
12513         { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
12514         { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12515         { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12516 
12517         //----------------------------------------------------------------------
12518         // Supervisor Call (previously Software Interrupt)
12519         //----------------------------------------------------------------------
12520         { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
12521 
12522         //----------------------------------------------------------------------
12523         // If Then makes up to four following instructions conditional.
12524         //----------------------------------------------------------------------
12525         // The next 5 opcode _must_ come before the if then instruction
12526         { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"},
12527         { 0xffffffff, 0x0000bf10, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
12528         { 0xffffffff, 0x0000bf20, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
12529         { 0xffffffff, 0x0000bf30, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
12530         { 0xffffffff, 0x0000bf40, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
12531         { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
12532 
12533         //----------------------------------------------------------------------
12534         // Branch instructions
12535         //----------------------------------------------------------------------
12536         // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
12537         { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
12538         { 0xfffff800, 0x0000e000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
12539         { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
12540         { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
12541         // J1 == J2 == 1
12542         { 0xf800d000, 0xf000d000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12543         // J1 == J2 == 1
12544         { 0xf800d001, 0xf000c000, ARMV5_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12545         { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12546         // for example, "bx lr"
12547         { 0xffffff87, 0x00004700, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12548         // bxj
12549         { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12550         // compare and branch
12551         { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
12552         // table branch byte
12553         { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
12554         // table branch halfword
12555         { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
12556 
12557         //----------------------------------------------------------------------
12558         // Data-processing instructions
12559         //----------------------------------------------------------------------
12560         // adc (immediate)
12561         { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
12562         // adc (register)
12563         { 0xffffffc0, 0x00004140, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
12564         { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12565         // add (register)
12566         { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
12567         // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
12568         { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
12569         // adr
12570         { 0xfffff800, 0x0000a000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12571         { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12572         { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12573         // and (immediate)
12574         { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
12575         // and (register)
12576         { 0xffffffc0, 0x00004000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
12577         { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12578         // bic (immediate)
12579         { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
12580         // bic (register)
12581         { 0xffffffc0, 0x00004380, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
12582         { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12583         // eor (immediate)
12584         { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
12585         // eor (register)
12586         { 0xffffffc0, 0x00004040, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
12587         { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12588         // orr (immediate)
12589         { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
12590         // orr (register)
12591         { 0xffffffc0, 0x00004300, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
12592         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12593         // rsb (immediate)
12594         { 0xffffffc0, 0x00004240, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
12595         { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
12596         // rsb (register)
12597         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12598         // sbc (immediate)
12599         { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12600         // sbc (register)
12601         { 0xffffffc0, 0x00004180, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
12602         { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12603         // add (immediate, Thumb)
12604         { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
12605         { 0xfffff800, 0x00003000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
12606         { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
12607         { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
12608         // sub (immediate, Thumb)
12609         { 0xfffffe00, 0x00001e00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
12610         { 0xfffff800, 0x00003800, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
12611         { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
12612         { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
12613         // sub (sp minus immediate)
12614         { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
12615         { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
12616         // sub (register)
12617         { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
12618         { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
12619         // teq (immediate)
12620         { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
12621         // teq (register)
12622         { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12623         // tst (immediate)
12624         { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
12625         // tst (register)
12626         { 0xffffffc0, 0x00004200, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
12627         { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
12628 
12629 
12630         // move from high register to high register
12631         { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
12632         // move from low register to low register
12633         { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
12634         // mov{s}<c>.w <Rd>, <Rm>
12635         { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
12636         // move immediate
12637         { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
12638         { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
12639         { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
12640         // mvn (immediate)
12641         { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
12642         // mvn (register)
12643         { 0xffffffc0, 0x000043c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
12644         { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
12645         // cmn (immediate)
12646         { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12647         // cmn (register)
12648         { 0xffffffc0, 0x000042c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
12649         { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12650         // cmp (immediate)
12651         { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
12652         { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
12653         // cmp (register) (Rn and Rm both from r0-r7)
12654         { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12655         // cmp (register) (Rn and Rm not both from r0-r7)
12656         { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12657         // asr (immediate)
12658         { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
12659         { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
12660         // asr (register)
12661         { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
12662         { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12663         // lsl (immediate)
12664         { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
12665         { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
12666         // lsl (register)
12667         { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
12668         { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
12669         // lsr (immediate)
12670         { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
12671         { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
12672         // lsr (register)
12673         { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
12674         { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12675         // rrx is a special case encoding of ror (immediate)
12676         { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
12677         // ror (immediate)
12678         { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
12679         // ror (register)
12680         { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
12681         { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
12682         // mul
12683         { 0xffffffc0, 0x00004340, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
12684         // mul
12685         { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
12686 
12687         // subs pc, lr and related instructions
12688         { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" },
12689 
12690         //----------------------------------------------------------------------
12691         // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table;
12692         // otherwise the wrong instructions will be selected.
12693         //----------------------------------------------------------------------
12694 
12695         { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
12696         { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
12697 
12698         //----------------------------------------------------------------------
12699         // Load instructions
12700         //----------------------------------------------------------------------
12701         { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12702         { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
12703         { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12704         { 0xfffff800, 0x00006800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
12705         { 0xfffff800, 0x00009800, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
12706         { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
12707         { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
12708                   // Thumb2 PC-relative load into register
12709         { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
12710         { 0xfffffe00, 0x00005800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
12711         { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
12712         { 0xfffff800, 0x00007800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
12713         { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12714         { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" },
12715         { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
12716         { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
12717         { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
12718         { 0xfffff800, 0x00008800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"  },
12719         { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12720         { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"  },
12721         { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12722         { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
12723         { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12724         { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
12725         { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12726         { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
12727         { 0xfffffe00, 0x00005600, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
12728         { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"  },
12729         { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
12730         { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12731         { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12732         { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
12733         { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12734         { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
12735         { 0xfe100f00, 0xec100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12736         { 0xfe100f00, 0xec100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
12737         { 0xffe00f00, 0xed100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12738         { 0xff300f00, 0xed100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
12739         { 0xffb00000, 0xf9200000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12740         { 0xffb00300, 0xf9a00000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12741         { 0xffb00f00, 0xf9a00c00, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12742 
12743         //----------------------------------------------------------------------
12744         // Store instructions
12745         //----------------------------------------------------------------------
12746         { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12747         { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
12748         { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12749         { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
12750         { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
12751         { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
12752         { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
12753         { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
12754         { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
12755         { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
12756         { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
12757         { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
12758         { 0xfffffe00, 0x00005200, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
12759         { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12760         { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
12761         { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
12762         { 0xfe100f00, 0xec000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12763         { 0xfea00f00, 0xec000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12764         { 0xff300f00, 0xed000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12765         { 0xff300f00, 0xed000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12766         { 0xffb00000, 0xfa000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12767         { 0xffb00300, 0xf9800000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12768 
12769         //----------------------------------------------------------------------
12770         // Other instructions
12771         //----------------------------------------------------------------------
12772         { 0xffffffc0, 0x0000b240, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
12773         { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12774         { 0xffffffc0, 0x0000b200, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
12775         { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12776         { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
12777         { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12778         { 0xffffffc0, 0x0000b280, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
12779         { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12780     };
12781 
12782     const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode);
12783     for (size_t i=0; i<k_num_thumb_opcodes; ++i)
12784     {
12785         if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
12786             (g_thumb_opcodes[i].variants & arm_isa) != 0)
12787             return &g_thumb_opcodes[i];
12788     }
12789     return NULL;
12790 }
12791 
12792 bool
12793 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
12794 {
12795     m_arch = arch;
12796     m_arm_isa = 0;
12797     const char *arch_cstr = arch.GetArchitectureName ();
12798     if (arch_cstr)
12799     {
12800         if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
12801         else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
12802         else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
12803         else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
12804         else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
12805         else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
12806         else if (0 == ::strcasecmp(arch_cstr, "armv7s"))    m_arm_isa = ARMv7S;
12807         else if (0 == ::strcasecmp(arch_cstr, "arm"))       m_arm_isa = ARMvAll;
12808         else if (0 == ::strcasecmp(arch_cstr, "thumb"))     m_arm_isa = ARMvAll;
12809         else if (0 == ::strncasecmp(arch_cstr,"armv4", 5))  m_arm_isa = ARMv4;
12810         else if (0 == ::strncasecmp(arch_cstr,"armv6", 5))  m_arm_isa = ARMv6;
12811         else if (0 == ::strncasecmp(arch_cstr,"armv7", 5))  m_arm_isa = ARMv7;
12812         else if (0 == ::strncasecmp(arch_cstr,"armv8", 5))  m_arm_isa = ARMv8;
12813     }
12814     return m_arm_isa != 0;
12815 }
12816 
12817 bool
12818 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
12819 {
12820     if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
12821     {
12822         if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
12823             m_opcode_mode = eModeThumb;
12824         else
12825         {
12826             AddressClass addr_class = inst_addr.GetAddressClass();
12827 
12828             if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
12829                 m_opcode_mode = eModeARM;
12830             else if (addr_class == eAddressClassCodeAlternateISA)
12831                 m_opcode_mode = eModeThumb;
12832             else
12833                 return false;
12834         }
12835         if (m_opcode_mode == eModeThumb)
12836             m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
12837         else
12838             m_opcode_cpsr = CPSR_MODE_USR;
12839         return true;
12840     }
12841     return false;
12842 }
12843 
12844 bool
12845 EmulateInstructionARM::ReadInstruction ()
12846 {
12847     bool success = false;
12848     m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
12849     if (success)
12850     {
12851         addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
12852         if (success)
12853         {
12854             Context read_inst_context;
12855             read_inst_context.type = eContextReadOpcode;
12856             read_inst_context.SetNoArgs ();
12857 
12858             if (m_opcode_cpsr & MASK_CPSR_T)
12859             {
12860                 m_opcode_mode = eModeThumb;
12861                 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
12862 
12863                 if (success)
12864                 {
12865                     if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
12866                     {
12867                         m_opcode.SetOpcode16 (thumb_opcode);
12868                     }
12869                     else
12870                     {
12871                         m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success));
12872                     }
12873                 }
12874             }
12875             else
12876             {
12877                 m_opcode_mode = eModeARM;
12878                 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success));
12879             }
12880         }
12881     }
12882     if (!success)
12883     {
12884         m_opcode_mode = eModeInvalid;
12885         m_addr = LLDB_INVALID_ADDRESS;
12886     }
12887     return success;
12888 }
12889 
12890 uint32_t
12891 EmulateInstructionARM::ArchVersion ()
12892 {
12893     return m_arm_isa;
12894 }
12895 
12896 bool
12897 EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional)
12898 {
12899    // If we are ignoring conditions, then always return true.
12900    // this allows us to iterate over disassembly code and still
12901    // emulate an instruction even if we don't have all the right
12902    // bits set in the CPSR register...
12903     if (m_ignore_conditions)
12904         return true;
12905 
12906     if (is_conditional)
12907         *is_conditional = true;
12908 
12909     const uint32_t cond = CurrentCond (opcode);
12910 
12911     if (cond == UINT32_MAX)
12912         return false;
12913 
12914     bool result = false;
12915     switch (UnsignedBits(cond, 3, 1))
12916     {
12917     case 0:
12918 		if (m_opcode_cpsr == 0)
12919 			result = true;
12920         else
12921             result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
12922 		break;
12923     case 1:
12924         if (m_opcode_cpsr == 0)
12925             result = true;
12926         else
12927             result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
12928 		break;
12929     case 2:
12930         if (m_opcode_cpsr == 0)
12931             result = true;
12932         else
12933             result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
12934 		break;
12935     case 3:
12936         if (m_opcode_cpsr == 0)
12937             result = true;
12938         else
12939             result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
12940 		break;
12941     case 4:
12942         if (m_opcode_cpsr == 0)
12943             result = true;
12944         else
12945             result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12946 		break;
12947     case 5:
12948         if (m_opcode_cpsr == 0)
12949             result = true;
12950         else
12951 		{
12952             bool n = (m_opcode_cpsr & MASK_CPSR_N);
12953             bool v = (m_opcode_cpsr & MASK_CPSR_V);
12954             result = n == v;
12955         }
12956         break;
12957     case 6:
12958         if (m_opcode_cpsr == 0)
12959             result = true;
12960         else
12961 		{
12962             bool n = (m_opcode_cpsr & MASK_CPSR_N);
12963             bool v = (m_opcode_cpsr & MASK_CPSR_V);
12964             result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12965         }
12966         break;
12967     case 7:
12968         // Always execute (cond == 0b1110, or the special 0b1111 which gives
12969         // opcodes different meanings, but always means execution happpens.
12970         if (is_conditional)
12971             *is_conditional = false;
12972         result = true;
12973         break;
12974     }
12975 
12976     if (cond & 1)
12977         result = !result;
12978     return result;
12979 }
12980 
12981 uint32_t
12982 EmulateInstructionARM::CurrentCond (const uint32_t opcode)
12983 {
12984     switch (m_opcode_mode)
12985     {
12986     default:
12987     case eModeInvalid:
12988         break;
12989 
12990     case eModeARM:
12991         return UnsignedBits(opcode, 31, 28);
12992 
12993     case eModeThumb:
12994         // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
12995         // 'cond' field of the encoding.
12996         {
12997             const uint32_t byte_size = m_opcode.GetByteSize();
12998             if (byte_size == 2)
12999             {
13000                 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f)
13001                     return Bits32(opcode, 11, 7);
13002             }
13003             else if (byte_size == 4)
13004             {
13005                 if (Bits32(opcode, 31, 27) == 0x1e &&
13006                     Bits32(opcode, 15, 14) == 0x02 &&
13007                     Bits32(opcode, 12, 12) == 0x00 &&
13008                     Bits32(opcode, 25, 22) <= 0x0d)
13009                 {
13010                     return Bits32(opcode, 25, 22);
13011                 }
13012             }
13013             else
13014                 // We have an invalid thumb instruction, let's bail out.
13015                 break;
13016 
13017             return m_it_session.GetCond();
13018         }
13019     }
13020     return UINT32_MAX;  // Return invalid value
13021 }
13022 
13023 bool
13024 EmulateInstructionARM::InITBlock()
13025 {
13026     return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13027 }
13028 
13029 bool
13030 EmulateInstructionARM::LastInITBlock()
13031 {
13032     return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13033 }
13034 
13035 bool
13036 EmulateInstructionARM::BadMode (uint32_t mode)
13037 {
13038 
13039     switch (mode)
13040     {
13041         case 16: return false; // '10000'
13042         case 17: return false; // '10001'
13043         case 18: return false; // '10010'
13044         case 19: return false; // '10011'
13045         case 22: return false; // '10110'
13046         case 23: return false; // '10111'
13047         case 27: return false; // '11011'
13048         case 31: return false; // '11111'
13049         default: return true;
13050     }
13051     return true;
13052 }
13053 
13054 bool
13055 EmulateInstructionARM::CurrentModeIsPrivileged ()
13056 {
13057     uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
13058 
13059     if (BadMode (mode))
13060         return false;
13061 
13062     if (mode == 16)
13063         return false;
13064 
13065     return true;
13066 }
13067 
13068 void
13069 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
13070 {
13071     bool privileged = CurrentModeIsPrivileged();
13072 
13073     uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20;
13074 
13075     if (BitIsSet (bytemask, 3))
13076     {
13077         tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
13078         if (affect_execstate)
13079             tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
13080     }
13081 
13082     if (BitIsSet (bytemask, 2))
13083     {
13084         tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
13085     }
13086 
13087     if (BitIsSet (bytemask, 1))
13088     {
13089         if (affect_execstate)
13090             tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
13091         tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
13092         if (privileged)
13093             tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
13094     }
13095 
13096     if (BitIsSet (bytemask, 0))
13097     {
13098         if (privileged)
13099             tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
13100         if (affect_execstate)
13101             tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
13102         if (privileged)
13103             tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
13104     }
13105 
13106     m_opcode_cpsr = tmp_cpsr;
13107 }
13108 
13109 
13110 bool
13111 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
13112 {
13113     addr_t target;
13114 
13115     // Check the current instruction set.
13116     if (CurrentInstrSet() == eModeARM)
13117         target = addr & 0xfffffffc;
13118     else
13119         target = addr & 0xfffffffe;
13120 
13121     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13122         return false;
13123 
13124     return true;
13125 }
13126 
13127 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
13128 bool
13129 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
13130 {
13131     addr_t target;
13132     // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
13133     // we want to record it and issue a WriteRegister callback so the clients
13134     // can track the mode changes accordingly.
13135     bool cpsr_changed = false;
13136 
13137     if (BitIsSet(addr, 0))
13138     {
13139         if (CurrentInstrSet() != eModeThumb)
13140         {
13141             SelectInstrSet(eModeThumb);
13142             cpsr_changed = true;
13143         }
13144         target = addr & 0xfffffffe;
13145         context.SetISA (eModeThumb);
13146     }
13147     else if (BitIsClear(addr, 1))
13148     {
13149         if (CurrentInstrSet() != eModeARM)
13150         {
13151             SelectInstrSet(eModeARM);
13152             cpsr_changed = true;
13153         }
13154         target = addr & 0xfffffffc;
13155         context.SetISA (eModeARM);
13156     }
13157     else
13158         return false; // address<1:0> == '10' => UNPREDICTABLE
13159 
13160     if (cpsr_changed)
13161     {
13162         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13163             return false;
13164     }
13165     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13166         return false;
13167 
13168     return true;
13169 }
13170 
13171 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
13172 bool
13173 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
13174 {
13175     if (ArchVersion() >= ARMv5T)
13176         return BXWritePC(context, addr);
13177     else
13178         return BranchWritePC((const Context)context, addr);
13179 }
13180 
13181 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
13182 bool
13183 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
13184 {
13185     if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
13186         return BXWritePC(context, addr);
13187     else
13188         return BranchWritePC((const Context)context, addr);
13189 }
13190 
13191 EmulateInstructionARM::Mode
13192 EmulateInstructionARM::CurrentInstrSet ()
13193 {
13194     return m_opcode_mode;
13195 }
13196 
13197 // Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
13198 // ReadInstruction() is performed.  This function has a side effect of updating
13199 // the m_new_inst_cpsr member variable if necessary.
13200 bool
13201 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
13202 {
13203     m_new_inst_cpsr = m_opcode_cpsr;
13204     switch (arm_or_thumb)
13205     {
13206     default:
13207         return false;
13208     case eModeARM:
13209         // Clear the T bit.
13210         m_new_inst_cpsr &= ~MASK_CPSR_T;
13211         break;
13212     case eModeThumb:
13213         // Set the T bit.
13214         m_new_inst_cpsr |= MASK_CPSR_T;
13215         break;
13216     }
13217     return true;
13218 }
13219 
13220 // This function returns TRUE if the processor currently provides support for
13221 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
13222 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
13223 bool
13224 EmulateInstructionARM::UnalignedSupport()
13225 {
13226     return (ArchVersion() >= ARMv7);
13227 }
13228 
13229 // The main addition and subtraction instructions can produce status information
13230 // about both unsigned carry and signed overflow conditions.  This status
13231 // information can be used to synthesize multi-word additions and subtractions.
13232 EmulateInstructionARM::AddWithCarryResult
13233 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
13234 {
13235     uint32_t result;
13236     uint8_t carry_out;
13237     uint8_t overflow;
13238 
13239     uint64_t unsigned_sum = x + y + carry_in;
13240     int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
13241 
13242     result = UnsignedBits(unsigned_sum, 31, 0);
13243 //    carry_out = (result == unsigned_sum ? 0 : 1);
13244     overflow = ((int32_t)result == signed_sum ? 0 : 1);
13245 
13246     if (carry_in)
13247         carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0;
13248     else
13249         carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0;
13250 
13251     AddWithCarryResult res = { result, carry_out, overflow };
13252     return res;
13253 }
13254 
13255 uint32_t
13256 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
13257 {
13258     uint32_t reg_kind, reg_num;
13259     switch (num)
13260     {
13261     case SP_REG:
13262         reg_kind = eRegisterKindGeneric;
13263         reg_num  = LLDB_REGNUM_GENERIC_SP;
13264         break;
13265     case LR_REG:
13266         reg_kind = eRegisterKindGeneric;
13267         reg_num  = LLDB_REGNUM_GENERIC_RA;
13268         break;
13269     case PC_REG:
13270         reg_kind = eRegisterKindGeneric;
13271         reg_num  = LLDB_REGNUM_GENERIC_PC;
13272         break;
13273     default:
13274         if (num < SP_REG)
13275         {
13276             reg_kind = eRegisterKindDWARF;
13277             reg_num  = dwarf_r0 + num;
13278         }
13279         else
13280         {
13281             //assert(0 && "Invalid register number");
13282             *success = false;
13283             return UINT32_MAX;
13284         }
13285         break;
13286     }
13287 
13288     // Read our register.
13289     uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
13290 
13291     // When executing an ARM instruction , PC reads as the address of the current
13292     // instruction plus 8.
13293     // When executing a Thumb instruction , PC reads as the address of the current
13294     // instruction plus 4.
13295     if (num == 15)
13296     {
13297         if (CurrentInstrSet() == eModeARM)
13298             val += 8;
13299         else
13300             val += 4;
13301     }
13302 
13303     return val;
13304 }
13305 
13306 // Write the result to the ARM core register Rd, and optionally update the
13307 // condition flags based on the result.
13308 //
13309 // This helper method tries to encapsulate the following pseudocode from the
13310 // ARM Architecture Reference Manual:
13311 //
13312 // if d == 15 then         // Can only occur for encoding A1
13313 //     ALUWritePC(result); // setflags is always FALSE here
13314 // else
13315 //     R[d] = result;
13316 //     if setflags then
13317 //         APSR.N = result<31>;
13318 //         APSR.Z = IsZeroBit(result);
13319 //         APSR.C = carry;
13320 //         // APSR.V unchanged
13321 //
13322 // In the above case, the API client does not pass in the overflow arg, which
13323 // defaults to ~0u.
13324 bool
13325 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
13326                                                   const uint32_t result,
13327                                                   const uint32_t Rd,
13328                                                   bool setflags,
13329                                                   const uint32_t carry,
13330                                                   const uint32_t overflow)
13331 {
13332     if (Rd == 15)
13333     {
13334         if (!ALUWritePC (context, result))
13335             return false;
13336     }
13337     else
13338     {
13339         uint32_t reg_kind, reg_num;
13340         switch (Rd)
13341         {
13342         case SP_REG:
13343             reg_kind = eRegisterKindGeneric;
13344             reg_num  = LLDB_REGNUM_GENERIC_SP;
13345             break;
13346         case LR_REG:
13347             reg_kind = eRegisterKindGeneric;
13348             reg_num  = LLDB_REGNUM_GENERIC_RA;
13349             break;
13350         default:
13351             reg_kind = eRegisterKindDWARF;
13352             reg_num  = dwarf_r0 + Rd;
13353         }
13354         if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
13355             return false;
13356         if (setflags)
13357             return WriteFlags (context, result, carry, overflow);
13358     }
13359     return true;
13360 }
13361 
13362 // This helper method tries to encapsulate the following pseudocode from the
13363 // ARM Architecture Reference Manual:
13364 //
13365 // APSR.N = result<31>;
13366 // APSR.Z = IsZeroBit(result);
13367 // APSR.C = carry;
13368 // APSR.V = overflow
13369 //
13370 // Default arguments can be specified for carry and overflow parameters, which means
13371 // not to update the respective flags.
13372 bool
13373 EmulateInstructionARM::WriteFlags (Context &context,
13374                                    const uint32_t result,
13375                                    const uint32_t carry,
13376                                    const uint32_t overflow)
13377 {
13378     m_new_inst_cpsr = m_opcode_cpsr;
13379     SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
13380     SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
13381     if (carry != ~0u)
13382         SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
13383     if (overflow != ~0u)
13384         SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
13385     if (m_new_inst_cpsr != m_opcode_cpsr)
13386     {
13387         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13388             return false;
13389     }
13390     return true;
13391 }
13392 
13393 bool
13394 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
13395 {
13396     // Advance the ITSTATE bits to their values for the next instruction.
13397     if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
13398         m_it_session.ITAdvance();
13399 
13400     ARMOpcode *opcode_data = NULL;
13401 
13402     if (m_opcode_mode == eModeThumb)
13403         opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13404     else if (m_opcode_mode == eModeARM)
13405         opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13406 
13407     if (opcode_data == NULL)
13408         return false;
13409 
13410     const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
13411     m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
13412 
13413     bool success = false;
13414     if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
13415     {
13416         m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF,
13417                                                 dwarf_cpsr,
13418                                                 0,
13419                                                 &success);
13420     }
13421 
13422     // Only return false if we are unable to read the CPSR if we care about conditions
13423     if (success == false && m_ignore_conditions == false)
13424         return false;
13425 
13426     uint32_t orig_pc_value = 0;
13427     if (auto_advance_pc)
13428     {
13429         orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13430         if (!success)
13431             return false;
13432     }
13433 
13434     // Call the Emulate... function.
13435     success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
13436     if (!success)
13437         return false;
13438 
13439     if (auto_advance_pc)
13440     {
13441         uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13442         if (!success)
13443             return false;
13444 
13445         if (auto_advance_pc && (after_pc_value == orig_pc_value))
13446         {
13447             if (opcode_data->size == eSize32)
13448                 after_pc_value += 4;
13449             else if (opcode_data->size == eSize16)
13450                 after_pc_value += 2;
13451 
13452             EmulateInstruction::Context context;
13453             context.type = eContextAdvancePC;
13454             context.SetNoArgs();
13455             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
13456                 return false;
13457 
13458         }
13459     }
13460     return true;
13461 }
13462 
13463 bool
13464 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data)
13465 {
13466     if (!test_data)
13467     {
13468         out_stream->Printf ("TestEmulation: Missing test data.\n");
13469         return false;
13470     }
13471 
13472     static ConstString opcode_key ("opcode");
13473     static ConstString before_key ("before_state");
13474     static ConstString after_key ("after_state");
13475 
13476     OptionValueSP value_sp = test_data->GetValueForKey (opcode_key);
13477 
13478     uint32_t test_opcode;
13479     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64))
13480     {
13481         out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n");
13482         return false;
13483     }
13484     test_opcode = value_sp->GetUInt64Value ();
13485 
13486     if (arch.GetTriple().getArch() == llvm::Triple::arm)
13487     {
13488         m_opcode_mode = eModeARM;
13489         m_opcode.SetOpcode32 (test_opcode);
13490     }
13491     else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
13492     {
13493         m_opcode_mode = eModeThumb;
13494         if (test_opcode < 0x10000)
13495             m_opcode.SetOpcode16 (test_opcode);
13496         else
13497             m_opcode.SetOpcode32 (test_opcode);
13498 
13499     }
13500     else
13501     {
13502         out_stream->Printf ("TestEmulation:  Invalid arch.\n");
13503         return false;
13504     }
13505 
13506     EmulationStateARM before_state;
13507     EmulationStateARM after_state;
13508 
13509     value_sp = test_data->GetValueForKey (before_key);
13510     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13511     {
13512         out_stream->Printf ("TestEmulation:  Failed to find 'before' state.\n");
13513         return false;
13514     }
13515 
13516     OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary ();
13517     if (!before_state.LoadStateFromDictionary (state_dictionary))
13518     {
13519         out_stream->Printf ("TestEmulation:  Failed loading 'before' state.\n");
13520         return false;
13521     }
13522 
13523     value_sp = test_data->GetValueForKey (after_key);
13524     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13525     {
13526         out_stream->Printf ("TestEmulation:  Failed to find 'after' state.\n");
13527         return false;
13528     }
13529 
13530     state_dictionary = value_sp->GetAsDictionary ();
13531     if (!after_state.LoadStateFromDictionary (state_dictionary))
13532     {
13533         out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n");
13534         return false;
13535     }
13536 
13537     SetBaton ((void *) &before_state);
13538     SetCallbacks (&EmulationStateARM::ReadPseudoMemory,
13539                   &EmulationStateARM::WritePseudoMemory,
13540                   &EmulationStateARM::ReadPseudoRegister,
13541                   &EmulationStateARM::WritePseudoRegister);
13542 
13543     bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC);
13544     if (!success)
13545     {
13546         out_stream->Printf ("TestEmulation:  EvaluateInstruction() failed.\n");
13547         return false;
13548     }
13549 
13550     success = before_state.CompareState (after_state);
13551     if (!success)
13552         out_stream->Printf ("TestEmulation:  'before' and 'after' states do not match.\n");
13553 
13554     return success;
13555 }
13556 //
13557 //
13558 //const char *
13559 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
13560 //{
13561 //    if (reg_kind == eRegisterKindGeneric)
13562 //    {
13563 //        switch (reg_num)
13564 //        {
13565 //        case LLDB_REGNUM_GENERIC_PC:    return "pc";
13566 //        case LLDB_REGNUM_GENERIC_SP:    return "sp";
13567 //        case LLDB_REGNUM_GENERIC_FP:    return "fp";
13568 //        case LLDB_REGNUM_GENERIC_RA:    return "lr";
13569 //        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
13570 //        default: return NULL;
13571 //        }
13572 //    }
13573 //    else if (reg_kind == eRegisterKindDWARF)
13574 //    {
13575 //        return GetARMDWARFRegisterName (reg_num);
13576 //    }
13577 //    return NULL;
13578 //}
13579 //
13580 bool
13581 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
13582 {
13583     unwind_plan.Clear();
13584     unwind_plan.SetRegisterKind (eRegisterKindDWARF);
13585 
13586     UnwindPlan::Row row;
13587 
13588     // Our previous Call Frame Address is the stack pointer
13589     row.SetCFARegister (dwarf_sp);
13590 
13591     // Our previous PC is in the LR
13592     row.SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true);
13593     unwind_plan.AppendRow (row);
13594 
13595     // All other registers are the same.
13596 
13597     unwind_plan.SetSourceName ("EmulateInstructionARM");
13598     return true;
13599 }
13600 
13601 
13602 
13603 
13604