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 = false; // Add this back if/when support eEncodingT3 eEncodingA1
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                 imm32 = (Bits32 (opcode, 7, 0) << 2);
1305 
1306                 break;
1307 
1308             case eEncodingT2:
1309                 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1310                 d = 13;
1311                 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1312 
1313                 break;
1314 
1315             default:
1316                 return false;
1317         }
1318         addr_t sp_offset = imm32;
1319         addr_t addr = sp + sp_offset; // the adjusted stack pointer value
1320 
1321         EmulateInstruction::Context context;
1322         context.type = EmulateInstruction::eContextAdjustStackPointer;
1323         RegisterInfo sp_reg;
1324         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1325         context.SetRegisterPlusOffset (sp_reg, sp_offset);
1326 
1327         if (d == 15)
1328         {
1329             if (!ALUWritePC (context, addr))
1330                 return false;
1331         }
1332         else
1333         {
1334             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr))
1335                 return false;
1336 
1337             // Add this back if/when support eEncodingT3 eEncodingA1
1338             //if (setflags)
1339             //{
1340             //    APSR.N = result<31>;
1341             //    APSR.Z = IsZeroBit(result);
1342             //    APSR.C = carry;
1343             //    APSR.V = overflow;
1344             //}
1345         }
1346     }
1347     return true;
1348 }
1349 
1350 // An add operation to adjust the SP.
1351 // ADD (SP plus register)
1352 bool
1353 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding)
1354 {
1355 #if 0
1356     // ARM pseudo code...
1357     if (ConditionPassed())
1358     {
1359         EncodingSpecificOperations();
1360         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1361         (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1362         if d == 15 then
1363             ALUWritePC(result); // setflags is always FALSE here
1364         else
1365             R[d] = result;
1366             if setflags then
1367                 APSR.N = result<31>;
1368                 APSR.Z = IsZeroBit(result);
1369                 APSR.C = carry;
1370                 APSR.V = overflow;
1371     }
1372 #endif
1373 
1374     bool success = false;
1375 
1376     if (ConditionPassed(opcode))
1377     {
1378         const addr_t sp = ReadCoreReg (SP_REG, &success);
1379         if (!success)
1380             return false;
1381         uint32_t Rm; // the second operand
1382         switch (encoding) {
1383         case eEncodingT2:
1384             Rm = Bits32(opcode, 6, 3);
1385             break;
1386         default:
1387             return false;
1388         }
1389         int32_t reg_value = ReadCoreReg(Rm, &success);
1390         if (!success)
1391             return false;
1392 
1393         addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1394 
1395         EmulateInstruction::Context context;
1396         context.type = eContextArithmetic;
1397         RegisterInfo sp_reg;
1398         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1399 
1400         RegisterInfo other_reg;
1401         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1402         context.SetRegisterRegisterOperands (sp_reg, other_reg);
1403 
1404         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
1405             return false;
1406     }
1407     return true;
1408 }
1409 
1410 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
1411 // at a PC-relative address, and changes instruction set from ARM to Thumb, or
1412 // from Thumb to ARM.
1413 // BLX (immediate)
1414 bool
1415 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding)
1416 {
1417 #if 0
1418     // ARM pseudo code...
1419     if (ConditionPassed())
1420     {
1421         EncodingSpecificOperations();
1422         if CurrentInstrSet() == InstrSet_ARM then
1423             LR = PC - 4;
1424         else
1425             LR = PC<31:1> : '1';
1426         if targetInstrSet == InstrSet_ARM then
1427             targetAddress = Align(PC,4) + imm32;
1428         else
1429             targetAddress = PC + imm32;
1430         SelectInstrSet(targetInstrSet);
1431         BranchWritePC(targetAddress);
1432     }
1433 #endif
1434 
1435     bool success = true;
1436 
1437     if (ConditionPassed(opcode))
1438     {
1439         EmulateInstruction::Context context;
1440         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1441         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1442         if (!success)
1443             return false;
1444         addr_t lr; // next instruction address
1445         addr_t target; // target address
1446         int32_t imm32; // PC-relative offset
1447         switch (encoding) {
1448         case eEncodingT1:
1449             {
1450             lr = pc | 1u; // return address
1451             uint32_t S = Bit32(opcode, 26);
1452             uint32_t imm10 = Bits32(opcode, 25, 16);
1453             uint32_t J1 = Bit32(opcode, 13);
1454             uint32_t J2 = Bit32(opcode, 11);
1455             uint32_t imm11 = Bits32(opcode, 10, 0);
1456             uint32_t I1 = !(J1 ^ S);
1457             uint32_t I2 = !(J2 ^ S);
1458             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1459             imm32 = llvm::SignExtend32<25>(imm25);
1460             target = pc + imm32;
1461             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
1462             if (InITBlock() && !LastInITBlock())
1463                 return false;
1464             break;
1465             }
1466         case eEncodingT2:
1467             {
1468             lr = pc | 1u; // return address
1469             uint32_t S = Bit32(opcode, 26);
1470             uint32_t imm10H = Bits32(opcode, 25, 16);
1471             uint32_t J1 = Bit32(opcode, 13);
1472             uint32_t J2 = Bit32(opcode, 11);
1473             uint32_t imm10L = Bits32(opcode, 10, 1);
1474             uint32_t I1 = !(J1 ^ S);
1475             uint32_t I2 = !(J2 ^ S);
1476             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
1477             imm32 = llvm::SignExtend32<25>(imm25);
1478             target = Align(pc, 4) + imm32;
1479             context.SetISAAndImmediateSigned (eModeARM, 4 + imm32);
1480             if (InITBlock() && !LastInITBlock())
1481                 return false;
1482             break;
1483             }
1484         case eEncodingA1:
1485             lr = pc - 4; // return address
1486             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1487             target = Align(pc, 4) + imm32;
1488             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
1489             break;
1490         case eEncodingA2:
1491             lr = pc - 4; // return address
1492             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
1493             target = pc + imm32;
1494             context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32);
1495             break;
1496         default:
1497             return false;
1498         }
1499         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1500             return false;
1501         if (!BranchWritePC(context, target))
1502             return false;
1503     }
1504     return true;
1505 }
1506 
1507 // Branch with Link and Exchange (register) calls a subroutine at an address and
1508 // instruction set specified by a register.
1509 // BLX (register)
1510 bool
1511 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding)
1512 {
1513 #if 0
1514     // ARM pseudo code...
1515     if (ConditionPassed())
1516     {
1517         EncodingSpecificOperations();
1518         target = R[m];
1519         if CurrentInstrSet() == InstrSet_ARM then
1520             next_instr_addr = PC - 4;
1521             LR = next_instr_addr;
1522         else
1523             next_instr_addr = PC - 2;
1524             LR = next_instr_addr<31:1> : '1';
1525         BXWritePC(target);
1526     }
1527 #endif
1528 
1529     bool success = false;
1530 
1531     if (ConditionPassed(opcode))
1532     {
1533         EmulateInstruction::Context context;
1534         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1535         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1536         addr_t lr; // next instruction address
1537         if (!success)
1538             return false;
1539         uint32_t Rm; // the register with the target address
1540         switch (encoding) {
1541         case eEncodingT1:
1542             lr = (pc - 2) | 1u; // return address
1543             Rm = Bits32(opcode, 6, 3);
1544             // if m == 15 then UNPREDICTABLE;
1545             if (Rm == 15)
1546                 return false;
1547             if (InITBlock() && !LastInITBlock())
1548                 return false;
1549             break;
1550         case eEncodingA1:
1551             lr = pc - 4; // return address
1552             Rm = Bits32(opcode, 3, 0);
1553             // if m == 15 then UNPREDICTABLE;
1554             if (Rm == 15)
1555                 return false;
1556             break;
1557         default:
1558             return false;
1559         }
1560         addr_t target = ReadCoreReg (Rm, &success);
1561         if (!success)
1562             return false;
1563         RegisterInfo dwarf_reg;
1564         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1565         context.SetRegister (dwarf_reg);
1566         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1567             return false;
1568         if (!BXWritePC(context, target))
1569             return false;
1570     }
1571     return true;
1572 }
1573 
1574 // Branch and Exchange causes a branch to an address and instruction set specified by a register.
1575 bool
1576 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding)
1577 {
1578 #if 0
1579     // ARM pseudo code...
1580     if (ConditionPassed())
1581     {
1582         EncodingSpecificOperations();
1583         BXWritePC(R[m]);
1584     }
1585 #endif
1586 
1587     if (ConditionPassed(opcode))
1588     {
1589         EmulateInstruction::Context context;
1590         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1591         uint32_t Rm; // the register with the target address
1592         switch (encoding) {
1593         case eEncodingT1:
1594             Rm = Bits32(opcode, 6, 3);
1595             if (InITBlock() && !LastInITBlock())
1596                 return false;
1597             break;
1598         case eEncodingA1:
1599             Rm = Bits32(opcode, 3, 0);
1600             break;
1601         default:
1602             return false;
1603         }
1604         bool success = false;
1605         addr_t target = ReadCoreReg (Rm, &success);
1606         if (!success)
1607             return false;
1608 
1609         RegisterInfo dwarf_reg;
1610         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1611         context.SetRegister (dwarf_reg);
1612         if (!BXWritePC(context, target))
1613             return false;
1614     }
1615     return true;
1616 }
1617 
1618 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an
1619 // address and instruction set specified by a register as though it were a BX instruction.
1620 //
1621 // TODO: Emulate Jazelle architecture?
1622 //       We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation.
1623 bool
1624 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding)
1625 {
1626 #if 0
1627     // ARM pseudo code...
1628     if (ConditionPassed())
1629     {
1630         EncodingSpecificOperations();
1631         if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
1632             BXWritePC(R[m]);
1633         else
1634             if JazelleAcceptsExecution() then
1635                 SwitchToJazelleExecution();
1636             else
1637                 SUBARCHITECTURE_DEFINED handler call;
1638     }
1639 #endif
1640 
1641     if (ConditionPassed(opcode))
1642     {
1643         EmulateInstruction::Context context;
1644         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1645         uint32_t Rm; // the register with the target address
1646         switch (encoding) {
1647         case eEncodingT1:
1648             Rm = Bits32(opcode, 19, 16);
1649             if (BadReg(Rm))
1650                 return false;
1651             if (InITBlock() && !LastInITBlock())
1652                 return false;
1653             break;
1654         case eEncodingA1:
1655             Rm = Bits32(opcode, 3, 0);
1656             if (Rm == 15)
1657                 return false;
1658             break;
1659         default:
1660             return false;
1661         }
1662         bool success = false;
1663         addr_t target = ReadCoreReg (Rm, &success);
1664         if (!success)
1665             return false;
1666 
1667         RegisterInfo dwarf_reg;
1668         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1669         context.SetRegister (dwarf_reg);
1670         if (!BXWritePC(context, target))
1671             return false;
1672     }
1673     return true;
1674 }
1675 
1676 // Set r7 to point to some ip offset.
1677 // SUB (immediate)
1678 bool
1679 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding)
1680 {
1681 #if 0
1682     // ARM pseudo code...
1683     if (ConditionPassed())
1684     {
1685         EncodingSpecificOperations();
1686         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1687         if d == 15 then // Can only occur for ARM encoding
1688            ALUWritePC(result); // setflags is always FALSE here
1689         else
1690             R[d] = result;
1691             if setflags then
1692                 APSR.N = result<31>;
1693                 APSR.Z = IsZeroBit(result);
1694                 APSR.C = carry;
1695                 APSR.V = overflow;
1696     }
1697 #endif
1698 
1699     if (ConditionPassed(opcode))
1700     {
1701         bool success = false;
1702         const addr_t ip = ReadCoreReg (12, &success);
1703         if (!success)
1704             return false;
1705         uint32_t imm32;
1706         switch (encoding) {
1707         case eEncodingA1:
1708             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1709             break;
1710         default:
1711             return false;
1712         }
1713         addr_t ip_offset = imm32;
1714         addr_t addr = ip - ip_offset; // the adjusted ip value
1715 
1716         EmulateInstruction::Context context;
1717         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1718         RegisterInfo dwarf_reg;
1719         GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg);
1720         context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
1721 
1722         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
1723             return false;
1724     }
1725     return true;
1726 }
1727 
1728 // Set ip to point to some stack offset.
1729 // SUB (SP minus immediate)
1730 bool
1731 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding)
1732 {
1733 #if 0
1734     // ARM pseudo code...
1735     if (ConditionPassed())
1736     {
1737         EncodingSpecificOperations();
1738         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1739         if d == 15 then // Can only occur for ARM encoding
1740            ALUWritePC(result); // setflags is always FALSE here
1741         else
1742             R[d] = result;
1743             if setflags then
1744                 APSR.N = result<31>;
1745                 APSR.Z = IsZeroBit(result);
1746                 APSR.C = carry;
1747                 APSR.V = overflow;
1748     }
1749 #endif
1750 
1751     if (ConditionPassed(opcode))
1752     {
1753         bool success = false;
1754         const addr_t sp = ReadCoreReg (SP_REG, &success);
1755         if (!success)
1756             return false;
1757         uint32_t imm32;
1758         switch (encoding) {
1759         case eEncodingA1:
1760             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1761             break;
1762         default:
1763             return false;
1764         }
1765         addr_t sp_offset = imm32;
1766         addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1767 
1768         EmulateInstruction::Context context;
1769         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1770         RegisterInfo dwarf_reg;
1771         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
1772         context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
1773 
1774         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
1775             return false;
1776     }
1777     return true;
1778 }
1779 
1780 // This instruction subtracts an immediate value from the SP value, and writes
1781 // the result to the destination register.
1782 //
1783 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage.
1784 bool
1785 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding)
1786 {
1787 #if 0
1788     // ARM pseudo code...
1789     if (ConditionPassed())
1790     {
1791         EncodingSpecificOperations();
1792         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1793         if d == 15 then        // Can only occur for ARM encoding
1794            ALUWritePC(result); // setflags is always FALSE here
1795         else
1796             R[d] = result;
1797             if setflags then
1798                 APSR.N = result<31>;
1799                 APSR.Z = IsZeroBit(result);
1800                 APSR.C = carry;
1801                 APSR.V = overflow;
1802     }
1803 #endif
1804 
1805     bool success = false;
1806     if (ConditionPassed(opcode))
1807     {
1808         const addr_t sp = ReadCoreReg (SP_REG, &success);
1809         if (!success)
1810             return false;
1811 
1812         uint32_t Rd;
1813         bool setflags;
1814         uint32_t imm32;
1815         switch (encoding) {
1816         case eEncodingT1:
1817             Rd = 13;
1818             setflags = false;
1819             imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1820             break;
1821         case eEncodingT2:
1822             Rd = Bits32(opcode, 11, 8);
1823             setflags = BitIsSet(opcode, 20);
1824             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1825             if (Rd == 15 && setflags)
1826                 return EmulateCMPImm(opcode, eEncodingT2);
1827             if (Rd == 15 && !setflags)
1828                 return false;
1829             break;
1830         case eEncodingT3:
1831             Rd = Bits32(opcode, 11, 8);
1832             setflags = false;
1833             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
1834             if (Rd == 15)
1835                 return false;
1836             break;
1837         case eEncodingA1:
1838             Rd = Bits32(opcode, 15, 12);
1839             setflags = BitIsSet(opcode, 20);
1840             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1841 
1842             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1843             if (Rd == 15 && setflags)
1844                 return EmulateSUBSPcLrEtc (opcode, encoding);
1845             break;
1846         default:
1847             return false;
1848         }
1849         AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
1850 
1851         EmulateInstruction::Context context;
1852         if (Rd == 13)
1853         {
1854             uint64_t imm64 = imm32;  // Need to expand it to 64 bits before attempting to negate it, or the wrong
1855                                      // value gets passed down to context.SetImmediateSigned.
1856             context.type = EmulateInstruction::eContextAdjustStackPointer;
1857             context.SetImmediateSigned (-imm64); // the stack pointer offset
1858         }
1859         else
1860         {
1861             context.type = EmulateInstruction::eContextImmediate;
1862             context.SetNoArgs ();
1863         }
1864 
1865         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
1866             return false;
1867     }
1868     return true;
1869 }
1870 
1871 // A store operation to the stack that also updates the SP.
1872 bool
1873 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding)
1874 {
1875 #if 0
1876     // ARM pseudo code...
1877     if (ConditionPassed())
1878     {
1879         EncodingSpecificOperations();
1880         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1881         address = if index then offset_addr else R[n];
1882         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1883         if wback then R[n] = offset_addr;
1884     }
1885 #endif
1886 
1887     bool conditional = false;
1888     bool success = false;
1889     if (ConditionPassed(opcode, &conditional))
1890     {
1891         const uint32_t addr_byte_size = GetAddressByteSize();
1892         const addr_t sp = ReadCoreReg (SP_REG, &success);
1893         if (!success)
1894             return false;
1895         uint32_t Rt; // the source register
1896         uint32_t imm12;
1897         uint32_t Rn;  // This function assumes Rn is the SP, but we should verify that.
1898 
1899         bool index;
1900         bool add;
1901         bool wback;
1902         switch (encoding) {
1903         case eEncodingA1:
1904             Rt = Bits32(opcode, 15, 12);
1905             imm12 = Bits32(opcode, 11, 0);
1906             Rn = Bits32 (opcode, 19, 16);
1907 
1908             if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
1909                 return false;
1910 
1911             index = BitIsSet (opcode, 24);
1912             add = BitIsSet (opcode, 23);
1913             wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
1914 
1915             if (wback && ((Rn == 15) || (Rn == Rt)))
1916                 return false;
1917             break;
1918         default:
1919             return false;
1920         }
1921         addr_t offset_addr;
1922         if (add)
1923             offset_addr = sp + imm12;
1924         else
1925             offset_addr = sp - imm12;
1926 
1927         addr_t addr;
1928         if (index)
1929             addr = offset_addr;
1930         else
1931             addr = sp;
1932 
1933         EmulateInstruction::Context context;
1934         if (conditional)
1935             context.type = EmulateInstruction::eContextRegisterStore;
1936         else
1937             context.type = EmulateInstruction::eContextPushRegisterOnStack;
1938         RegisterInfo sp_reg;
1939         RegisterInfo dwarf_reg;
1940 
1941         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1942         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
1943         context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
1944         if (Rt != 15)
1945         {
1946             uint32_t reg_value = ReadCoreReg(Rt, &success);
1947             if (!success)
1948                 return false;
1949             if (!MemUWrite (context, addr, reg_value, addr_byte_size))
1950                 return false;
1951         }
1952         else
1953         {
1954             const uint32_t pc = ReadCoreReg(PC_REG, &success);
1955             if (!success)
1956                 return false;
1957             if (!MemUWrite (context, addr, pc, addr_byte_size))
1958                 return false;
1959         }
1960 
1961 
1962         if (wback)
1963         {
1964             context.type = EmulateInstruction::eContextAdjustStackPointer;
1965             context.SetImmediateSigned (addr - sp);
1966             if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr))
1967                 return false;
1968         }
1969     }
1970     return true;
1971 }
1972 
1973 // Vector Push stores multiple extension registers to the stack.
1974 // It also updates SP to point to the start of the stored data.
1975 bool
1976 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding)
1977 {
1978 #if 0
1979     // ARM pseudo code...
1980     if (ConditionPassed())
1981     {
1982         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1983         address = SP - imm32;
1984         SP = SP - imm32;
1985         if single_regs then
1986             for r = 0 to regs-1
1987                 MemA[address,4] = S[d+r]; address = address+4;
1988         else
1989             for r = 0 to regs-1
1990                 // Store as two word-aligned words in the correct order for current endianness.
1991                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
1992                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
1993                 address = address+8;
1994     }
1995 #endif
1996 
1997     bool success = false;
1998     bool conditional = false;
1999     if (ConditionPassed(opcode, &conditional))
2000     {
2001         const uint32_t addr_byte_size = GetAddressByteSize();
2002         const addr_t sp = ReadCoreReg (SP_REG, &success);
2003         if (!success)
2004             return false;
2005         bool single_regs;
2006         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2007         uint32_t imm32; // stack offset
2008         uint32_t regs;  // number of registers
2009         switch (encoding) {
2010         case eEncodingT1:
2011         case eEncodingA1:
2012             single_regs = false;
2013             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2014             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2015             // If UInt(imm8) is odd, see "FSTMX".
2016             regs = Bits32(opcode, 7, 0) / 2;
2017             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2018             if (regs == 0 || regs > 16 || (d + regs) > 32)
2019                 return false;
2020             break;
2021         case eEncodingT2:
2022         case eEncodingA2:
2023             single_regs = true;
2024             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2025             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2026             regs = Bits32(opcode, 7, 0);
2027             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2028             if (regs == 0 || regs > 16 || (d + regs) > 32)
2029                 return false;
2030             break;
2031         default:
2032             return false;
2033         }
2034         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2035         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2036         addr_t sp_offset = imm32;
2037         addr_t addr = sp - sp_offset;
2038         uint32_t i;
2039 
2040         EmulateInstruction::Context context;
2041         if (conditional)
2042             context.type = EmulateInstruction::eContextRegisterStore;
2043         else
2044             context.type = EmulateInstruction::eContextPushRegisterOnStack;
2045         RegisterInfo dwarf_reg;
2046         RegisterInfo sp_reg;
2047         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2048         for (i=0; i<regs; ++i)
2049         {
2050             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2051             context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
2052             // uint64_t to accommodate 64-bit registers.
2053             uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success);
2054             if (!success)
2055                 return false;
2056             if (!MemAWrite (context, addr, reg_value, reg_byte_size))
2057                 return false;
2058             addr += reg_byte_size;
2059         }
2060 
2061         context.type = EmulateInstruction::eContextAdjustStackPointer;
2062         context.SetImmediateSigned (-sp_offset);
2063 
2064         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2065             return false;
2066     }
2067     return true;
2068 }
2069 
2070 // Vector Pop loads multiple extension registers from the stack.
2071 // It also updates SP to point just above the loaded data.
2072 bool
2073 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding)
2074 {
2075 #if 0
2076     // ARM pseudo code...
2077     if (ConditionPassed())
2078     {
2079         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2080         address = SP;
2081         SP = SP + imm32;
2082         if single_regs then
2083             for r = 0 to regs-1
2084                 S[d+r] = MemA[address,4]; address = address+4;
2085         else
2086             for r = 0 to regs-1
2087                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2088                 // Combine the word-aligned words in the correct order for current endianness.
2089                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2090     }
2091 #endif
2092 
2093     bool success = false;
2094     bool conditional = false;
2095     if (ConditionPassed(opcode, &conditional))
2096     {
2097         const uint32_t addr_byte_size = GetAddressByteSize();
2098         const addr_t sp = ReadCoreReg (SP_REG, &success);
2099         if (!success)
2100             return false;
2101         bool single_regs;
2102         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2103         uint32_t imm32; // stack offset
2104         uint32_t regs;  // number of registers
2105         switch (encoding) {
2106         case eEncodingT1:
2107         case eEncodingA1:
2108             single_regs = false;
2109             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2110             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2111             // If UInt(imm8) is odd, see "FLDMX".
2112             regs = Bits32(opcode, 7, 0) / 2;
2113             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2114             if (regs == 0 || regs > 16 || (d + regs) > 32)
2115                 return false;
2116             break;
2117         case eEncodingT2:
2118         case eEncodingA2:
2119             single_regs = true;
2120             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2121             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2122             regs = Bits32(opcode, 7, 0);
2123             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2124             if (regs == 0 || regs > 16 || (d + regs) > 32)
2125                 return false;
2126             break;
2127         default:
2128             return false;
2129         }
2130         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2131         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2132         addr_t sp_offset = imm32;
2133         addr_t addr = sp;
2134         uint32_t i;
2135         uint64_t data; // uint64_t to accomodate 64-bit registers.
2136 
2137         EmulateInstruction::Context context;
2138         if (conditional)
2139             context.type = EmulateInstruction::eContextRegisterLoad;
2140         else
2141             context.type = EmulateInstruction::eContextPopRegisterOffStack;
2142         RegisterInfo dwarf_reg;
2143         RegisterInfo sp_reg;
2144         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2145         for (i=0; i<regs; ++i)
2146         {
2147             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2148             context.SetRegisterPlusOffset (sp_reg, addr - sp);
2149             data = MemARead(context, addr, reg_byte_size, 0, &success);
2150             if (!success)
2151                 return false;
2152             if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2153                 return false;
2154             addr += reg_byte_size;
2155         }
2156 
2157         context.type = EmulateInstruction::eContextAdjustStackPointer;
2158         context.SetImmediateSigned (sp_offset);
2159 
2160         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2161             return false;
2162     }
2163     return true;
2164 }
2165 
2166 // SVC (previously SWI)
2167 bool
2168 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding)
2169 {
2170 #if 0
2171     // ARM pseudo code...
2172     if (ConditionPassed())
2173     {
2174         EncodingSpecificOperations();
2175         CallSupervisor();
2176     }
2177 #endif
2178 
2179     bool success = false;
2180 
2181     if (ConditionPassed(opcode))
2182     {
2183         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2184         addr_t lr; // next instruction address
2185         if (!success)
2186             return false;
2187         uint32_t imm32; // the immediate constant
2188         uint32_t mode;  // ARM or Thumb mode
2189         switch (encoding) {
2190         case eEncodingT1:
2191             lr = (pc + 2) | 1u; // return address
2192             imm32 = Bits32(opcode, 7, 0);
2193             mode = eModeThumb;
2194             break;
2195         case eEncodingA1:
2196             lr = pc + 4; // return address
2197             imm32 = Bits32(opcode, 23, 0);
2198             mode = eModeARM;
2199             break;
2200         default:
2201             return false;
2202         }
2203 
2204         EmulateInstruction::Context context;
2205         context.type = EmulateInstruction::eContextSupervisorCall;
2206         context.SetISAAndImmediate (mode, imm32);
2207         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
2208             return false;
2209     }
2210     return true;
2211 }
2212 
2213 // If Then makes up to four following instructions (the IT block) conditional.
2214 bool
2215 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding)
2216 {
2217 #if 0
2218     // ARM pseudo code...
2219     EncodingSpecificOperations();
2220     ITSTATE.IT<7:0> = firstcond:mask;
2221 #endif
2222 
2223     m_it_session.InitIT(Bits32(opcode, 7, 0));
2224     return true;
2225 }
2226 
2227 bool
2228 EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding)
2229 {
2230     // NOP, nothing to do...
2231     return true;
2232 }
2233 
2234 // Branch causes a branch to a target address.
2235 bool
2236 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding)
2237 {
2238 #if 0
2239     // ARM pseudo code...
2240     if (ConditionPassed())
2241     {
2242         EncodingSpecificOperations();
2243         BranchWritePC(PC + imm32);
2244     }
2245 #endif
2246 
2247     bool success = false;
2248 
2249     if (ConditionPassed(opcode))
2250     {
2251         EmulateInstruction::Context context;
2252         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2253         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2254         if (!success)
2255             return false;
2256         addr_t target; // target address
2257         int32_t imm32; // PC-relative offset
2258         switch (encoding) {
2259         case eEncodingT1:
2260             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2261             imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2262             target = pc + imm32;
2263             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2264             break;
2265         case eEncodingT2:
2266             imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0));
2267             target = pc + imm32;
2268             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2269             break;
2270         case eEncodingT3:
2271             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2272             {
2273             uint32_t S = Bit32(opcode, 26);
2274             uint32_t imm6 = Bits32(opcode, 21, 16);
2275             uint32_t J1 = Bit32(opcode, 13);
2276             uint32_t J2 = Bit32(opcode, 11);
2277             uint32_t imm11 = Bits32(opcode, 10, 0);
2278             uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2279             imm32 = llvm::SignExtend32<21>(imm21);
2280             target = pc + imm32;
2281             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2282             break;
2283             }
2284         case eEncodingT4:
2285             {
2286             uint32_t S = Bit32(opcode, 26);
2287             uint32_t imm10 = Bits32(opcode, 25, 16);
2288             uint32_t J1 = Bit32(opcode, 13);
2289             uint32_t J2 = Bit32(opcode, 11);
2290             uint32_t imm11 = Bits32(opcode, 10, 0);
2291             uint32_t I1 = !(J1 ^ S);
2292             uint32_t I2 = !(J2 ^ S);
2293             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2294             imm32 = llvm::SignExtend32<25>(imm25);
2295             target = pc + imm32;
2296             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2297             break;
2298             }
2299         case eEncodingA1:
2300             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2301             target = pc + imm32;
2302             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
2303             break;
2304         default:
2305             return false;
2306         }
2307         if (!BranchWritePC(context, target))
2308             return false;
2309     }
2310     return true;
2311 }
2312 
2313 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
2314 // zero and conditionally branch forward a constant value.  They do not affect the condition flags.
2315 // CBNZ, CBZ
2316 bool
2317 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding)
2318 {
2319 #if 0
2320     // ARM pseudo code...
2321     EncodingSpecificOperations();
2322     if nonzero ^ IsZero(R[n]) then
2323         BranchWritePC(PC + imm32);
2324 #endif
2325 
2326     bool success = false;
2327 
2328     // Read the register value from the operand register Rn.
2329     uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2330     if (!success)
2331         return false;
2332 
2333     EmulateInstruction::Context context;
2334     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2335     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2336     if (!success)
2337         return false;
2338 
2339     addr_t target;  // target address
2340     uint32_t imm32; // PC-relative offset to branch forward
2341     bool nonzero;
2342     switch (encoding) {
2343     case eEncodingT1:
2344         imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2345         nonzero = BitIsSet(opcode, 11);
2346         target = pc + imm32;
2347         context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2348         break;
2349     default:
2350         return false;
2351     }
2352     if (nonzero ^ (reg_val == 0))
2353         if (!BranchWritePC(context, target))
2354             return false;
2355 
2356     return true;
2357 }
2358 
2359 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
2360 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2361 // The branch length is twice the value of the byte returned from the table.
2362 //
2363 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
2364 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2365 // The branch length is twice the value of the halfword returned from the table.
2366 // TBB, TBH
2367 bool
2368 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding)
2369 {
2370 #if 0
2371     // ARM pseudo code...
2372     EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2373     if is_tbh then
2374         halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2375     else
2376         halfwords = UInt(MemU[R[n]+R[m], 1]);
2377     BranchWritePC(PC + 2*halfwords);
2378 #endif
2379 
2380     bool success = false;
2381 
2382     uint32_t Rn;     // the base register which contains the address of the table of branch lengths
2383     uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
2384     bool is_tbh;     // true if table branch halfword
2385     switch (encoding) {
2386     case eEncodingT1:
2387         Rn = Bits32(opcode, 19, 16);
2388         Rm = Bits32(opcode, 3, 0);
2389         is_tbh = BitIsSet(opcode, 4);
2390         if (Rn == 13 || BadReg(Rm))
2391             return false;
2392         if (InITBlock() && !LastInITBlock())
2393             return false;
2394         break;
2395     default:
2396         return false;
2397     }
2398 
2399     // Read the address of the table from the operand register Rn.
2400     // The PC can be used, in which case the table immediately follows this instruction.
2401     uint32_t base = ReadCoreReg(Rm, &success);
2402     if (!success)
2403         return false;
2404 
2405     // the table index
2406     uint32_t index = ReadCoreReg(Rm, &success);
2407     if (!success)
2408         return false;
2409 
2410     // the offsetted table address
2411     addr_t addr = base + (is_tbh ? index*2 : index);
2412 
2413     // PC-relative offset to branch forward
2414     EmulateInstruction::Context context;
2415     context.type = EmulateInstruction::eContextTableBranchReadMemory;
2416     uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2417     if (!success)
2418         return false;
2419 
2420     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2421     if (!success)
2422         return false;
2423 
2424     // target address
2425     addr_t target = pc + offset;
2426     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2427     context.SetISAAndImmediateSigned (eModeThumb, 4 + offset);
2428 
2429     if (!BranchWritePC(context, target))
2430         return false;
2431 
2432     return true;
2433 }
2434 
2435 // This instruction adds an immediate value to a register value, and writes the result to the destination register.
2436 // It can optionally update the condition flags based on the result.
2437 bool
2438 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding)
2439 {
2440 #if 0
2441     if ConditionPassed() then
2442         EncodingSpecificOperations();
2443         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2444         R[d] = result;
2445         if setflags then
2446             APSR.N = result<31>;
2447             APSR.Z = IsZeroBit(result);
2448             APSR.C = carry;
2449             APSR.V = overflow;
2450 #endif
2451 
2452     bool success = false;
2453 
2454     if (ConditionPassed(opcode))
2455     {
2456         uint32_t d;
2457         uint32_t n;
2458         bool setflags;
2459         uint32_t imm32;
2460         uint32_t carry_out;
2461 
2462         //EncodingSpecificOperations();
2463         switch (encoding)
2464         {
2465             case eEncodingT1:
2466                 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32);
2467                 d = Bits32 (opcode, 2, 0);
2468                 n = Bits32 (opcode, 5, 3);
2469                 setflags = !InITBlock();
2470                 imm32 = Bits32 (opcode, 8,6);
2471 
2472                 break;
2473 
2474             case eEncodingT2:
2475                 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32);
2476                 d = Bits32 (opcode, 10, 8);
2477                 n = Bits32 (opcode, 10, 8);
2478                 setflags = !InITBlock();
2479                 imm32 = Bits32 (opcode, 7, 0);
2480 
2481                 break;
2482 
2483             case eEncodingT3:
2484                 // if Rd == '1111' && S == '1' then SEE CMN (immediate);
2485                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2486                 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8);
2487                 d = Bits32 (opcode, 11, 8);
2488                 n = Bits32 (opcode, 19, 16);
2489                 setflags = BitIsSet (opcode, 20);
2490                 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out);
2491 
2492                 // if BadReg(d) || n == 15 then UNPREDICTABLE;
2493                 if (BadReg (d) || (n == 15))
2494                     return false;
2495 
2496                 break;
2497 
2498             case eEncodingT4:
2499             {
2500                 // if Rn == '1111' then SEE ADR;
2501                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2502                 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
2503                 d = Bits32 (opcode, 11, 8);
2504                 n = Bits32 (opcode, 19, 16);
2505                 setflags = false;
2506                 uint32_t i = Bit32 (opcode, 26);
2507                 uint32_t imm3 = Bits32 (opcode, 14, 12);
2508                 uint32_t imm8 = Bits32 (opcode, 7, 0);
2509                 imm32 = (i << 11) | (imm3 << 8) | imm8;
2510 
2511                 // if BadReg(d) then UNPREDICTABLE;
2512                 if (BadReg (d))
2513                     return false;
2514 
2515                 break;
2516             }
2517             default:
2518                 return false;
2519         }
2520 
2521         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2522         if (!success)
2523             return false;
2524 
2525         //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2526         AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
2527 
2528         RegisterInfo reg_n;
2529         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
2530 
2531         EmulateInstruction::Context context;
2532         context.type = eContextArithmetic;
2533         context.SetRegisterPlusOffset (reg_n, imm32);
2534 
2535         //R[d] = result;
2536         //if setflags then
2537             //APSR.N = result<31>;
2538             //APSR.Z = IsZeroBit(result);
2539             //APSR.C = carry;
2540             //APSR.V = overflow;
2541         if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
2542             return false;
2543 
2544     }
2545     return true;
2546 }
2547 
2548 // This instruction adds an immediate value to a register value, and writes the result to the destination
2549 // register.  It can optionally update the condition flags based on the result.
2550 bool
2551 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding)
2552 {
2553 #if 0
2554     // ARM pseudo code...
2555     if ConditionPassed() then
2556         EncodingSpecificOperations();
2557         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2558         if d == 15 then
2559             ALUWritePC(result); // setflags is always FALSE here
2560         else
2561             R[d] = result;
2562             if setflags then
2563                 APSR.N = result<31>;
2564                 APSR.Z = IsZeroBit(result);
2565                 APSR.C = carry;
2566                 APSR.V = overflow;
2567 #endif
2568 
2569     bool success = false;
2570 
2571     if (ConditionPassed(opcode))
2572     {
2573         uint32_t Rd, Rn;
2574         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
2575         bool setflags;
2576         switch (encoding)
2577         {
2578         case eEncodingA1:
2579             Rd = Bits32(opcode, 15, 12);
2580             Rn = Bits32(opcode, 19, 16);
2581             setflags = BitIsSet(opcode, 20);
2582             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2583             break;
2584         default:
2585             return false;
2586         }
2587 
2588         // Read the first operand.
2589         uint32_t val1 = ReadCoreReg(Rn, &success);
2590         if (!success)
2591             return false;
2592 
2593         AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
2594 
2595         EmulateInstruction::Context context;
2596         context.type = eContextArithmetic;
2597         RegisterInfo dwarf_reg;
2598         GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
2599         context.SetRegisterPlusOffset (dwarf_reg, imm32);
2600 
2601         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2602             return false;
2603     }
2604     return true;
2605 }
2606 
2607 // This instruction adds a register value and an optionally-shifted register value, and writes the result
2608 // to the destination register. It can optionally update the condition flags based on the result.
2609 bool
2610 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding)
2611 {
2612 #if 0
2613     // ARM pseudo code...
2614     if ConditionPassed() then
2615         EncodingSpecificOperations();
2616         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2617         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2618         if d == 15 then
2619             ALUWritePC(result); // setflags is always FALSE here
2620         else
2621             R[d] = result;
2622             if setflags then
2623                 APSR.N = result<31>;
2624                 APSR.Z = IsZeroBit(result);
2625                 APSR.C = carry;
2626                 APSR.V = overflow;
2627 #endif
2628 
2629     bool success = false;
2630 
2631     if (ConditionPassed(opcode))
2632     {
2633         uint32_t Rd, Rn, Rm;
2634         ARM_ShifterType shift_t;
2635         uint32_t shift_n; // the shift applied to the value read from Rm
2636         bool setflags;
2637         switch (encoding)
2638         {
2639         case eEncodingT1:
2640             Rd = Bits32(opcode, 2, 0);
2641             Rn = Bits32(opcode, 5, 3);
2642             Rm = Bits32(opcode, 8, 6);
2643             setflags = !InITBlock();
2644             shift_t = SRType_LSL;
2645             shift_n = 0;
2646             break;
2647         case eEncodingT2:
2648             Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2649             Rm = Bits32(opcode, 6, 3);
2650             setflags = false;
2651             shift_t = SRType_LSL;
2652             shift_n = 0;
2653             if (Rn == 15 && Rm == 15)
2654                 return false;
2655             if (Rd == 15 && InITBlock() && !LastInITBlock())
2656                 return false;
2657             break;
2658         case eEncodingA1:
2659             Rd = Bits32(opcode, 15, 12);
2660             Rn = Bits32(opcode, 19, 16);
2661             Rm = Bits32(opcode, 3, 0);
2662             setflags = BitIsSet(opcode, 20);
2663             shift_n = DecodeImmShiftARM(opcode, shift_t);
2664             break;
2665         default:
2666             return false;
2667         }
2668 
2669         // Read the first operand.
2670         uint32_t val1 = ReadCoreReg(Rn, &success);
2671         if (!success)
2672             return false;
2673 
2674         // Read the second operand.
2675         uint32_t val2 = ReadCoreReg(Rm, &success);
2676         if (!success)
2677             return false;
2678 
2679         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2680         if (!success)
2681             return false;
2682         AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2683 
2684         EmulateInstruction::Context context;
2685         context.type = eContextArithmetic;
2686         RegisterInfo op1_reg;
2687         RegisterInfo op2_reg;
2688         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
2689         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
2690         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
2691 
2692         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2693             return false;
2694     }
2695     return true;
2696 }
2697 
2698 // Compare Negative (immediate) adds a register value and an immediate value.
2699 // It updates the condition flags based on the result, and discards the result.
2700 bool
2701 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding)
2702 {
2703 #if 0
2704     // ARM pseudo code...
2705     if ConditionPassed() then
2706         EncodingSpecificOperations();
2707         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2708         APSR.N = result<31>;
2709         APSR.Z = IsZeroBit(result);
2710         APSR.C = carry;
2711         APSR.V = overflow;
2712 #endif
2713 
2714     bool success = false;
2715 
2716     uint32_t Rn; // the first operand
2717     uint32_t imm32; // the immediate value to be compared with
2718     switch (encoding) {
2719     case eEncodingT1:
2720         Rn = Bits32(opcode, 19, 16);
2721         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2722         if (Rn == 15)
2723             return false;
2724         break;
2725     case eEncodingA1:
2726         Rn = Bits32(opcode, 19, 16);
2727         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2728         break;
2729     default:
2730         return false;
2731     }
2732     // Read the register value from the operand register Rn.
2733     uint32_t reg_val = ReadCoreReg(Rn, &success);
2734     if (!success)
2735         return false;
2736 
2737     AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
2738 
2739     EmulateInstruction::Context context;
2740     context.type = EmulateInstruction::eContextImmediate;
2741     context.SetNoArgs ();
2742     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2743         return false;
2744 
2745     return true;
2746 }
2747 
2748 // Compare Negative (register) adds a register value and an optionally-shifted register value.
2749 // It updates the condition flags based on the result, and discards the result.
2750 bool
2751 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding)
2752 {
2753 #if 0
2754     // ARM pseudo code...
2755     if ConditionPassed() then
2756         EncodingSpecificOperations();
2757         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2758         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2759         APSR.N = result<31>;
2760         APSR.Z = IsZeroBit(result);
2761         APSR.C = carry;
2762         APSR.V = overflow;
2763 #endif
2764 
2765     bool success = false;
2766 
2767     uint32_t Rn; // the first operand
2768     uint32_t Rm; // the second operand
2769     ARM_ShifterType shift_t;
2770     uint32_t shift_n; // the shift applied to the value read from Rm
2771     switch (encoding) {
2772     case eEncodingT1:
2773         Rn = Bits32(opcode, 2, 0);
2774         Rm = Bits32(opcode, 5, 3);
2775         shift_t = SRType_LSL;
2776         shift_n = 0;
2777         break;
2778     case eEncodingT2:
2779         Rn = Bits32(opcode, 19, 16);
2780         Rm = Bits32(opcode, 3, 0);
2781         shift_n = DecodeImmShiftThumb(opcode, shift_t);
2782         // if n == 15 || BadReg(m) then UNPREDICTABLE;
2783         if (Rn == 15 || BadReg(Rm))
2784             return false;
2785         break;
2786     case eEncodingA1:
2787         Rn = Bits32(opcode, 19, 16);
2788         Rm = Bits32(opcode, 3, 0);
2789         shift_n = DecodeImmShiftARM(opcode, shift_t);
2790         break;
2791     default:
2792         return false;
2793     }
2794     // Read the register value from register Rn.
2795     uint32_t val1 = ReadCoreReg(Rn, &success);
2796     if (!success)
2797         return false;
2798 
2799     // Read the register value from register Rm.
2800     uint32_t val2 = ReadCoreReg(Rm, &success);
2801     if (!success)
2802         return false;
2803 
2804     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2805     if (!success)
2806         return false;
2807     AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2808 
2809     EmulateInstruction::Context context;
2810     context.type = EmulateInstruction::eContextImmediate;
2811     context.SetNoArgs();
2812     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2813         return false;
2814 
2815     return true;
2816 }
2817 
2818 // Compare (immediate) subtracts an immediate value from a register value.
2819 // It updates the condition flags based on the result, and discards the result.
2820 bool
2821 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding)
2822 {
2823 #if 0
2824     // ARM pseudo code...
2825     if ConditionPassed() then
2826         EncodingSpecificOperations();
2827         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2828         APSR.N = result<31>;
2829         APSR.Z = IsZeroBit(result);
2830         APSR.C = carry;
2831         APSR.V = overflow;
2832 #endif
2833 
2834     bool success = false;
2835 
2836     uint32_t Rn; // the first operand
2837     uint32_t imm32; // the immediate value to be compared with
2838     switch (encoding) {
2839     case eEncodingT1:
2840         Rn = Bits32(opcode, 10, 8);
2841         imm32 = Bits32(opcode, 7, 0);
2842         break;
2843     case eEncodingT2:
2844         Rn = Bits32(opcode, 19, 16);
2845         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2846         if (Rn == 15)
2847             return false;
2848         break;
2849     case eEncodingA1:
2850         Rn = Bits32(opcode, 19, 16);
2851         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2852         break;
2853     default:
2854         return false;
2855     }
2856     // Read the register value from the operand register Rn.
2857     uint32_t reg_val = ReadCoreReg(Rn, &success);
2858     if (!success)
2859         return false;
2860 
2861     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
2862 
2863     EmulateInstruction::Context context;
2864     context.type = EmulateInstruction::eContextImmediate;
2865     context.SetNoArgs ();
2866     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2867         return false;
2868 
2869     return true;
2870 }
2871 
2872 // Compare (register) subtracts an optionally-shifted register value from a register value.
2873 // It updates the condition flags based on the result, and discards the result.
2874 bool
2875 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding)
2876 {
2877 #if 0
2878     // ARM pseudo code...
2879     if ConditionPassed() then
2880         EncodingSpecificOperations();
2881         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2882         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2883         APSR.N = result<31>;
2884         APSR.Z = IsZeroBit(result);
2885         APSR.C = carry;
2886         APSR.V = overflow;
2887 #endif
2888 
2889     bool success = false;
2890 
2891     uint32_t Rn; // the first operand
2892     uint32_t Rm; // the second operand
2893     ARM_ShifterType shift_t;
2894     uint32_t shift_n; // the shift applied to the value read from Rm
2895     switch (encoding) {
2896     case eEncodingT1:
2897         Rn = Bits32(opcode, 2, 0);
2898         Rm = Bits32(opcode, 5, 3);
2899         shift_t = SRType_LSL;
2900         shift_n = 0;
2901         break;
2902     case eEncodingT2:
2903         Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2904         Rm = Bits32(opcode, 6, 3);
2905         shift_t = SRType_LSL;
2906         shift_n = 0;
2907         if (Rn < 8 && Rm < 8)
2908             return false;
2909         if (Rn == 15 || Rm == 15)
2910             return false;
2911         break;
2912     case eEncodingA1:
2913         Rn = Bits32(opcode, 19, 16);
2914         Rm = Bits32(opcode, 3, 0);
2915         shift_n = DecodeImmShiftARM(opcode, shift_t);
2916         break;
2917     default:
2918         return false;
2919     }
2920     // Read the register value from register Rn.
2921     uint32_t val1 = ReadCoreReg(Rn, &success);
2922     if (!success)
2923         return false;
2924 
2925     // Read the register value from register Rm.
2926     uint32_t val2 = ReadCoreReg(Rm, &success);
2927     if (!success)
2928         return false;
2929 
2930     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2931     if (!success)
2932         return false;
2933     AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
2934 
2935     EmulateInstruction::Context context;
2936     context.type = EmulateInstruction::eContextImmediate;
2937     context.SetNoArgs();
2938     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2939         return false;
2940 
2941     return true;
2942 }
2943 
2944 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
2945 // shifting in copies of its sign bit, and writes the result to the destination register.  It can
2946 // optionally update the condition flags based on the result.
2947 bool
2948 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding)
2949 {
2950 #if 0
2951     // ARM pseudo code...
2952     if ConditionPassed() then
2953         EncodingSpecificOperations();
2954         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2955         if d == 15 then         // Can only occur for ARM encoding
2956             ALUWritePC(result); // setflags is always FALSE here
2957         else
2958             R[d] = result;
2959             if setflags then
2960                 APSR.N = result<31>;
2961                 APSR.Z = IsZeroBit(result);
2962                 APSR.C = carry;
2963                 // APSR.V unchanged
2964 #endif
2965 
2966     return EmulateShiftImm (opcode, encoding, SRType_ASR);
2967 }
2968 
2969 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
2970 // shifting in copies of its sign bit, and writes the result to the destination register.
2971 // The variable number of bits is read from the bottom byte of a register. It can optionally update
2972 // the condition flags based on the result.
2973 bool
2974 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding)
2975 {
2976 #if 0
2977     // ARM pseudo code...
2978     if ConditionPassed() then
2979         EncodingSpecificOperations();
2980         shift_n = UInt(R[m]<7:0>);
2981         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2982         R[d] = result;
2983         if setflags then
2984             APSR.N = result<31>;
2985             APSR.Z = IsZeroBit(result);
2986             APSR.C = carry;
2987             // APSR.V unchanged
2988 #endif
2989 
2990     return EmulateShiftReg (opcode, encoding, SRType_ASR);
2991 }
2992 
2993 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
2994 // shifting in zeros, and writes the result to the destination register.  It can optionally
2995 // update the condition flags based on the result.
2996 bool
2997 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding)
2998 {
2999 #if 0
3000     // ARM pseudo code...
3001     if ConditionPassed() then
3002         EncodingSpecificOperations();
3003         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3004         if d == 15 then         // Can only occur for ARM encoding
3005             ALUWritePC(result); // setflags is always FALSE here
3006         else
3007             R[d] = result;
3008             if setflags then
3009                 APSR.N = result<31>;
3010                 APSR.Z = IsZeroBit(result);
3011                 APSR.C = carry;
3012                 // APSR.V unchanged
3013 #endif
3014 
3015     return EmulateShiftImm (opcode, encoding, SRType_LSL);
3016 }
3017 
3018 // Logical Shift Left (register) shifts a register value left by a variable number of bits,
3019 // shifting in zeros, and writes the result to the destination register.  The variable number
3020 // of bits is read from the bottom byte of a register. It can optionally update the condition
3021 // flags based on the result.
3022 bool
3023 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding)
3024 {
3025 #if 0
3026     // ARM pseudo code...
3027     if ConditionPassed() then
3028         EncodingSpecificOperations();
3029         shift_n = UInt(R[m]<7:0>);
3030         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3031         R[d] = result;
3032         if setflags then
3033             APSR.N = result<31>;
3034             APSR.Z = IsZeroBit(result);
3035             APSR.C = carry;
3036             // APSR.V unchanged
3037 #endif
3038 
3039     return EmulateShiftReg (opcode, encoding, SRType_LSL);
3040 }
3041 
3042 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
3043 // shifting in zeros, and writes the result to the destination register.  It can optionally
3044 // update the condition flags based on the result.
3045 bool
3046 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding)
3047 {
3048 #if 0
3049     // ARM pseudo code...
3050     if ConditionPassed() then
3051         EncodingSpecificOperations();
3052         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3053         if d == 15 then         // Can only occur for ARM encoding
3054             ALUWritePC(result); // setflags is always FALSE here
3055         else
3056             R[d] = result;
3057             if setflags then
3058                 APSR.N = result<31>;
3059                 APSR.Z = IsZeroBit(result);
3060                 APSR.C = carry;
3061                 // APSR.V unchanged
3062 #endif
3063 
3064     return EmulateShiftImm (opcode, encoding, SRType_LSR);
3065 }
3066 
3067 // Logical Shift Right (register) shifts a register value right by a variable number of bits,
3068 // shifting in zeros, and writes the result to the destination register.  The variable number
3069 // of bits is read from the bottom byte of a register. It can optionally update the condition
3070 // flags based on the result.
3071 bool
3072 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding)
3073 {
3074 #if 0
3075     // ARM pseudo code...
3076     if ConditionPassed() then
3077         EncodingSpecificOperations();
3078         shift_n = UInt(R[m]<7:0>);
3079         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3080         R[d] = result;
3081         if setflags then
3082             APSR.N = result<31>;
3083             APSR.Z = IsZeroBit(result);
3084             APSR.C = carry;
3085             // APSR.V unchanged
3086 #endif
3087 
3088     return EmulateShiftReg (opcode, encoding, SRType_LSR);
3089 }
3090 
3091 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
3092 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3093 // It can optionally update the condition flags based on the result.
3094 bool
3095 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding)
3096 {
3097 #if 0
3098     // ARM pseudo code...
3099     if ConditionPassed() then
3100         EncodingSpecificOperations();
3101         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3102         if d == 15 then         // Can only occur for ARM encoding
3103             ALUWritePC(result); // setflags is always FALSE here
3104         else
3105             R[d] = result;
3106             if setflags then
3107                 APSR.N = result<31>;
3108                 APSR.Z = IsZeroBit(result);
3109                 APSR.C = carry;
3110                 // APSR.V unchanged
3111 #endif
3112 
3113     return EmulateShiftImm (opcode, encoding, SRType_ROR);
3114 }
3115 
3116 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
3117 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3118 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
3119 // flags based on the result.
3120 bool
3121 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding)
3122 {
3123 #if 0
3124     // ARM pseudo code...
3125     if ConditionPassed() then
3126         EncodingSpecificOperations();
3127         shift_n = UInt(R[m]<7:0>);
3128         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3129         R[d] = result;
3130         if setflags then
3131             APSR.N = result<31>;
3132             APSR.Z = IsZeroBit(result);
3133             APSR.C = carry;
3134             // APSR.V unchanged
3135 #endif
3136 
3137     return EmulateShiftReg (opcode, encoding, SRType_ROR);
3138 }
3139 
3140 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
3141 // with the carry flag shifted into bit [31].
3142 //
3143 // RRX can optionally update the condition flags based on the result.
3144 // In that case, bit [0] is shifted into the carry flag.
3145 bool
3146 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding)
3147 {
3148 #if 0
3149     // ARM pseudo code...
3150     if ConditionPassed() then
3151         EncodingSpecificOperations();
3152         (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3153         if d == 15 then         // Can only occur for ARM encoding
3154             ALUWritePC(result); // setflags is always FALSE here
3155         else
3156             R[d] = result;
3157             if setflags then
3158                 APSR.N = result<31>;
3159                 APSR.Z = IsZeroBit(result);
3160                 APSR.C = carry;
3161                 // APSR.V unchanged
3162 #endif
3163 
3164     return EmulateShiftImm (opcode, encoding, SRType_RRX);
3165 }
3166 
3167 bool
3168 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3169 {
3170 //    assert(shift_type == SRType_ASR
3171 //           || shift_type == SRType_LSL
3172 //           || shift_type == SRType_LSR
3173 //           || shift_type == SRType_ROR
3174 //           || shift_type == SRType_RRX);
3175 
3176     bool success = false;
3177 
3178     if (ConditionPassed(opcode))
3179     {
3180         uint32_t Rd;    // the destination register
3181         uint32_t Rm;    // the first operand register
3182         uint32_t imm5;  // encoding for the shift amount
3183         uint32_t carry; // the carry bit after the shift operation
3184         bool setflags;
3185 
3186         // Special case handling!
3187         // A8.6.139 ROR (immediate) -- Encoding T1
3188         ARMEncoding use_encoding = encoding;
3189         if (shift_type == SRType_ROR && use_encoding == eEncodingT1)
3190         {
3191             // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
3192             // have the same decoding of bit fields as the other Thumb2 shift operations.
3193             use_encoding = eEncodingT2;
3194         }
3195 
3196         switch (use_encoding) {
3197         case eEncodingT1:
3198             // Due to the above special case handling!
3199             if (shift_type == SRType_ROR)
3200                 return false;
3201 
3202             Rd = Bits32(opcode, 2, 0);
3203             Rm = Bits32(opcode, 5, 3);
3204             setflags = !InITBlock();
3205             imm5 = Bits32(opcode, 10, 6);
3206             break;
3207         case eEncodingT2:
3208             // A8.6.141 RRX
3209             // There's no imm form of RRX instructions.
3210             if (shift_type == SRType_RRX)
3211                 return false;
3212 
3213             Rd = Bits32(opcode, 11, 8);
3214             Rm = Bits32(opcode, 3, 0);
3215             setflags = BitIsSet(opcode, 20);
3216             imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3217             if (BadReg(Rd) || BadReg(Rm))
3218                 return false;
3219             break;
3220         case eEncodingA1:
3221             Rd = Bits32(opcode, 15, 12);
3222             Rm = Bits32(opcode, 3, 0);
3223             setflags = BitIsSet(opcode, 20);
3224             imm5 = Bits32(opcode, 11, 7);
3225             break;
3226         default:
3227             return false;
3228         }
3229 
3230         // A8.6.139 ROR (immediate)
3231         if (shift_type == SRType_ROR && imm5 == 0)
3232             shift_type = SRType_RRX;
3233 
3234         // Get the first operand.
3235         uint32_t value = ReadCoreReg (Rm, &success);
3236         if (!success)
3237             return false;
3238 
3239         // Decode the shift amount if not RRX.
3240         uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3241 
3242         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3243         if (!success)
3244             return false;
3245 
3246         // The context specifies that an immediate is to be moved into Rd.
3247         EmulateInstruction::Context context;
3248         context.type = EmulateInstruction::eContextImmediate;
3249         context.SetNoArgs ();
3250 
3251         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3252             return false;
3253     }
3254     return true;
3255 }
3256 
3257 bool
3258 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3259 {
3260     // assert(shift_type == SRType_ASR
3261     //        || shift_type == SRType_LSL
3262     //        || shift_type == SRType_LSR
3263     //        || shift_type == SRType_ROR);
3264 
3265     bool success = false;
3266 
3267     if (ConditionPassed(opcode))
3268     {
3269         uint32_t Rd;    // the destination register
3270         uint32_t Rn;    // the first operand register
3271         uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
3272         uint32_t carry; // the carry bit after the shift operation
3273         bool setflags;
3274         switch (encoding) {
3275         case eEncodingT1:
3276             Rd = Bits32(opcode, 2, 0);
3277             Rn = Rd;
3278             Rm = Bits32(opcode, 5, 3);
3279             setflags = !InITBlock();
3280             break;
3281         case eEncodingT2:
3282             Rd = Bits32(opcode, 11, 8);
3283             Rn = Bits32(opcode, 19, 16);
3284             Rm = Bits32(opcode, 3, 0);
3285             setflags = BitIsSet(opcode, 20);
3286             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3287                 return false;
3288             break;
3289         case eEncodingA1:
3290             Rd = Bits32(opcode, 15, 12);
3291             Rn = Bits32(opcode, 3, 0);
3292             Rm = Bits32(opcode, 11, 8);
3293             setflags = BitIsSet(opcode, 20);
3294             if (Rd == 15 || Rn == 15 || Rm == 15)
3295                 return false;
3296             break;
3297         default:
3298             return false;
3299         }
3300 
3301         // Get the first operand.
3302         uint32_t value = ReadCoreReg (Rn, &success);
3303         if (!success)
3304             return false;
3305         // Get the Rm register content.
3306         uint32_t val = ReadCoreReg (Rm, &success);
3307         if (!success)
3308             return false;
3309 
3310         // Get the shift amount.
3311         uint32_t amt = Bits32(val, 7, 0);
3312 
3313         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3314         if (!success)
3315             return false;
3316 
3317         // The context specifies that an immediate is to be moved into Rd.
3318         EmulateInstruction::Context context;
3319         context.type = EmulateInstruction::eContextImmediate;
3320         context.SetNoArgs ();
3321 
3322         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3323             return false;
3324     }
3325     return true;
3326 }
3327 
3328 // LDM loads multiple registers from consecutive memory locations, using an
3329 // address from a base register.  Optionally the address just above the highest of those locations
3330 // can be written back to the base register.
3331 bool
3332 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding)
3333 {
3334 #if 0
3335     // ARM pseudo code...
3336     if ConditionPassed()
3337         EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3338         address = R[n];
3339 
3340         for i = 0 to 14
3341             if registers<i> == '1' then
3342                 R[i] = MemA[address, 4]; address = address + 4;
3343         if registers<15> == '1' then
3344             LoadWritePC (MemA[address, 4]);
3345 
3346         if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3347         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3348 
3349 #endif
3350 
3351     bool success = false;
3352     bool conditional = false;
3353     if (ConditionPassed(opcode, &conditional))
3354     {
3355         uint32_t n;
3356         uint32_t registers = 0;
3357         bool wback;
3358         const uint32_t addr_byte_size = GetAddressByteSize();
3359         switch (encoding)
3360         {
3361             case eEncodingT1:
3362                 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0');
3363                 n = Bits32 (opcode, 10, 8);
3364                 registers = Bits32 (opcode, 7, 0);
3365                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3366                 wback = BitIsClear (registers, n);
3367                 // if BitCount(registers) < 1 then UNPREDICTABLE;
3368                 if (BitCount(registers) < 1)
3369                     return false;
3370                 break;
3371             case eEncodingT2:
3372                 // if W == '1' && Rn == '1101' then SEE POP;
3373                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3374                 n = Bits32 (opcode, 19, 16);
3375                 registers = Bits32 (opcode, 15, 0);
3376                 registers = registers & 0xdfff; // Make sure bit 13 is zero.
3377                 wback = BitIsSet (opcode, 21);
3378 
3379                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3380                 if ((n == 15)
3381                     || (BitCount (registers) < 2)
3382                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3383                     return false;
3384 
3385                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3386                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3387                     return false;
3388 
3389                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3390                 if (wback
3391                     && BitIsSet (registers, n))
3392                     return false;
3393                 break;
3394 
3395             case eEncodingA1:
3396                 n = Bits32 (opcode, 19, 16);
3397                 registers = Bits32 (opcode, 15, 0);
3398                 wback = BitIsSet (opcode, 21);
3399                 if ((n == 15)
3400                     || (BitCount (registers) < 1))
3401                     return false;
3402                 break;
3403             default:
3404                 return false;
3405         }
3406 
3407         int32_t offset = 0;
3408         const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3409         if (!success)
3410             return false;
3411 
3412         EmulateInstruction::Context context;
3413         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3414         RegisterInfo dwarf_reg;
3415         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3416         context.SetRegisterPlusOffset (dwarf_reg, offset);
3417 
3418         for (int i = 0; i < 14; ++i)
3419         {
3420             if (BitIsSet (registers, i))
3421             {
3422                 context.type = EmulateInstruction::eContextRegisterPlusOffset;
3423                 context.SetRegisterPlusOffset (dwarf_reg, offset);
3424                 if (wback && (n == 13)) // Pop Instruction
3425                 {
3426                     if (conditional)
3427                         context.type = EmulateInstruction::eContextRegisterLoad;
3428                     else
3429                         context.type = EmulateInstruction::eContextPopRegisterOffStack;
3430                 }
3431 
3432                 // R[i] = MemA [address, 4]; address = address + 4;
3433                 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3434                 if (!success)
3435                     return false;
3436 
3437                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3438                     return false;
3439 
3440                 offset += addr_byte_size;
3441             }
3442         }
3443 
3444         if (BitIsSet (registers, 15))
3445         {
3446             //LoadWritePC (MemA [address, 4]);
3447             context.type = EmulateInstruction::eContextRegisterPlusOffset;
3448             context.SetRegisterPlusOffset (dwarf_reg, offset);
3449             uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3450             if (!success)
3451                 return false;
3452             // In ARMv5T and above, this is an interworking branch.
3453             if (!LoadWritePC(context, data))
3454                 return false;
3455         }
3456 
3457         if (wback && BitIsClear (registers, n))
3458         {
3459             // R[n] = R[n] + 4 * BitCount (registers)
3460             int32_t offset = addr_byte_size * BitCount (registers);
3461             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3462             context.SetRegisterPlusOffset (dwarf_reg, offset);
3463 
3464             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
3465                 return false;
3466         }
3467         if (wback && BitIsSet (registers, n))
3468             // R[n] bits(32) UNKNOWN;
3469             return WriteBits32Unknown (n);
3470     }
3471     return true;
3472 }
3473 
3474 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register.
3475 // The consecutive memory locations end at this address and the address just below the lowest of those locations
3476 // can optionally be written back to the base register.
3477 bool
3478 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding)
3479 {
3480 #if 0
3481     // ARM pseudo code...
3482     if ConditionPassed() then
3483         EncodingSpecificOperations();
3484         address = R[n] - 4*BitCount(registers) + 4;
3485 
3486         for i = 0 to 14
3487             if registers<i> == '1' then
3488                   R[i] = MemA[address,4]; address = address + 4;
3489 
3490         if registers<15> == '1' then
3491             LoadWritePC(MemA[address,4]);
3492 
3493         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3494         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3495 #endif
3496 
3497     bool success = false;
3498 
3499     if (ConditionPassed(opcode))
3500     {
3501         uint32_t n;
3502         uint32_t registers = 0;
3503         bool wback;
3504         const uint32_t addr_byte_size = GetAddressByteSize();
3505 
3506         // EncodingSpecificOperations();
3507         switch (encoding)
3508         {
3509             case eEncodingA1:
3510                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3511                 n = Bits32 (opcode, 19, 16);
3512                 registers = Bits32 (opcode, 15, 0);
3513                 wback = BitIsSet (opcode, 21);
3514 
3515                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3516                 if ((n == 15) || (BitCount (registers) < 1))
3517                     return false;
3518 
3519                 break;
3520 
3521             default:
3522                 return false;
3523         }
3524         // address = R[n] - 4*BitCount(registers) + 4;
3525 
3526         int32_t offset = 0;
3527         addr_t Rn = ReadCoreReg (n, &success);
3528 
3529         if (!success)
3530             return false;
3531 
3532         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size;
3533 
3534         EmulateInstruction::Context context;
3535         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3536         RegisterInfo dwarf_reg;
3537         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3538         context.SetRegisterPlusOffset (dwarf_reg, offset);
3539 
3540         // for i = 0 to 14
3541         for (int i = 0; i < 14; ++i)
3542         {
3543             // if registers<i> == '1' then
3544             if (BitIsSet (registers, i))
3545             {
3546                   // R[i] = MemA[address,4]; address = address + 4;
3547                   context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3548                   uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3549                   if (!success)
3550                       return false;
3551                   if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3552                       return false;
3553                   offset += addr_byte_size;
3554             }
3555         }
3556 
3557         // if registers<15> == '1' then
3558         //     LoadWritePC(MemA[address,4]);
3559         if (BitIsSet (registers, 15))
3560         {
3561             context.SetRegisterPlusOffset (dwarf_reg, offset);
3562             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3563             if (!success)
3564                 return false;
3565             // In ARMv5T and above, this is an interworking branch.
3566             if (!LoadWritePC(context, data))
3567                 return false;
3568         }
3569 
3570         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3571         if (wback && BitIsClear (registers, n))
3572         {
3573             if (!success)
3574                 return false;
3575 
3576             offset = (addr_byte_size * BitCount (registers)) * -1;
3577             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3578             context.SetImmediateSigned (offset);
3579             addr_t addr = Rn + offset;
3580             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3581                 return false;
3582         }
3583 
3584         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3585         if (wback && BitIsSet (registers, n))
3586             return WriteBits32Unknown (n);
3587     }
3588     return true;
3589 }
3590 
3591 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
3592 // consecutive memory lcoations end just below this address, and the address of the lowest of those locations can
3593 // be optionally written back to the base register.
3594 bool
3595 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding)
3596 {
3597 #if 0
3598     // ARM pseudo code...
3599     if ConditionPassed() then
3600         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3601         address = R[n] - 4*BitCount(registers);
3602 
3603         for i = 0 to 14
3604             if registers<i> == '1' then
3605                   R[i] = MemA[address,4]; address = address + 4;
3606         if registers<15> == '1' then
3607                   LoadWritePC(MemA[address,4]);
3608 
3609         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3610         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3611 #endif
3612 
3613     bool success = false;
3614 
3615     if (ConditionPassed(opcode))
3616     {
3617         uint32_t n;
3618         uint32_t registers = 0;
3619         bool wback;
3620         const uint32_t addr_byte_size = GetAddressByteSize();
3621         switch (encoding)
3622         {
3623             case eEncodingT1:
3624                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3625                 n = Bits32 (opcode, 19, 16);
3626                 registers = Bits32 (opcode, 15, 0);
3627                 registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
3628                 wback = BitIsSet (opcode, 21);
3629 
3630                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3631                 if ((n == 15)
3632                     || (BitCount (registers) < 2)
3633                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3634                     return false;
3635 
3636                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3637                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3638                     return false;
3639 
3640                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3641                 if (wback && BitIsSet (registers, n))
3642                     return false;
3643 
3644                 break;
3645 
3646             case eEncodingA1:
3647                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3648                 n = Bits32 (opcode, 19, 16);
3649                 registers = Bits32 (opcode, 15, 0);
3650                 wback = BitIsSet (opcode, 21);
3651 
3652                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3653                 if ((n == 15) || (BitCount (registers) < 1))
3654                     return false;
3655 
3656                 break;
3657 
3658             default:
3659                 return false;
3660         }
3661 
3662         // address = R[n] - 4*BitCount(registers);
3663 
3664         int32_t offset = 0;
3665         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3666 
3667         if (!success)
3668             return false;
3669 
3670         addr_t address = Rn - (addr_byte_size * BitCount (registers));
3671         EmulateInstruction::Context context;
3672         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3673         RegisterInfo dwarf_reg;
3674         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3675         context.SetRegisterPlusOffset (dwarf_reg, Rn - address);
3676 
3677         for (int i = 0; i < 14; ++i)
3678         {
3679             if (BitIsSet (registers, i))
3680             {
3681                 // R[i] = MemA[address,4]; address = address + 4;
3682                 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3683                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3684                 if (!success)
3685                     return false;
3686 
3687                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3688                     return false;
3689 
3690                 offset += addr_byte_size;
3691             }
3692         }
3693 
3694         // if registers<15> == '1' then
3695         //     LoadWritePC(MemA[address,4]);
3696         if (BitIsSet (registers, 15))
3697         {
3698             context.SetRegisterPlusOffset (dwarf_reg, offset);
3699             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3700             if (!success)
3701                 return false;
3702             // In ARMv5T and above, this is an interworking branch.
3703             if (!LoadWritePC(context, data))
3704                 return false;
3705         }
3706 
3707         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3708         if (wback && BitIsClear (registers, n))
3709         {
3710             if (!success)
3711                 return false;
3712 
3713             offset = (addr_byte_size * BitCount (registers)) * -1;
3714             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3715             context.SetImmediateSigned (offset);
3716             addr_t addr = Rn + offset;
3717             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3718                 return false;
3719         }
3720 
3721         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3722         if (wback && BitIsSet (registers, n))
3723             return WriteBits32Unknown (n);
3724     }
3725     return true;
3726 }
3727 
3728 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
3729 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can
3730 // optinoally be written back to the base register.
3731 bool
3732 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding)
3733 {
3734 #if 0
3735     if ConditionPassed() then
3736         EncodingSpecificOperations();
3737         address = R[n] + 4;
3738 
3739         for i = 0 to 14
3740             if registers<i> == '1' then
3741                   R[i] = MemA[address,4]; address = address + 4;
3742         if registers<15> == '1' then
3743             LoadWritePC(MemA[address,4]);
3744 
3745         if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3746         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3747 #endif
3748 
3749     bool success = false;
3750 
3751     if (ConditionPassed(opcode))
3752     {
3753         uint32_t n;
3754         uint32_t registers = 0;
3755         bool wback;
3756         const uint32_t addr_byte_size = GetAddressByteSize();
3757         switch (encoding)
3758         {
3759             case eEncodingA1:
3760                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3761                 n = Bits32 (opcode, 19, 16);
3762                 registers = Bits32 (opcode, 15, 0);
3763                 wback = BitIsSet (opcode, 21);
3764 
3765                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3766                 if ((n == 15) || (BitCount (registers) < 1))
3767                     return false;
3768 
3769                 break;
3770             default:
3771                 return false;
3772         }
3773         // address = R[n] + 4;
3774 
3775         int32_t offset = 0;
3776         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3777 
3778         if (!success)
3779             return false;
3780 
3781         addr_t address = Rn + addr_byte_size;
3782 
3783         EmulateInstruction::Context context;
3784         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3785         RegisterInfo dwarf_reg;
3786         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3787         context.SetRegisterPlusOffset (dwarf_reg, offset);
3788 
3789         for (int i = 0; i < 14; ++i)
3790         {
3791             if (BitIsSet (registers, i))
3792             {
3793                 // R[i] = MemA[address,4]; address = address + 4;
3794 
3795                 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size);
3796                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3797                 if (!success)
3798                     return false;
3799 
3800                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3801                     return false;
3802 
3803                 offset += addr_byte_size;
3804             }
3805         }
3806 
3807         // if registers<15> == '1' then
3808         //     LoadWritePC(MemA[address,4]);
3809         if (BitIsSet (registers, 15))
3810         {
3811             context.SetRegisterPlusOffset (dwarf_reg, offset);
3812             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3813             if (!success)
3814                 return false;
3815             // In ARMv5T and above, this is an interworking branch.
3816             if (!LoadWritePC(context, data))
3817                 return false;
3818         }
3819 
3820         // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3821         if (wback && BitIsClear (registers, n))
3822         {
3823             if (!success)
3824                 return false;
3825 
3826             offset = addr_byte_size * BitCount (registers);
3827             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3828             context.SetImmediateSigned (offset);
3829             addr_t addr = Rn + offset;
3830             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3831                 return false;
3832         }
3833 
3834         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3835         if (wback && BitIsSet (registers, n))
3836             return WriteBits32Unknown (n);
3837     }
3838     return true;
3839 }
3840 
3841 // Load Register (immediate) calculates an address from a base register value and
3842 // an immediate offset, loads a word from memory, and writes to a register.
3843 // LDR (immediate, Thumb)
3844 bool
3845 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding)
3846 {
3847 #if 0
3848     // ARM pseudo code...
3849     if (ConditionPassed())
3850     {
3851         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3852         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3853         address = if index then offset_addr else R[n];
3854         data = MemU[address,4];
3855         if wback then R[n] = offset_addr;
3856         if t == 15 then
3857             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3858         elsif UnalignedSupport() || address<1:0> = '00' then
3859             R[t] = data;
3860         else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3861     }
3862 #endif
3863 
3864     bool success = false;
3865 
3866     if (ConditionPassed(opcode))
3867     {
3868         uint32_t Rt; // the destination register
3869         uint32_t Rn; // the base register
3870         uint32_t imm32; // the immediate offset used to form the address
3871         addr_t offset_addr; // the offset address
3872         addr_t address; // the calculated address
3873         uint32_t data; // the literal data value from memory load
3874         bool add, index, wback;
3875         switch (encoding) {
3876             case eEncodingT1:
3877                 Rt = Bits32(opcode, 2, 0);
3878                 Rn = Bits32(opcode, 5, 3);
3879                 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3880                 // index = TRUE; add = TRUE; wback = FALSE
3881                 add = true;
3882                 index = true;
3883                 wback = false;
3884 
3885                 break;
3886 
3887             case eEncodingT2:
3888                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
3889                 Rt = Bits32 (opcode, 10, 8);
3890                 Rn = 13;
3891                 imm32 = Bits32 (opcode, 7, 0) << 2;
3892 
3893                 // index = TRUE; add = TRUE; wback = FALSE;
3894                 index = true;
3895                 add = true;
3896                 wback = false;
3897 
3898                 break;
3899 
3900             case eEncodingT3:
3901                 // if Rn == '1111' then SEE LDR (literal);
3902                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
3903                 Rt = Bits32 (opcode, 15, 12);
3904                 Rn = Bits32 (opcode, 19, 16);
3905                 imm32 = Bits32 (opcode, 11, 0);
3906 
3907                 // index = TRUE; add = TRUE; wback = FALSE;
3908                 index = true;
3909                 add = true;
3910                 wback = false;
3911 
3912                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3913                 if ((Rt == 15) && InITBlock() && !LastInITBlock())
3914                     return false;
3915 
3916                 break;
3917 
3918             case eEncodingT4:
3919                 // if Rn == '1111' then SEE LDR (literal);
3920                 // if P == '1' && U == '1' && W == '0' then SEE LDRT;
3921                 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
3922                 // if P == '0' && W == '0' then UNDEFINED;
3923                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
3924                     return false;
3925 
3926                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
3927                 Rt = Bits32 (opcode, 15, 12);
3928                 Rn = Bits32 (opcode, 19, 16);
3929                 imm32 = Bits32 (opcode, 7, 0);
3930 
3931                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
3932                 index = BitIsSet (opcode, 10);
3933                 add = BitIsSet (opcode, 9);
3934                 wback = BitIsSet (opcode, 8);
3935 
3936                 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
3937                 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock()))
3938                     return false;
3939 
3940                 break;
3941 
3942             default:
3943                 return false;
3944         }
3945         uint32_t base = ReadCoreReg (Rn, &success);
3946         if (!success)
3947             return false;
3948         if (add)
3949             offset_addr = base + imm32;
3950         else
3951             offset_addr = base - imm32;
3952 
3953         address = (index ? offset_addr : base);
3954 
3955         RegisterInfo base_reg;
3956         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
3957         if (wback)
3958         {
3959             EmulateInstruction::Context ctx;
3960             ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
3961             ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3962 
3963             if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
3964                 return false;
3965         }
3966 
3967         // Prepare to write to the Rt register.
3968         EmulateInstruction::Context context;
3969         context.type = EmulateInstruction::eContextRegisterLoad;
3970         context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3971 
3972         // Read memory from the address.
3973         data = MemURead(context, address, 4, 0, &success);
3974         if (!success)
3975             return false;
3976 
3977         if (Rt == 15)
3978         {
3979             if (Bits32(address, 1, 0) == 0)
3980             {
3981                 if (!LoadWritePC(context, data))
3982                     return false;
3983             }
3984             else
3985                 return false;
3986         }
3987         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
3988         {
3989             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
3990                 return false;
3991         }
3992         else
3993             WriteBits32Unknown (Rt);
3994     }
3995     return true;
3996 }
3997 
3998 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
3999 // from a base register.  The consecutive memory locations start at this address, and teh address just above the last
4000 // of those locations can optionally be written back to the base register.
4001 bool
4002 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding)
4003 {
4004 #if 0
4005     if ConditionPassed() then
4006         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4007         address = R[n];
4008 
4009         for i = 0 to 14
4010             if registers<i> == '1' then
4011                 if i == n && wback && i != LowestSetBit(registers) then
4012                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4013                 else
4014                     MemA[address,4] = R[i];
4015                 address = address + 4;
4016 
4017         if registers<15> == '1' then // Only possible for encoding A1
4018             MemA[address,4] = PCStoreValue();
4019         if wback then R[n] = R[n] + 4*BitCount(registers);
4020 #endif
4021 
4022     bool success = false;
4023 
4024     if (ConditionPassed(opcode))
4025     {
4026         uint32_t n;
4027         uint32_t registers = 0;
4028         bool wback;
4029         const uint32_t addr_byte_size = GetAddressByteSize();
4030 
4031         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4032         switch (encoding)
4033         {
4034             case eEncodingT1:
4035                 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4036                 n = Bits32 (opcode, 10, 8);
4037                 registers = Bits32 (opcode, 7, 0);
4038                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
4039                 wback = true;
4040 
4041                 // if BitCount(registers) < 1 then UNPREDICTABLE;
4042                 if (BitCount (registers) < 1)
4043                     return false;
4044 
4045                 break;
4046 
4047             case eEncodingT2:
4048                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4049                 n = Bits32 (opcode, 19, 16);
4050                 registers = Bits32 (opcode, 15, 0);
4051                 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4052                 wback = BitIsSet (opcode, 21);
4053 
4054                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4055                 if ((n == 15) || (BitCount (registers) < 2))
4056                     return false;
4057 
4058                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4059                 if (wback && BitIsSet (registers, n))
4060                     return false;
4061 
4062                 break;
4063 
4064             case eEncodingA1:
4065                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4066                 n = Bits32 (opcode, 19, 16);
4067                 registers = Bits32 (opcode, 15, 0);
4068                 wback = BitIsSet (opcode, 21);
4069 
4070                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4071                 if ((n == 15) || (BitCount (registers) < 1))
4072                     return false;
4073 
4074                 break;
4075 
4076             default:
4077                 return false;
4078         }
4079 
4080         // address = R[n];
4081         int32_t offset = 0;
4082         const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4083         if (!success)
4084             return false;
4085 
4086         EmulateInstruction::Context context;
4087         context.type = EmulateInstruction::eContextRegisterStore;
4088         RegisterInfo base_reg;
4089         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4090 
4091         // for i = 0 to 14
4092         int lowest_set_bit = 14;
4093         for (int i = 0; i < 14; ++i)
4094         {
4095             // if registers<i> == '1' then
4096             if (BitIsSet (registers, i))
4097             {
4098                   if (i < lowest_set_bit)
4099                       lowest_set_bit = i;
4100                   // if i == n && wback && i != LowestSetBit(registers) then
4101                   if ((i == n) && wback && (i != lowest_set_bit))
4102                       // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4103                       WriteBits32UnknownToMemory (address + offset);
4104                   else
4105                   {
4106                      // MemA[address,4] = R[i];
4107                       uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4108                       if (!success)
4109                           return false;
4110 
4111                       RegisterInfo data_reg;
4112                       GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4113                       context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4114                       if (!MemAWrite (context, address + offset, data, addr_byte_size))
4115                           return false;
4116                   }
4117 
4118                   // address = address + 4;
4119                   offset += addr_byte_size;
4120             }
4121         }
4122 
4123         // if registers<15> == '1' then // Only possible for encoding A1
4124         //     MemA[address,4] = PCStoreValue();
4125         if (BitIsSet (registers, 15))
4126         {
4127             RegisterInfo pc_reg;
4128             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4129             context.SetRegisterPlusOffset (pc_reg, 8);
4130             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4131             if (!success)
4132                 return false;
4133 
4134             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4135                 return false;
4136         }
4137 
4138         // if wback then R[n] = R[n] + 4*BitCount(registers);
4139         if (wback)
4140         {
4141             offset = addr_byte_size * BitCount (registers);
4142             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4143             context.SetImmediateSigned (offset);
4144             addr_t data = address + offset;
4145             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4146                 return false;
4147         }
4148     }
4149     return true;
4150 }
4151 
4152 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
4153 // from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
4154 // of those locations can optionally be written back to the base register.
4155 bool
4156 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding)
4157 {
4158 #if 0
4159     if ConditionPassed() then
4160         EncodingSpecificOperations();
4161         address = R[n] - 4*BitCount(registers) + 4;
4162 
4163         for i = 0 to 14
4164             if registers<i> == '1' then
4165                 if i == n && wback && i != LowestSetBit(registers) then
4166                     MemA[address,4] = bits(32) UNKNOWN;
4167                 else
4168                     MemA[address,4] = R[i];
4169                 address = address + 4;
4170 
4171         if registers<15> == '1' then
4172             MemA[address,4] = PCStoreValue();
4173 
4174         if wback then R[n] = R[n] - 4*BitCount(registers);
4175 #endif
4176 
4177     bool success = false;
4178 
4179     if (ConditionPassed(opcode))
4180     {
4181         uint32_t n;
4182         uint32_t registers = 0;
4183         bool wback;
4184         const uint32_t addr_byte_size = GetAddressByteSize();
4185 
4186         // EncodingSpecificOperations();
4187         switch (encoding)
4188         {
4189             case eEncodingA1:
4190                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4191                 n = Bits32 (opcode, 19, 16);
4192                 registers = Bits32 (opcode, 15, 0);
4193                 wback = BitIsSet (opcode, 21);
4194 
4195                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4196                 if ((n == 15) || (BitCount (registers) < 1))
4197                     return false;
4198                 break;
4199             default:
4200                 return false;
4201         }
4202 
4203         // address = R[n] - 4*BitCount(registers) + 4;
4204         int32_t offset = 0;
4205         addr_t Rn = ReadCoreReg (n, &success);
4206         if (!success)
4207             return false;
4208 
4209         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4;
4210 
4211         EmulateInstruction::Context context;
4212         context.type = EmulateInstruction::eContextRegisterStore;
4213         RegisterInfo base_reg;
4214         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4215 
4216         // for i = 0 to 14
4217         int lowest_bit_set = 14;
4218         for (int i = 0; i < 14; ++i)
4219         {
4220             // if registers<i> == '1' then
4221             if (BitIsSet (registers, i))
4222             {
4223                 if (i < lowest_bit_set)
4224                     lowest_bit_set = i;
4225                 //if i == n && wback && i != LowestSetBit(registers) then
4226                 if ((i == n) && wback && (i != lowest_bit_set))
4227                     // MemA[address,4] = bits(32) UNKNOWN;
4228                     WriteBits32UnknownToMemory (address + offset);
4229                 else
4230                 {
4231                     // MemA[address,4] = R[i];
4232                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4233                     if (!success)
4234                         return false;
4235 
4236                     RegisterInfo data_reg;
4237                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4238                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4239                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4240                         return false;
4241                 }
4242 
4243                 // address = address + 4;
4244                 offset += addr_byte_size;
4245             }
4246         }
4247 
4248         // if registers<15> == '1' then
4249         //    MemA[address,4] = PCStoreValue();
4250         if (BitIsSet (registers, 15))
4251         {
4252             RegisterInfo pc_reg;
4253             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4254             context.SetRegisterPlusOffset (pc_reg, 8);
4255             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4256             if (!success)
4257                 return false;
4258 
4259             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4260                 return false;
4261         }
4262 
4263         // if wback then R[n] = R[n] - 4*BitCount(registers);
4264         if (wback)
4265         {
4266             offset = (addr_byte_size * BitCount (registers)) * -1;
4267             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4268             context.SetImmediateSigned (offset);
4269             addr_t data = Rn + offset;
4270             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4271                 return false;
4272         }
4273     }
4274     return true;
4275 }
4276 
4277 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
4278 // from a base register.  The consecutive memory locations end just below this address, and the address of the first of
4279 // those locations can optionally be written back to the base register.
4280 bool
4281 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding)
4282 {
4283 #if 0
4284     if ConditionPassed() then
4285         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4286         address = R[n] - 4*BitCount(registers);
4287 
4288         for i = 0 to 14
4289             if registers<i> == '1' then
4290                 if i == n && wback && i != LowestSetBit(registers) then
4291                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4292                 else
4293                     MemA[address,4] = R[i];
4294                 address = address + 4;
4295 
4296         if registers<15> == '1' then // Only possible for encoding A1
4297             MemA[address,4] = PCStoreValue();
4298 
4299         if wback then R[n] = R[n] - 4*BitCount(registers);
4300 #endif
4301 
4302 
4303     bool success = false;
4304 
4305     if (ConditionPassed(opcode))
4306     {
4307         uint32_t n;
4308         uint32_t registers = 0;
4309         bool wback;
4310         const uint32_t addr_byte_size = GetAddressByteSize();
4311 
4312         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4313         switch (encoding)
4314         {
4315             case eEncodingT1:
4316                 // if W == '1' && Rn == '1101' then SEE PUSH;
4317                 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
4318                 {
4319                     // See PUSH
4320                 }
4321                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4322                 n = Bits32 (opcode, 19, 16);
4323                 registers = Bits32 (opcode, 15, 0);
4324                 registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
4325                 wback = BitIsSet (opcode, 21);
4326                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4327                 if ((n == 15) || BitCount (registers) < 2)
4328                     return false;
4329                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4330                 if (wback && BitIsSet (registers, n))
4331                     return false;
4332                 break;
4333 
4334             case eEncodingA1:
4335                 // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH;
4336                 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
4337                 {
4338                     // See Push
4339                 }
4340                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4341                 n = Bits32 (opcode, 19, 16);
4342                 registers = Bits32 (opcode, 15, 0);
4343                 wback = BitIsSet (opcode, 21);
4344                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4345                 if ((n == 15) || BitCount (registers) < 1)
4346                     return false;
4347                 break;
4348 
4349             default:
4350                 return false;
4351         }
4352 
4353         // address = R[n] - 4*BitCount(registers);
4354 
4355         int32_t offset = 0;
4356         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4357         if (!success)
4358         return false;
4359 
4360         addr_t address = Rn - (addr_byte_size * BitCount (registers));
4361 
4362         EmulateInstruction::Context context;
4363         context.type = EmulateInstruction::eContextRegisterStore;
4364         RegisterInfo base_reg;
4365         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4366 
4367         // for i = 0 to 14
4368         uint32_t lowest_set_bit = 14;
4369         for (int i = 0; i < 14; ++i)
4370         {
4371             // if registers<i> == '1' then
4372             if (BitIsSet (registers, i))
4373             {
4374                 if (i < lowest_set_bit)
4375                     lowest_set_bit = i;
4376                 // if i == n && wback && i != LowestSetBit(registers) then
4377                 if ((i == n) && wback && (i != lowest_set_bit))
4378                     // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4379                     WriteBits32UnknownToMemory (address + offset);
4380                 else
4381                 {
4382                     // MemA[address,4] = R[i];
4383                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4384                     if (!success)
4385                         return false;
4386 
4387                     RegisterInfo data_reg;
4388                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4389                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4390                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4391                         return false;
4392                 }
4393 
4394                 // address = address + 4;
4395                 offset += addr_byte_size;
4396             }
4397         }
4398 
4399         // if registers<15> == '1' then // Only possible for encoding A1
4400         //     MemA[address,4] = PCStoreValue();
4401         if (BitIsSet (registers, 15))
4402         {
4403             RegisterInfo pc_reg;
4404             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4405             context.SetRegisterPlusOffset (pc_reg, 8);
4406             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4407             if (!success)
4408                 return false;
4409 
4410             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4411                 return false;
4412         }
4413 
4414         // if wback then R[n] = R[n] - 4*BitCount(registers);
4415         if (wback)
4416         {
4417             offset = (addr_byte_size * BitCount (registers)) * -1;
4418             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4419             context.SetImmediateSigned (offset);
4420             addr_t data = Rn + offset;
4421             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4422                 return false;
4423         }
4424     }
4425     return true;
4426 }
4427 
4428 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
4429 // from a base register.  The consecutive memory locations start just above this address, and the address of the last
4430 // of those locations can optionally be written back to the base register.
4431 bool
4432 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding)
4433 {
4434 #if 0
4435     if ConditionPassed() then
4436         EncodingSpecificOperations();
4437         address = R[n] + 4;
4438 
4439         for i = 0 to 14
4440             if registers<i> == '1' then
4441                 if i == n && wback && i != LowestSetBit(registers) then
4442                     MemA[address,4] = bits(32) UNKNOWN;
4443                 else
4444                     MemA[address,4] = R[i];
4445                 address = address + 4;
4446 
4447         if registers<15> == '1' then
4448             MemA[address,4] = PCStoreValue();
4449 
4450         if wback then R[n] = R[n] + 4*BitCount(registers);
4451 #endif
4452 
4453     bool success = false;
4454 
4455     if (ConditionPassed(opcode))
4456     {
4457         uint32_t n;
4458         uint32_t registers = 0;
4459         bool wback;
4460         const uint32_t addr_byte_size = GetAddressByteSize();
4461 
4462         // EncodingSpecificOperations();
4463         switch (encoding)
4464         {
4465             case eEncodingA1:
4466                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4467                 n = Bits32 (opcode, 19, 16);
4468                 registers = Bits32 (opcode, 15, 0);
4469                 wback = BitIsSet (opcode, 21);
4470 
4471                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4472                 if ((n == 15) && (BitCount (registers) < 1))
4473                     return false;
4474                 break;
4475             default:
4476                 return false;
4477         }
4478         // address = R[n] + 4;
4479 
4480         int32_t offset = 0;
4481         addr_t Rn = ReadCoreReg (n, &success);
4482         if (!success)
4483             return false;
4484 
4485         addr_t address = Rn + addr_byte_size;
4486 
4487         EmulateInstruction::Context context;
4488         context.type = EmulateInstruction::eContextRegisterStore;
4489         RegisterInfo base_reg;
4490         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4491 
4492         uint32_t lowest_set_bit = 14;
4493         // for i = 0 to 14
4494         for (int i = 0; i < 14; ++i)
4495         {
4496             // if registers<i> == '1' then
4497             if (BitIsSet (registers, i))
4498             {
4499                 if (i < lowest_set_bit)
4500                     lowest_set_bit = i;
4501                 // if i == n && wback && i != LowestSetBit(registers) then
4502                 if ((i == n) && wback && (i != lowest_set_bit))
4503                     // MemA[address,4] = bits(32) UNKNOWN;
4504                     WriteBits32UnknownToMemory (address + offset);
4505                 // else
4506                 else
4507                 {
4508                     // MemA[address,4] = R[i];
4509                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4510                     if (!success)
4511                         return false;
4512 
4513                     RegisterInfo data_reg;
4514                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4515                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size);
4516                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4517                         return false;
4518                 }
4519 
4520                 // address = address + 4;
4521                 offset += addr_byte_size;
4522             }
4523         }
4524 
4525         // if registers<15> == '1' then
4526             // MemA[address,4] = PCStoreValue();
4527         if (BitIsSet (registers, 15))
4528         {
4529             RegisterInfo pc_reg;
4530             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4531             context.SetRegisterPlusOffset (pc_reg, 8);
4532             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4533             if (!success)
4534             return false;
4535 
4536             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4537                 return false;
4538         }
4539 
4540         // if wback then R[n] = R[n] + 4*BitCount(registers);
4541         if (wback)
4542         {
4543             offset = addr_byte_size * BitCount (registers);
4544             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4545             context.SetImmediateSigned (offset);
4546             addr_t data = Rn + offset;
4547             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4548                 return false;
4549         }
4550     }
4551     return true;
4552 }
4553 
4554 // STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word
4555 // from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
4556 bool
4557 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding)
4558 {
4559 #if 0
4560     if ConditionPassed() then
4561         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4562         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4563         address = if index then offset_addr else R[n];
4564         if UnalignedSupport() || address<1:0> == '00' then
4565             MemU[address,4] = R[t];
4566         else // Can only occur before ARMv7
4567             MemU[address,4] = bits(32) UNKNOWN;
4568         if wback then R[n] = offset_addr;
4569 #endif
4570 
4571     bool success = false;
4572 
4573     if (ConditionPassed(opcode))
4574     {
4575         const uint32_t addr_byte_size = GetAddressByteSize();
4576 
4577         uint32_t t;
4578         uint32_t n;
4579         uint32_t imm32;
4580         bool index;
4581         bool add;
4582         bool wback;
4583         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4584         switch (encoding)
4585         {
4586             case eEncodingT1:
4587                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
4588                 t = Bits32 (opcode, 2, 0);
4589                 n = Bits32 (opcode, 5, 3);
4590                 imm32 = Bits32 (opcode, 10, 6) << 2;
4591 
4592                 // index = TRUE; add = TRUE; wback = FALSE;
4593                 index = true;
4594                 add = false;
4595                 wback = false;
4596                 break;
4597 
4598             case eEncodingT2:
4599                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4600                 t = Bits32 (opcode, 10, 8);
4601                 n = 13;
4602                 imm32 = Bits32 (opcode, 7, 0) << 2;
4603 
4604                 // index = TRUE; add = TRUE; wback = FALSE;
4605                 index = true;
4606                 add = true;
4607                 wback = false;
4608                 break;
4609 
4610             case eEncodingT3:
4611                 // if Rn == '1111' then UNDEFINED;
4612                 if (Bits32 (opcode, 19, 16) == 15)
4613                     return false;
4614 
4615                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4616                 t = Bits32 (opcode, 15, 12);
4617                 n = Bits32 (opcode, 19, 16);
4618                 imm32 = Bits32 (opcode, 11, 0);
4619 
4620                 // index = TRUE; add = TRUE; wback = FALSE;
4621                 index = true;
4622                 add = true;
4623                 wback = false;
4624 
4625                 // if t == 15 then UNPREDICTABLE;
4626                 if (t == 15)
4627                     return false;
4628                 break;
4629 
4630             case eEncodingT4:
4631                 // if P == '1' && U == '1' && W == '0' then SEE STRT;
4632                 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH;
4633                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4634                 if ((Bits32 (opcode, 19, 16) == 15)
4635                       || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
4636                     return false;
4637 
4638                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4639                 t = Bits32 (opcode, 15, 12);
4640                 n = Bits32 (opcode, 19, 16);
4641                 imm32 = Bits32 (opcode, 7, 0);
4642 
4643                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4644                 index = BitIsSet (opcode, 10);
4645                 add = BitIsSet (opcode, 9);
4646                 wback = BitIsSet (opcode, 8);
4647 
4648                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
4649                 if ((t == 15) || (wback && (n == t)))
4650                     return false;
4651                 break;
4652 
4653             default:
4654                 return false;
4655         }
4656 
4657         addr_t offset_addr;
4658         addr_t address;
4659 
4660         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4661         uint32_t base_address = ReadCoreReg (n, &success);
4662         if (!success)
4663             return false;
4664 
4665         if (add)
4666             offset_addr = base_address + imm32;
4667         else
4668             offset_addr = base_address - imm32;
4669 
4670         // address = if index then offset_addr else R[n];
4671         if (index)
4672             address = offset_addr;
4673         else
4674             address = base_address;
4675 
4676         EmulateInstruction::Context context;
4677         context.type = eContextRegisterStore;
4678         RegisterInfo base_reg;
4679         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4680 
4681         // if UnalignedSupport() || address<1:0> == '00' then
4682         if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
4683         {
4684             // MemU[address,4] = R[t];
4685             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4686             if (!success)
4687                 return false;
4688 
4689             RegisterInfo data_reg;
4690             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4691             int32_t offset = address - base_address;
4692             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4693             if (!MemUWrite (context, address, data, addr_byte_size))
4694                 return false;
4695         }
4696         else
4697         {
4698             // MemU[address,4] = bits(32) UNKNOWN;
4699             WriteBits32UnknownToMemory (address);
4700         }
4701 
4702         // if wback then R[n] = offset_addr;
4703         if (wback)
4704         {
4705             context.type = eContextRegisterLoad;
4706             context.SetAddress (offset_addr);
4707             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4708                 return false;
4709         }
4710     }
4711     return true;
4712 }
4713 
4714 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a
4715 // word from a register to memory.   The offset register value can optionally be shifted.
4716 bool
4717 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding)
4718 {
4719 #if 0
4720     if ConditionPassed() then
4721         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4722         offset = Shift(R[m], shift_t, shift_n, APSR.C);
4723         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4724         address = if index then offset_addr else R[n];
4725         if t == 15 then // Only possible for encoding A1
4726             data = PCStoreValue();
4727         else
4728             data = R[t];
4729         if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4730             MemU[address,4] = data;
4731         else // Can only occur before ARMv7
4732             MemU[address,4] = bits(32) UNKNOWN;
4733         if wback then R[n] = offset_addr;
4734 #endif
4735 
4736     bool success = false;
4737 
4738     if (ConditionPassed(opcode))
4739     {
4740         const uint32_t addr_byte_size = GetAddressByteSize();
4741 
4742         uint32_t t;
4743         uint32_t n;
4744         uint32_t m;
4745         ARM_ShifterType shift_t;
4746         uint32_t shift_n;
4747         bool index;
4748         bool add;
4749         bool wback;
4750 
4751         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4752         switch (encoding)
4753         {
4754             case eEncodingT1:
4755                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4756                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4757                 t = Bits32 (opcode, 2, 0);
4758                 n = Bits32 (opcode, 5, 3);
4759                 m = Bits32 (opcode, 8, 6);
4760 
4761                 // index = TRUE; add = TRUE; wback = FALSE;
4762                 index = true;
4763                 add = true;
4764                 wback = false;
4765 
4766                 // (shift_t, shift_n) = (SRType_LSL, 0);
4767                 shift_t = SRType_LSL;
4768                 shift_n = 0;
4769                 break;
4770 
4771             case eEncodingT2:
4772                 // if Rn == '1111' then UNDEFINED;
4773                 if (Bits32 (opcode, 19, 16) == 15)
4774                     return false;
4775 
4776                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4777                 t = Bits32 (opcode, 15, 12);
4778                 n = Bits32 (opcode, 19, 16);
4779                 m = Bits32 (opcode, 3, 0);
4780 
4781                 // index = TRUE; add = TRUE; wback = FALSE;
4782                 index = true;
4783                 add = true;
4784                 wback = false;
4785 
4786                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4787                 shift_t = SRType_LSL;
4788                 shift_n = Bits32 (opcode, 5, 4);
4789 
4790                 // if t == 15 || BadReg(m) then UNPREDICTABLE;
4791                 if ((t == 15) || (BadReg (m)))
4792                     return false;
4793                 break;
4794 
4795             case eEncodingA1:
4796             {
4797                 // if P == '0' && W == '1' then SEE STRT;
4798                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4799                 t = Bits32 (opcode, 15, 12);
4800                 n = Bits32 (opcode, 19, 16);
4801                 m = Bits32 (opcode, 3, 0);
4802 
4803                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
4804                 index = BitIsSet (opcode, 24);
4805                 add = BitIsSet (opcode, 23);
4806                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
4807 
4808                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
4809                 uint32_t typ = Bits32 (opcode, 6, 5);
4810                 uint32_t imm5 = Bits32 (opcode, 11, 7);
4811                 shift_n = DecodeImmShift(typ, imm5, shift_t);
4812 
4813                 // if m == 15 then UNPREDICTABLE;
4814                 if (m == 15)
4815                     return false;
4816 
4817                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
4818                 if (wback && ((n == 15) || (n == t)))
4819                     return false;
4820 
4821                 break;
4822             }
4823             default:
4824                 return false;
4825         }
4826 
4827         addr_t offset_addr;
4828         addr_t address;
4829         int32_t offset = 0;
4830 
4831         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4832         if (!success)
4833             return false;
4834 
4835         uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
4836         if (!success)
4837             return false;
4838 
4839         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4840         offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success);
4841         if (!success)
4842             return false;
4843 
4844         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4845         if (add)
4846             offset_addr = base_address + offset;
4847         else
4848             offset_addr = base_address - offset;
4849 
4850         // address = if index then offset_addr else R[n];
4851         if (index)
4852             address = offset_addr;
4853         else
4854             address = base_address;
4855 
4856         uint32_t data;
4857         // if t == 15 then // Only possible for encoding A1
4858         if (t == 15)
4859             // data = PCStoreValue();
4860             data = ReadCoreReg (PC_REG, &success);
4861         else
4862             // data = R[t];
4863             data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4864 
4865         if (!success)
4866             return false;
4867 
4868         EmulateInstruction::Context context;
4869         context.type = eContextRegisterStore;
4870 
4871         // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4872         if (UnalignedSupport ()
4873             || (BitIsClear (address, 1) && BitIsClear (address, 0))
4874             || CurrentInstrSet() == eModeARM)
4875         {
4876             // MemU[address,4] = data;
4877 
4878             RegisterInfo base_reg;
4879             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 +  n, base_reg);
4880 
4881             RegisterInfo data_reg;
4882             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4883 
4884             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4885             if (!MemUWrite (context, address, data, addr_byte_size))
4886                 return false;
4887 
4888         }
4889         else
4890             // MemU[address,4] = bits(32) UNKNOWN;
4891             WriteBits32UnknownToMemory (address);
4892 
4893         // if wback then R[n] = offset_addr;
4894         if (wback)
4895         {
4896             context.type = eContextRegisterLoad;
4897             context.SetAddress (offset_addr);
4898             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4899                 return false;
4900         }
4901 
4902     }
4903     return true;
4904 }
4905 
4906 bool
4907 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding)
4908 {
4909 #if 0
4910     if ConditionPassed() then
4911         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4912         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4913         address = if index then offset_addr else R[n];
4914         MemU[address,1] = R[t]<7:0>;
4915         if wback then R[n] = offset_addr;
4916 #endif
4917 
4918 
4919     bool success = false;
4920 
4921     if (ConditionPassed(opcode))
4922     {
4923         uint32_t t;
4924         uint32_t n;
4925         uint32_t imm32;
4926         bool index;
4927         bool add;
4928         bool wback;
4929         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4930         switch (encoding)
4931         {
4932             case eEncodingT1:
4933                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
4934                 t = Bits32 (opcode, 2, 0);
4935                 n = Bits32 (opcode, 5, 3);
4936                 imm32 = Bits32 (opcode, 10, 6);
4937 
4938                 // index = TRUE; add = TRUE; wback = FALSE;
4939                 index = true;
4940                 add = true;
4941                 wback = false;
4942                 break;
4943 
4944             case eEncodingT2:
4945                 // if Rn == '1111' then UNDEFINED;
4946                 if (Bits32 (opcode, 19, 16) == 15)
4947                     return false;
4948 
4949                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4950                 t = Bits32 (opcode, 15, 12);
4951                 n = Bits32 (opcode, 19, 16);
4952                 imm32 = Bits32 (opcode, 11, 0);
4953 
4954                 // index = TRUE; add = TRUE; wback = FALSE;
4955                 index = true;
4956                 add = true;
4957                 wback = false;
4958 
4959                 // if BadReg(t) then UNPREDICTABLE;
4960                 if (BadReg (t))
4961                     return false;
4962                 break;
4963 
4964             case eEncodingT3:
4965                 // if P == '1' && U == '1' && W == '0' then SEE STRBT;
4966                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4967                 if (Bits32 (opcode, 19, 16) == 15)
4968                     return false;
4969 
4970                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4971                 t = Bits32 (opcode, 15, 12);
4972                 n = Bits32 (opcode, 19, 16);
4973                 imm32 = Bits32 (opcode, 7, 0);
4974 
4975                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4976                 index = BitIsSet (opcode, 10);
4977                 add = BitIsSet (opcode, 9);
4978                 wback = BitIsSet (opcode, 8);
4979 
4980                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
4981                 if ((BadReg (t)) || (wback && (n == t)))
4982                     return false;
4983                 break;
4984 
4985             default:
4986                 return false;
4987         }
4988 
4989         addr_t offset_addr;
4990         addr_t address;
4991         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4992         if (!success)
4993             return false;
4994 
4995         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4996         if (add)
4997             offset_addr = base_address + imm32;
4998         else
4999             offset_addr = base_address - imm32;
5000 
5001         // address = if index then offset_addr else R[n];
5002         if (index)
5003             address = offset_addr;
5004         else
5005             address = base_address;
5006 
5007         // MemU[address,1] = R[t]<7:0>
5008         RegisterInfo base_reg;
5009         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5010 
5011         RegisterInfo data_reg;
5012         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5013 
5014         EmulateInstruction::Context context;
5015         context.type = eContextRegisterStore;
5016         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
5017 
5018         uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5019         if (!success)
5020             return false;
5021 
5022         data = Bits32 (data, 7, 0);
5023 
5024         if (!MemUWrite (context, address, data, 1))
5025             return false;
5026 
5027         // if wback then R[n] = offset_addr;
5028         if (wback)
5029         {
5030             context.type = eContextRegisterLoad;
5031             context.SetAddress (offset_addr);
5032             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5033                 return false;
5034         }
5035 
5036     }
5037 
5038     return true;
5039 }
5040 
5041 // STRH (register) calculates an address from a base register value and an offset register value, and stores a
5042 // halfword from a register to memory.  The offset register alue can be shifted left by 0, 1, 2, or 3 bits.
5043 bool
5044 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding)
5045 {
5046 #if 0
5047     if ConditionPassed() then
5048         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5049         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5050         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5051         address = if index then offset_addr else R[n];
5052         if UnalignedSupport() || address<0> == '0' then
5053             MemU[address,2] = R[t]<15:0>;
5054         else // Can only occur before ARMv7
5055             MemU[address,2] = bits(16) UNKNOWN;
5056         if wback then R[n] = offset_addr;
5057 #endif
5058 
5059     bool success = false;
5060 
5061     if (ConditionPassed(opcode))
5062     {
5063         uint32_t t;
5064         uint32_t n;
5065         uint32_t m;
5066         bool index;
5067         bool add;
5068         bool wback;
5069         ARM_ShifterType shift_t;
5070         uint32_t shift_n;
5071 
5072         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5073         switch (encoding)
5074         {
5075             case eEncodingT1:
5076                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5077                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5078                 t = Bits32 (opcode, 2, 0);
5079                 n = Bits32 (opcode, 5, 3);
5080                 m = Bits32 (opcode, 8, 6);
5081 
5082                 // index = TRUE; add = TRUE; wback = FALSE;
5083                 index = true;
5084                 add = true;
5085                 wback = false;
5086 
5087                 // (shift_t, shift_n) = (SRType_LSL, 0);
5088                 shift_t = SRType_LSL;
5089                 shift_n = 0;
5090 
5091                 break;
5092 
5093             case eEncodingT2:
5094                 // if Rn == '1111' then UNDEFINED;
5095                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5096                 t = Bits32 (opcode, 15, 12);
5097                 n = Bits32 (opcode, 19, 16);
5098                 m = Bits32 (opcode, 3, 0);
5099                 if (n == 15)
5100                     return false;
5101 
5102                 // index = TRUE; add = TRUE; wback = FALSE;
5103                 index = true;
5104                 add = true;
5105                 wback = false;
5106 
5107                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5108                 shift_t = SRType_LSL;
5109                 shift_n = Bits32 (opcode, 5, 4);
5110 
5111                 // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5112                 if (BadReg (t) || BadReg (m))
5113                     return false;
5114 
5115                 break;
5116 
5117             case eEncodingA1:
5118                 // if P == '0' && W == '1' then SEE STRHT;
5119                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5120                 t = Bits32 (opcode, 15, 12);
5121                 n = Bits32 (opcode, 19, 16);
5122                 m = Bits32 (opcode, 3, 0);
5123 
5124                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5125                 index = BitIsSet (opcode, 24);
5126                 add = BitIsSet (opcode, 23);
5127                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5128 
5129                 // (shift_t, shift_n) = (SRType_LSL, 0);
5130                 shift_t = SRType_LSL;
5131                 shift_n = 0;
5132 
5133                 // if t == 15 || m == 15 then UNPREDICTABLE;
5134                 if ((t == 15) || (m == 15))
5135                     return false;
5136 
5137                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5138                 if (wback && ((n == 15) || (n == t)))
5139                     return false;
5140 
5141                 break;
5142 
5143             default:
5144                 return false;
5145         }
5146 
5147         uint32_t Rm = ReadCoreReg (m, &success);
5148         if (!success)
5149             return false;
5150 
5151         uint32_t Rn = ReadCoreReg (n, &success);
5152         if (!success)
5153             return false;
5154 
5155         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5156         uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
5157         if (!success)
5158             return false;
5159 
5160         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5161         addr_t offset_addr;
5162         if (add)
5163             offset_addr = Rn + offset;
5164         else
5165             offset_addr = Rn - offset;
5166 
5167         // address = if index then offset_addr else R[n];
5168         addr_t address;
5169         if (index)
5170             address = offset_addr;
5171         else
5172             address = Rn;
5173 
5174         EmulateInstruction::Context context;
5175         context.type = eContextRegisterStore;
5176         RegisterInfo base_reg;
5177         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5178         RegisterInfo offset_reg;
5179         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5180 
5181         // if UnalignedSupport() || address<0> == '0' then
5182         if (UnalignedSupport() || BitIsClear (address, 0))
5183         {
5184             // MemU[address,2] = R[t]<15:0>;
5185             uint32_t Rt = ReadCoreReg (t, &success);
5186             if (!success)
5187                 return false;
5188 
5189             EmulateInstruction::Context context;
5190             context.type = eContextRegisterStore;
5191             RegisterInfo base_reg;
5192             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5193             RegisterInfo offset_reg;
5194             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5195             RegisterInfo data_reg;
5196             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5197             context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
5198 
5199             if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2))
5200                 return false;
5201         }
5202         else // Can only occur before ARMv7
5203         {
5204             // MemU[address,2] = bits(16) UNKNOWN;
5205         }
5206 
5207         // if wback then R[n] = offset_addr;
5208         if (wback)
5209         {
5210             context.type = eContextAdjustBaseRegister;
5211             context.SetAddress (offset_addr);
5212             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5213                 return false;
5214         }
5215     }
5216 
5217     return true;
5218 }
5219 
5220 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value,
5221 // and writes the result to the destination register.  It can optionally update the condition flags
5222 // based on the result.
5223 bool
5224 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding)
5225 {
5226 #if 0
5227     // ARM pseudo code...
5228     if ConditionPassed() then
5229         EncodingSpecificOperations();
5230         (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5231         if d == 15 then         // Can only occur for ARM encoding
5232             ALUWritePC(result); // setflags is always FALSE here
5233         else
5234             R[d] = result;
5235             if setflags then
5236                 APSR.N = result<31>;
5237                 APSR.Z = IsZeroBit(result);
5238                 APSR.C = carry;
5239                 APSR.V = overflow;
5240 #endif
5241 
5242     bool success = false;
5243 
5244     if (ConditionPassed(opcode))
5245     {
5246         uint32_t Rd, Rn;
5247         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
5248         bool setflags;
5249         switch (encoding)
5250         {
5251         case eEncodingT1:
5252             Rd = Bits32(opcode, 11, 8);
5253             Rn = Bits32(opcode, 19, 16);
5254             setflags = BitIsSet(opcode, 20);
5255             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5256             if (BadReg(Rd) || BadReg(Rn))
5257                 return false;
5258             break;
5259         case eEncodingA1:
5260             Rd = Bits32(opcode, 15, 12);
5261             Rn = Bits32(opcode, 19, 16);
5262             setflags = BitIsSet(opcode, 20);
5263             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5264 
5265             if (Rd == 15 && setflags)
5266                 return EmulateSUBSPcLrEtc (opcode, encoding);
5267             break;
5268         default:
5269             return false;
5270         }
5271 
5272         // Read the first operand.
5273         int32_t val1 = ReadCoreReg(Rn, &success);
5274         if (!success)
5275             return false;
5276 
5277         AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5278 
5279         EmulateInstruction::Context context;
5280         context.type = EmulateInstruction::eContextImmediate;
5281         context.SetNoArgs ();
5282 
5283         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5284             return false;
5285     }
5286     return true;
5287 }
5288 
5289 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted
5290 // register value, and writes the result to the destination register.  It can optionally update the
5291 // condition flags based on the result.
5292 bool
5293 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding)
5294 {
5295 #if 0
5296     // ARM pseudo code...
5297     if ConditionPassed() then
5298         EncodingSpecificOperations();
5299         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5300         (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5301         if d == 15 then         // Can only occur for ARM encoding
5302             ALUWritePC(result); // setflags is always FALSE here
5303         else
5304             R[d] = result;
5305             if setflags then
5306                 APSR.N = result<31>;
5307                 APSR.Z = IsZeroBit(result);
5308                 APSR.C = carry;
5309                 APSR.V = overflow;
5310 #endif
5311 
5312     bool success = false;
5313 
5314     if (ConditionPassed(opcode))
5315     {
5316         uint32_t Rd, Rn, Rm;
5317         ARM_ShifterType shift_t;
5318         uint32_t shift_n; // the shift applied to the value read from Rm
5319         bool setflags;
5320         switch (encoding)
5321         {
5322         case eEncodingT1:
5323             Rd = Rn = Bits32(opcode, 2, 0);
5324             Rm = Bits32(opcode, 5, 3);
5325             setflags = !InITBlock();
5326             shift_t = SRType_LSL;
5327             shift_n = 0;
5328             break;
5329         case eEncodingT2:
5330             Rd = Bits32(opcode, 11, 8);
5331             Rn = Bits32(opcode, 19, 16);
5332             Rm = Bits32(opcode, 3, 0);
5333             setflags = BitIsSet(opcode, 20);
5334             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5335             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5336                 return false;
5337             break;
5338         case eEncodingA1:
5339             Rd = Bits32(opcode, 15, 12);
5340             Rn = Bits32(opcode, 19, 16);
5341             Rm = Bits32(opcode, 3, 0);
5342             setflags = BitIsSet(opcode, 20);
5343             shift_n = DecodeImmShiftARM(opcode, shift_t);
5344 
5345             if (Rd == 15 && setflags)
5346                 return EmulateSUBSPcLrEtc (opcode, encoding);
5347             break;
5348         default:
5349             return false;
5350         }
5351 
5352         // Read the first operand.
5353         int32_t val1 = ReadCoreReg(Rn, &success);
5354         if (!success)
5355             return false;
5356 
5357         // Read the second operand.
5358         int32_t val2 = ReadCoreReg(Rm, &success);
5359         if (!success)
5360             return false;
5361 
5362         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5363         if (!success)
5364             return false;
5365         AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5366 
5367         EmulateInstruction::Context context;
5368         context.type = EmulateInstruction::eContextImmediate;
5369         context.SetNoArgs ();
5370 
5371         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5372             return false;
5373     }
5374     return true;
5375 }
5376 
5377 // This instruction adds an immediate value to the PC value to form a PC-relative address,
5378 // and writes the result to the destination register.
5379 bool
5380 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding)
5381 {
5382 #if 0
5383     // ARM pseudo code...
5384     if ConditionPassed() then
5385         EncodingSpecificOperations();
5386         result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5387         if d == 15 then         // Can only occur for ARM encodings
5388             ALUWritePC(result);
5389         else
5390             R[d] = result;
5391 #endif
5392 
5393     bool success = false;
5394 
5395     if (ConditionPassed(opcode))
5396     {
5397         uint32_t Rd;
5398         uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5399         bool add;
5400         switch (encoding)
5401         {
5402         case eEncodingT1:
5403             Rd = Bits32(opcode, 10, 8);
5404             imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5405             add = true;
5406             break;
5407         case eEncodingT2:
5408         case eEncodingT3:
5409             Rd = Bits32(opcode, 11, 8);
5410             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5411             add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5412             if (BadReg(Rd))
5413                 return false;
5414             break;
5415         case eEncodingA1:
5416         case eEncodingA2:
5417             Rd = Bits32(opcode, 15, 12);
5418             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5419             add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5420             break;
5421         default:
5422             return false;
5423         }
5424 
5425         // Read the PC value.
5426         uint32_t pc = ReadCoreReg(PC_REG, &success);
5427         if (!success)
5428             return false;
5429 
5430         uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5431 
5432         EmulateInstruction::Context context;
5433         context.type = EmulateInstruction::eContextImmediate;
5434         context.SetNoArgs ();
5435 
5436         if (!WriteCoreReg(context, result, Rd))
5437             return false;
5438     }
5439     return true;
5440 }
5441 
5442 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result
5443 // to the destination register.  It can optionally update the condition flags based on the result.
5444 bool
5445 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding)
5446 {
5447 #if 0
5448     // ARM pseudo code...
5449     if ConditionPassed() then
5450         EncodingSpecificOperations();
5451         result = R[n] AND imm32;
5452         if d == 15 then         // Can only occur for ARM encoding
5453             ALUWritePC(result); // setflags is always FALSE here
5454         else
5455             R[d] = result;
5456             if setflags then
5457                 APSR.N = result<31>;
5458                 APSR.Z = IsZeroBit(result);
5459                 APSR.C = carry;
5460                 // APSR.V unchanged
5461 #endif
5462 
5463     bool success = false;
5464 
5465     if (ConditionPassed(opcode))
5466     {
5467         uint32_t Rd, Rn;
5468         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
5469         bool setflags;
5470         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5471         switch (encoding)
5472         {
5473         case eEncodingT1:
5474             Rd = Bits32(opcode, 11, 8);
5475             Rn = Bits32(opcode, 19, 16);
5476             setflags = BitIsSet(opcode, 20);
5477             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5478             // if Rd == '1111' && S == '1' then SEE TST (immediate);
5479             if (Rd == 15 && setflags)
5480                 return EmulateTSTImm(opcode, eEncodingT1);
5481             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
5482                 return false;
5483             break;
5484         case eEncodingA1:
5485             Rd = Bits32(opcode, 15, 12);
5486             Rn = Bits32(opcode, 19, 16);
5487             setflags = BitIsSet(opcode, 20);
5488             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5489 
5490             if (Rd == 15 && setflags)
5491                 return EmulateSUBSPcLrEtc (opcode, encoding);
5492             break;
5493         default:
5494             return false;
5495         }
5496 
5497         // Read the first operand.
5498         uint32_t val1 = ReadCoreReg(Rn, &success);
5499         if (!success)
5500             return false;
5501 
5502         uint32_t result = val1 & imm32;
5503 
5504         EmulateInstruction::Context context;
5505         context.type = EmulateInstruction::eContextImmediate;
5506         context.SetNoArgs ();
5507 
5508         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5509             return false;
5510     }
5511     return true;
5512 }
5513 
5514 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value,
5515 // and writes the result to the destination register.  It can optionally update the condition flags
5516 // based on the result.
5517 bool
5518 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding)
5519 {
5520 #if 0
5521     // ARM pseudo code...
5522     if ConditionPassed() then
5523         EncodingSpecificOperations();
5524         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5525         result = R[n] AND shifted;
5526         if d == 15 then         // Can only occur for ARM encoding
5527             ALUWritePC(result); // setflags is always FALSE here
5528         else
5529             R[d] = result;
5530             if setflags then
5531                 APSR.N = result<31>;
5532                 APSR.Z = IsZeroBit(result);
5533                 APSR.C = carry;
5534                 // APSR.V unchanged
5535 #endif
5536 
5537     bool success = false;
5538 
5539     if (ConditionPassed(opcode))
5540     {
5541         uint32_t Rd, Rn, Rm;
5542         ARM_ShifterType shift_t;
5543         uint32_t shift_n; // the shift applied to the value read from Rm
5544         bool setflags;
5545         uint32_t carry;
5546         switch (encoding)
5547         {
5548         case eEncodingT1:
5549             Rd = Rn = Bits32(opcode, 2, 0);
5550             Rm = Bits32(opcode, 5, 3);
5551             setflags = !InITBlock();
5552             shift_t = SRType_LSL;
5553             shift_n = 0;
5554             break;
5555         case eEncodingT2:
5556             Rd = Bits32(opcode, 11, 8);
5557             Rn = Bits32(opcode, 19, 16);
5558             Rm = Bits32(opcode, 3, 0);
5559             setflags = BitIsSet(opcode, 20);
5560             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5561             // if Rd == '1111' && S == '1' then SEE TST (register);
5562             if (Rd == 15 && setflags)
5563                 return EmulateTSTReg(opcode, eEncodingT2);
5564             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
5565                 return false;
5566             break;
5567         case eEncodingA1:
5568             Rd = Bits32(opcode, 15, 12);
5569             Rn = Bits32(opcode, 19, 16);
5570             Rm = Bits32(opcode, 3, 0);
5571             setflags = BitIsSet(opcode, 20);
5572             shift_n = DecodeImmShiftARM(opcode, shift_t);
5573 
5574             if (Rd == 15 && setflags)
5575                 return EmulateSUBSPcLrEtc (opcode, encoding);
5576             break;
5577         default:
5578             return false;
5579         }
5580 
5581         // Read the first operand.
5582         uint32_t val1 = ReadCoreReg(Rn, &success);
5583         if (!success)
5584             return false;
5585 
5586         // Read the second operand.
5587         uint32_t val2 = ReadCoreReg(Rm, &success);
5588         if (!success)
5589             return false;
5590 
5591         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5592         if (!success)
5593             return false;
5594         uint32_t result = val1 & shifted;
5595 
5596         EmulateInstruction::Context context;
5597         context.type = EmulateInstruction::eContextImmediate;
5598         context.SetNoArgs ();
5599 
5600         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5601             return false;
5602     }
5603     return true;
5604 }
5605 
5606 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an
5607 // immediate value, and writes the result to the destination register.  It can optionally update the
5608 // condition flags based on the result.
5609 bool
5610 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding)
5611 {
5612 #if 0
5613     // ARM pseudo code...
5614     if ConditionPassed() then
5615         EncodingSpecificOperations();
5616         result = R[n] AND NOT(imm32);
5617         if d == 15 then         // Can only occur for ARM encoding
5618             ALUWritePC(result); // setflags is always FALSE here
5619         else
5620             R[d] = result;
5621             if setflags then
5622                 APSR.N = result<31>;
5623                 APSR.Z = IsZeroBit(result);
5624                 APSR.C = carry;
5625                 // APSR.V unchanged
5626 #endif
5627 
5628     bool success = false;
5629 
5630     if (ConditionPassed(opcode))
5631     {
5632         uint32_t Rd, Rn;
5633         uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn
5634         bool setflags;
5635         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5636         switch (encoding)
5637         {
5638         case eEncodingT1:
5639             Rd = Bits32(opcode, 11, 8);
5640             Rn = Bits32(opcode, 19, 16);
5641             setflags = BitIsSet(opcode, 20);
5642             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5643             if (BadReg(Rd) || BadReg(Rn))
5644                 return false;
5645             break;
5646         case eEncodingA1:
5647             Rd = Bits32(opcode, 15, 12);
5648             Rn = Bits32(opcode, 19, 16);
5649             setflags = BitIsSet(opcode, 20);
5650             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5651 
5652             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5653             if (Rd == 15 && setflags)
5654                 return EmulateSUBSPcLrEtc (opcode, encoding);
5655             break;
5656         default:
5657             return false;
5658         }
5659 
5660         // Read the first operand.
5661         uint32_t val1 = ReadCoreReg(Rn, &success);
5662         if (!success)
5663             return false;
5664 
5665         uint32_t result = val1 & ~imm32;
5666 
5667         EmulateInstruction::Context context;
5668         context.type = EmulateInstruction::eContextImmediate;
5669         context.SetNoArgs ();
5670 
5671         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5672             return false;
5673     }
5674     return true;
5675 }
5676 
5677 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an
5678 // optionally-shifted register value, and writes the result to the destination register.
5679 // It can optionally update the condition flags based on the result.
5680 bool
5681 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding)
5682 {
5683 #if 0
5684     // ARM pseudo code...
5685     if ConditionPassed() then
5686         EncodingSpecificOperations();
5687         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5688         result = R[n] AND NOT(shifted);
5689         if d == 15 then         // Can only occur for ARM encoding
5690             ALUWritePC(result); // setflags is always FALSE here
5691         else
5692             R[d] = result;
5693             if setflags then
5694                 APSR.N = result<31>;
5695                 APSR.Z = IsZeroBit(result);
5696                 APSR.C = carry;
5697                 // APSR.V unchanged
5698 #endif
5699 
5700     bool success = false;
5701 
5702     if (ConditionPassed(opcode))
5703     {
5704         uint32_t Rd, Rn, Rm;
5705         ARM_ShifterType shift_t;
5706         uint32_t shift_n; // the shift applied to the value read from Rm
5707         bool setflags;
5708         uint32_t carry;
5709         switch (encoding)
5710         {
5711         case eEncodingT1:
5712             Rd = Rn = Bits32(opcode, 2, 0);
5713             Rm = Bits32(opcode, 5, 3);
5714             setflags = !InITBlock();
5715             shift_t = SRType_LSL;
5716             shift_n = 0;
5717             break;
5718         case eEncodingT2:
5719             Rd = Bits32(opcode, 11, 8);
5720             Rn = Bits32(opcode, 19, 16);
5721             Rm = Bits32(opcode, 3, 0);
5722             setflags = BitIsSet(opcode, 20);
5723             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5724             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5725                 return false;
5726             break;
5727         case eEncodingA1:
5728             Rd = Bits32(opcode, 15, 12);
5729             Rn = Bits32(opcode, 19, 16);
5730             Rm = Bits32(opcode, 3, 0);
5731             setflags = BitIsSet(opcode, 20);
5732             shift_n = DecodeImmShiftARM(opcode, shift_t);
5733 
5734             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5735             if (Rd == 15 && setflags)
5736                 return EmulateSUBSPcLrEtc (opcode, encoding);
5737             break;
5738         default:
5739             return false;
5740         }
5741 
5742         // Read the first operand.
5743         uint32_t val1 = ReadCoreReg(Rn, &success);
5744         if (!success)
5745             return false;
5746 
5747         // Read the second operand.
5748         uint32_t val2 = ReadCoreReg(Rm, &success);
5749         if (!success)
5750             return false;
5751 
5752         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5753         if (!success)
5754             return false;
5755         uint32_t result = val1 & ~shifted;
5756 
5757         EmulateInstruction::Context context;
5758         context.type = EmulateInstruction::eContextImmediate;
5759         context.SetNoArgs ();
5760 
5761         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5762             return false;
5763     }
5764     return true;
5765 }
5766 
5767 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
5768 // from memory, and writes it to a register.  It can use offset, post-indexed, or pre-indexed addressing.
5769 bool
5770 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding)
5771 {
5772 #if 0
5773     if ConditionPassed() then
5774         EncodingSpecificOperations();
5775         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5776         address = if index then offset_addr else R[n];
5777         data = MemU[address,4];
5778         if wback then R[n] = offset_addr;
5779         if t == 15 then
5780             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5781         elsif UnalignedSupport() || address<1:0> = '00' then
5782             R[t] = data;
5783         else // Can only apply before ARMv7
5784             R[t] = ROR(data, 8*UInt(address<1:0>));
5785 #endif
5786 
5787     bool success = false;
5788 
5789     if (ConditionPassed(opcode))
5790     {
5791         const uint32_t addr_byte_size = GetAddressByteSize();
5792 
5793         uint32_t t;
5794         uint32_t n;
5795         uint32_t imm32;
5796         bool index;
5797         bool add;
5798         bool wback;
5799 
5800         switch (encoding)
5801         {
5802             case eEncodingA1:
5803                 // if Rn == '1111' then SEE LDR (literal);
5804                 // if P == '0' && W == '1' then SEE LDRT;
5805                 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP;
5806                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5807                 t = Bits32 (opcode, 15, 12);
5808                 n = Bits32 (opcode, 19, 16);
5809                 imm32 = Bits32 (opcode, 11, 0);
5810 
5811                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5812                 index = BitIsSet (opcode, 24);
5813                 add = BitIsSet (opcode, 23);
5814                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5815 
5816                 // if wback && n == t then UNPREDICTABLE;
5817                 if (wback && (n == t))
5818                     return false;
5819 
5820                 break;
5821 
5822             default:
5823                 return false;
5824         }
5825 
5826         addr_t address;
5827         addr_t offset_addr;
5828         addr_t base_address = ReadCoreReg (n, &success);
5829         if (!success)
5830             return false;
5831 
5832         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5833         if (add)
5834             offset_addr = base_address + imm32;
5835         else
5836             offset_addr = base_address - imm32;
5837 
5838         // address = if index then offset_addr else R[n];
5839         if (index)
5840             address = offset_addr;
5841         else
5842             address = base_address;
5843 
5844         // data = MemU[address,4];
5845 
5846         RegisterInfo base_reg;
5847         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5848 
5849         EmulateInstruction::Context context;
5850         context.type = eContextRegisterLoad;
5851         context.SetRegisterPlusOffset (base_reg, address - base_address);
5852 
5853         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5854         if (!success)
5855             return false;
5856 
5857         // if wback then R[n] = offset_addr;
5858         if (wback)
5859         {
5860             context.type = eContextAdjustBaseRegister;
5861             context.SetAddress (offset_addr);
5862             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5863                 return false;
5864         }
5865 
5866         // if t == 15 then
5867         if (t == 15)
5868         {
5869             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5870             if (BitIsClear (address, 1) && BitIsClear (address, 0))
5871             {
5872                 // LoadWritePC (data);
5873                 context.type = eContextRegisterLoad;
5874                 context.SetRegisterPlusOffset (base_reg, address - base_address);
5875                 LoadWritePC (context, data);
5876             }
5877             else
5878                   return false;
5879         }
5880         // elsif UnalignedSupport() || address<1:0> = '00' then
5881         else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5882         {
5883             // R[t] = data;
5884             context.type = eContextRegisterLoad;
5885             context.SetRegisterPlusOffset (base_reg, address - base_address);
5886             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5887                 return false;
5888         }
5889         // else // Can only apply before ARMv7
5890         else
5891         {
5892             // R[t] = ROR(data, 8*UInt(address<1:0>));
5893             data = ROR (data, Bits32 (address, 1, 0), &success);
5894             if (!success)
5895                 return false;
5896             context.type = eContextRegisterLoad;
5897             context.SetImmediate (data);
5898             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5899                 return false;
5900         }
5901 
5902     }
5903     return true;
5904 }
5905 
5906 // LDR (register) calculates an address from a base register value and an offset register value, loads a word
5907 // from memory, and writes it to a resgister.  The offset register value can optionally be shifted.
5908 bool
5909 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding)
5910 {
5911 #if 0
5912     if ConditionPassed() then
5913         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5914         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5915         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5916         address = if index then offset_addr else R[n];
5917         data = MemU[address,4];
5918         if wback then R[n] = offset_addr;
5919         if t == 15 then
5920             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5921         elsif UnalignedSupport() || address<1:0> = '00' then
5922             R[t] = data;
5923         else // Can only apply before ARMv7
5924             if CurrentInstrSet() == InstrSet_ARM then
5925                 R[t] = ROR(data, 8*UInt(address<1:0>));
5926             else
5927                 R[t] = bits(32) UNKNOWN;
5928 #endif
5929 
5930     bool success = false;
5931 
5932     if (ConditionPassed(opcode))
5933     {
5934         const uint32_t addr_byte_size = GetAddressByteSize();
5935 
5936         uint32_t t;
5937         uint32_t n;
5938         uint32_t m;
5939         bool index;
5940         bool add;
5941         bool wback;
5942         ARM_ShifterType shift_t;
5943         uint32_t shift_n;
5944 
5945         switch (encoding)
5946         {
5947             case eEncodingT1:
5948                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5949                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5950                 t = Bits32 (opcode, 2, 0);
5951                 n = Bits32 (opcode, 5, 3);
5952                 m = Bits32 (opcode, 8, 6);
5953 
5954                 // index = TRUE; add = TRUE; wback = FALSE;
5955                 index = true;
5956                 add = true;
5957                 wback = false;
5958 
5959                 // (shift_t, shift_n) = (SRType_LSL, 0);
5960                 shift_t = SRType_LSL;
5961                 shift_n = 0;
5962 
5963                 break;
5964 
5965             case eEncodingT2:
5966                 // if Rn == '1111' then SEE LDR (literal);
5967                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5968                 t = Bits32 (opcode, 15, 12);
5969                 n = Bits32 (opcode, 19, 16);
5970                 m = Bits32 (opcode, 3, 0);
5971 
5972                 // index = TRUE; add = TRUE; wback = FALSE;
5973                 index = true;
5974                 add = true;
5975                 wback = false;
5976 
5977                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5978                 shift_t = SRType_LSL;
5979                 shift_n = Bits32 (opcode, 5, 4);
5980 
5981                 // if BadReg(m) then UNPREDICTABLE;
5982                 if (BadReg (m))
5983                     return false;
5984 
5985                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
5986                 if ((t == 15) && InITBlock() && !LastInITBlock())
5987                     return false;
5988 
5989                 break;
5990 
5991             case eEncodingA1:
5992             {
5993                 // if P == '0' && W == '1' then SEE LDRT;
5994                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5995                 t = Bits32 (opcode, 15, 12);
5996                 n = Bits32 (opcode, 19, 16);
5997                 m = Bits32 (opcode, 3, 0);
5998 
5999                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6000                 index = BitIsSet (opcode, 24);
6001                 add = BitIsSet (opcode, 23);
6002                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6003 
6004                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6005                 uint32_t type = Bits32 (opcode, 6, 5);
6006                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6007                 shift_n = DecodeImmShift (type, imm5, shift_t);
6008 
6009                 // if m == 15 then UNPREDICTABLE;
6010                 if (m == 15)
6011                     return false;
6012 
6013                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6014                 if (wback && ((n == 15) || (n == t)))
6015                     return false;
6016             }
6017                 break;
6018 
6019 
6020             default:
6021                 return false;
6022         }
6023 
6024         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6025         if (!success)
6026             return false;
6027 
6028         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6029         if (!success)
6030             return false;
6031 
6032         addr_t offset_addr;
6033         addr_t address;
6034 
6035         // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an application level alias for the CPSR".
6036         addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success);
6037         if (!success)
6038             return false;
6039 
6040         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6041         if (add)
6042             offset_addr = Rn + offset;
6043         else
6044             offset_addr = Rn - offset;
6045 
6046         // address = if index then offset_addr else R[n];
6047             if (index)
6048                 address = offset_addr;
6049             else
6050                 address = Rn;
6051 
6052         // data = MemU[address,4];
6053         RegisterInfo base_reg;
6054         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6055 
6056         EmulateInstruction::Context context;
6057         context.type = eContextRegisterLoad;
6058         context.SetRegisterPlusOffset (base_reg, address - Rn);
6059 
6060         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
6061         if (!success)
6062             return false;
6063 
6064         // if wback then R[n] = offset_addr;
6065         if (wback)
6066         {
6067             context.type = eContextAdjustBaseRegister;
6068             context.SetAddress (offset_addr);
6069             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6070                 return false;
6071         }
6072 
6073         // if t == 15 then
6074         if (t == 15)
6075         {
6076             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6077             if (BitIsClear (address, 1) && BitIsClear (address, 0))
6078             {
6079                 context.type = eContextRegisterLoad;
6080                 context.SetRegisterPlusOffset (base_reg, address - Rn);
6081                 LoadWritePC (context, data);
6082             }
6083             else
6084                 return false;
6085         }
6086         // elsif UnalignedSupport() || address<1:0> = '00' then
6087         else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
6088         {
6089             // R[t] = data;
6090             context.type = eContextRegisterLoad;
6091             context.SetRegisterPlusOffset (base_reg, address - Rn);
6092             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6093                 return false;
6094         }
6095         else // Can only apply before ARMv7
6096         {
6097             // if CurrentInstrSet() == InstrSet_ARM then
6098             if (CurrentInstrSet () == eModeARM)
6099             {
6100                 // R[t] = ROR(data, 8*UInt(address<1:0>));
6101                 data = ROR (data, Bits32 (address, 1, 0), &success);
6102                 if (!success)
6103                     return false;
6104                 context.type = eContextRegisterLoad;
6105                 context.SetImmediate (data);
6106                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6107                     return false;
6108             }
6109             else
6110             {
6111                 // R[t] = bits(32) UNKNOWN;
6112                 WriteBits32Unknown (t);
6113             }
6114         }
6115     }
6116     return true;
6117 }
6118 
6119 // LDRB (immediate, Thumb)
6120 bool
6121 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6122 {
6123 #if 0
6124     if ConditionPassed() then
6125         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6126         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6127         address = if index then offset_addr else R[n];
6128         R[t] = ZeroExtend(MemU[address,1], 32);
6129         if wback then R[n] = offset_addr;
6130 #endif
6131 
6132     bool success = false;
6133 
6134     if (ConditionPassed(opcode))
6135     {
6136         uint32_t t;
6137         uint32_t n;
6138         uint32_t imm32;
6139         bool index;
6140         bool add;
6141         bool wback;
6142 
6143         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6144         switch (encoding)
6145         {
6146             case eEncodingT1:
6147                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6148                 t = Bits32 (opcode, 2, 0);
6149                 n = Bits32 (opcode, 5, 3);
6150                 imm32 = Bits32 (opcode, 10, 6);
6151 
6152                 // index = TRUE; add = TRUE; wback = FALSE;
6153                 index = true;
6154                 add = true;
6155                 wback= false;
6156 
6157                 break;
6158 
6159             case eEncodingT2:
6160                 // if Rt == '1111' then SEE PLD;
6161                 // if Rn == '1111' then SEE LDRB (literal);
6162                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6163                 t = Bits32 (opcode, 15, 12);
6164                 n = Bits32 (opcode, 19, 16);
6165                 imm32 = Bits32 (opcode, 11, 0);
6166 
6167                 // index = TRUE; add = TRUE; wback = FALSE;
6168                 index = true;
6169                 add = true;
6170                 wback = false;
6171 
6172                 // if t == 13 then UNPREDICTABLE;
6173                 if (t == 13)
6174                     return false;
6175 
6176                 break;
6177 
6178             case eEncodingT3:
6179                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6180                 // if Rn == '1111' then SEE LDRB (literal);
6181                 // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6182                 // if P == '0' && W == '0' then UNDEFINED;
6183                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6184                     return false;
6185 
6186                   // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6187                 t = Bits32 (opcode, 15, 12);
6188                 n = Bits32 (opcode, 19, 16);
6189                 imm32 = Bits32 (opcode, 7, 0);
6190 
6191                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6192                 index = BitIsSet (opcode, 10);
6193                 add = BitIsSet (opcode, 9);
6194                 wback = BitIsSet (opcode, 8);
6195 
6196                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6197                 if (BadReg (t) || (wback && (n == t)))
6198                     return false;
6199 
6200                 break;
6201 
6202             default:
6203                 return false;
6204         }
6205 
6206         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6207         if (!success)
6208             return false;
6209 
6210         addr_t address;
6211         addr_t offset_addr;
6212 
6213         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6214         if (add)
6215             offset_addr = Rn + imm32;
6216         else
6217             offset_addr = Rn - imm32;
6218 
6219         // address = if index then offset_addr else R[n];
6220         if (index)
6221             address = offset_addr;
6222         else
6223             address = Rn;
6224 
6225         // R[t] = ZeroExtend(MemU[address,1], 32);
6226         RegisterInfo base_reg;
6227         RegisterInfo data_reg;
6228         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6229         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6230 
6231         EmulateInstruction::Context context;
6232         context.type = eContextRegisterLoad;
6233         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
6234 
6235         uint64_t data = MemURead (context, address, 1, 0, &success);
6236         if (!success)
6237             return false;
6238 
6239         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6240             return false;
6241 
6242         // if wback then R[n] = offset_addr;
6243         if (wback)
6244         {
6245             context.type = eContextAdjustBaseRegister;
6246             context.SetAddress (offset_addr);
6247             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6248                 return false;
6249         }
6250     }
6251     return true;
6252 }
6253 
6254 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6255 // zero-extends it to form a 32-bit word and writes it to a register.
6256 bool
6257 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6258 {
6259 #if 0
6260     if ConditionPassed() then
6261         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6262         base = Align(PC,4);
6263         address = if add then (base + imm32) else (base - imm32);
6264         R[t] = ZeroExtend(MemU[address,1], 32);
6265 #endif
6266 
6267     bool success = false;
6268 
6269     if (ConditionPassed(opcode))
6270     {
6271         uint32_t t;
6272         uint32_t imm32;
6273         bool add;
6274         switch (encoding)
6275         {
6276             case eEncodingT1:
6277                 // if Rt == '1111' then SEE PLD;
6278                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6279                 t = Bits32 (opcode, 15, 12);
6280                 imm32 = Bits32 (opcode, 11, 0);
6281                 add = BitIsSet (opcode, 23);
6282 
6283                 // if t == 13 then UNPREDICTABLE;
6284                 if (t == 13)
6285                     return false;
6286 
6287                 break;
6288 
6289             case eEncodingA1:
6290                 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6291                 t = Bits32 (opcode, 15, 12);
6292                 imm32 = Bits32 (opcode, 11, 0);
6293                 add = BitIsSet (opcode, 23);
6294 
6295                 // if t == 15 then UNPREDICTABLE;
6296                 if (t == 15)
6297                     return false;
6298                 break;
6299 
6300             default:
6301                 return false;
6302         }
6303 
6304         // base = Align(PC,4);
6305         uint32_t pc_val = ReadCoreReg (PC_REG, &success);
6306         if (!success)
6307             return false;
6308 
6309         uint32_t base = AlignPC (pc_val);
6310 
6311         addr_t address;
6312         // address = if add then (base + imm32) else (base - imm32);
6313         if (add)
6314             address = base + imm32;
6315         else
6316             address = base - imm32;
6317 
6318         // R[t] = ZeroExtend(MemU[address,1], 32);
6319         EmulateInstruction::Context context;
6320         context.type = eContextRelativeBranchImmediate;
6321         context.SetImmediate (address - base);
6322 
6323         uint64_t data = MemURead (context, address, 1, 0, &success);
6324         if (!success)
6325             return false;
6326 
6327         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6328             return false;
6329     }
6330     return true;
6331 }
6332 
6333 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from
6334 // memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6335 // optionally be shifted.
6336 bool
6337 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding)
6338 {
6339 #if 0
6340     if ConditionPassed() then
6341         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6342         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6343         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6344         address = if index then offset_addr else R[n];
6345         R[t] = ZeroExtend(MemU[address,1],32);
6346         if wback then R[n] = offset_addr;
6347 #endif
6348 
6349     bool success = false;
6350 
6351     if (ConditionPassed(opcode))
6352     {
6353         uint32_t t;
6354         uint32_t n;
6355         uint32_t m;
6356         bool index;
6357         bool add;
6358         bool wback;
6359         ARM_ShifterType shift_t;
6360         uint32_t shift_n;
6361 
6362         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6363         switch (encoding)
6364         {
6365             case eEncodingT1:
6366                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6367                 t = Bits32 (opcode, 2, 0);
6368                 n = Bits32 (opcode, 5, 3);
6369                 m = Bits32 (opcode, 8, 6);
6370 
6371                 // index = TRUE; add = TRUE; wback = FALSE;
6372                 index = true;
6373                 add = true;
6374                 wback = false;
6375 
6376                 // (shift_t, shift_n) = (SRType_LSL, 0);
6377                 shift_t = SRType_LSL;
6378                 shift_n = 0;
6379                 break;
6380 
6381             case eEncodingT2:
6382                 // if Rt == '1111' then SEE PLD;
6383                 // if Rn == '1111' then SEE LDRB (literal);
6384                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6385                 t = Bits32 (opcode, 15, 12);
6386                 n = Bits32 (opcode, 19, 16);
6387                 m = Bits32 (opcode, 3, 0);
6388 
6389                 // index = TRUE; add = TRUE; wback = FALSE;
6390                 index = true;
6391                 add = true;
6392                 wback = false;
6393 
6394                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6395                 shift_t = SRType_LSL;
6396                 shift_n = Bits32 (opcode, 5, 4);
6397 
6398                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6399                 if ((t == 13) || BadReg (m))
6400                     return false;
6401                 break;
6402 
6403             case eEncodingA1:
6404             {
6405                 // if P == '0' && W == '1' then SEE LDRBT;
6406                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6407                 t = Bits32 (opcode, 15, 12);
6408                 n = Bits32 (opcode, 19, 16);
6409                 m = Bits32 (opcode, 3, 0);
6410 
6411                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6412                 index = BitIsSet (opcode, 24);
6413                 add = BitIsSet (opcode, 23);
6414                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6415 
6416                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6417                 uint32_t type = Bits32 (opcode, 6, 5);
6418                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6419                 shift_n = DecodeImmShift (type, imm5, shift_t);
6420 
6421                 // if t == 15 || m == 15 then UNPREDICTABLE;
6422                 if ((t == 15) || (m == 15))
6423                     return false;
6424 
6425                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6426                 if (wback && ((n == 15) || (n == t)))
6427                     return false;
6428             }
6429                 break;
6430 
6431             default:
6432                 return false;
6433         }
6434 
6435         addr_t offset_addr;
6436         addr_t address;
6437 
6438         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6439         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6440         if (!success)
6441             return false;
6442 
6443         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6444         if (!success)
6445             return false;
6446 
6447         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6448         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6449         if (!success)
6450             return false;
6451 
6452         if (add)
6453             offset_addr = Rn + offset;
6454         else
6455             offset_addr = Rn - offset;
6456 
6457         // address = if index then offset_addr else R[n];
6458         if (index)
6459             address = offset_addr;
6460         else
6461             address = Rn;
6462 
6463         // R[t] = ZeroExtend(MemU[address,1],32);
6464         RegisterInfo base_reg;
6465         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6466 
6467         EmulateInstruction::Context context;
6468         context.type = eContextRegisterLoad;
6469         context.SetRegisterPlusOffset (base_reg, address - Rn);
6470 
6471         uint64_t data = MemURead (context, address, 1, 0, &success);
6472         if (!success)
6473             return false;
6474 
6475         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6476             return false;
6477 
6478         // if wback then R[n] = offset_addr;
6479         if (wback)
6480         {
6481             context.type = eContextAdjustBaseRegister;
6482             context.SetAddress (offset_addr);
6483             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6484                 return false;
6485         }
6486     }
6487     return true;
6488 }
6489 
6490 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a
6491 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register.  It can use offset,
6492 // post-indexed, or pre-indexed addressing.
6493 bool
6494 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding)
6495 {
6496 #if 0
6497     if ConditionPassed() then
6498         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6499         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6500         address = if index then offset_addr else R[n];
6501         data = MemU[address,2];
6502         if wback then R[n] = offset_addr;
6503         if UnalignedSupport() || address<0> = '0' then
6504             R[t] = ZeroExtend(data, 32);
6505         else // Can only apply before ARMv7
6506             R[t] = bits(32) UNKNOWN;
6507 #endif
6508 
6509 
6510     bool success = false;
6511 
6512     if (ConditionPassed(opcode))
6513     {
6514         uint32_t t;
6515         uint32_t n;
6516         uint32_t imm32;
6517         bool index;
6518         bool add;
6519         bool wback;
6520 
6521         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6522         switch (encoding)
6523         {
6524             case eEncodingT1:
6525                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
6526                 t = Bits32 (opcode, 2, 0);
6527                 n = Bits32 (opcode, 5, 3);
6528                 imm32 = Bits32 (opcode, 10, 6) << 1;
6529 
6530                 // index = TRUE; add = TRUE; wback = FALSE;
6531                 index = true;
6532                 add = true;
6533                 wback = false;
6534 
6535                 break;
6536 
6537             case eEncodingT2:
6538                 // if Rt == '1111' then SEE "Unallocated memory hints";
6539                 // if Rn == '1111' then SEE LDRH (literal);
6540                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6541                 t = Bits32 (opcode, 15, 12);
6542                 n = Bits32 (opcode, 19, 16);
6543                 imm32 = Bits32 (opcode, 11, 0);
6544 
6545                 // index = TRUE; add = TRUE; wback = FALSE;
6546                 index = true;
6547                 add = true;
6548                 wback = false;
6549 
6550                 // if t == 13 then UNPREDICTABLE;
6551                 if (t == 13)
6552                     return false;
6553                 break;
6554 
6555             case eEncodingT3:
6556                 // if Rn == '1111' then SEE LDRH (literal);
6557                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
6558                 // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
6559                 // if P == '0' && W == '0' then UNDEFINED;
6560                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6561                     return false;
6562 
6563                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6564                 t = Bits32 (opcode, 15, 12);
6565                 n = Bits32 (opcode, 19, 16);
6566                 imm32 = Bits32 (opcode, 7, 0);
6567 
6568                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6569                 index = BitIsSet (opcode, 10);
6570                 add = BitIsSet (opcode, 9);
6571                 wback = BitIsSet (opcode, 8);
6572 
6573                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6574                 if (BadReg (t) || (wback && (n == t)))
6575                     return false;
6576                 break;
6577 
6578             default:
6579                 return false;
6580         }
6581 
6582         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6583         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6584         if (!success)
6585             return false;
6586 
6587         addr_t offset_addr;
6588         addr_t address;
6589 
6590         if (add)
6591             offset_addr = Rn + imm32;
6592         else
6593             offset_addr = Rn - imm32;
6594 
6595         // address = if index then offset_addr else R[n];
6596         if (index)
6597             address = offset_addr;
6598         else
6599             address = Rn;
6600 
6601         // data = MemU[address,2];
6602         RegisterInfo base_reg;
6603         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6604 
6605         EmulateInstruction::Context context;
6606         context.type = eContextRegisterLoad;
6607         context.SetRegisterPlusOffset (base_reg, address - Rn);
6608 
6609         uint64_t data = MemURead (context, address, 2, 0, &success);
6610         if (!success)
6611             return false;
6612 
6613         // if wback then R[n] = offset_addr;
6614         if (wback)
6615         {
6616             context.type = eContextAdjustBaseRegister;
6617             context.SetAddress (offset_addr);
6618             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6619                 return false;
6620         }
6621 
6622         // if UnalignedSupport() || address<0> = '0' then
6623         if (UnalignedSupport () || BitIsClear (address, 0))
6624         {
6625             // R[t] = ZeroExtend(data, 32);
6626             context.type = eContextRegisterLoad;
6627             context.SetRegisterPlusOffset (base_reg, address - Rn);
6628             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6629                 return false;
6630         }
6631         else // Can only apply before ARMv7
6632         {
6633             // R[t] = bits(32) UNKNOWN;
6634             WriteBits32Unknown (t);
6635         }
6636     }
6637     return true;
6638 }
6639 
6640 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory,
6641 // zero-extends it to form a 32-bit word, and writes it to a register.
6642 bool
6643 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding)
6644 {
6645 #if 0
6646     if ConditionPassed() then
6647         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6648         base = Align(PC,4);
6649         address = if add then (base + imm32) else (base - imm32);
6650         data = MemU[address,2];
6651         if UnalignedSupport() || address<0> = '0' then
6652             R[t] = ZeroExtend(data, 32);
6653         else // Can only apply before ARMv7
6654             R[t] = bits(32) UNKNOWN;
6655 #endif
6656 
6657     bool success = false;
6658 
6659     if (ConditionPassed(opcode))
6660     {
6661         uint32_t t;
6662         uint32_t imm32;
6663         bool add;
6664 
6665         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6666         switch (encoding)
6667         {
6668             case eEncodingT1:
6669                 // if Rt == '1111' then SEE "Unallocated memory hints";
6670                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6671                 t = Bits32 (opcode, 15, 12);
6672                 imm32 = Bits32 (opcode, 11, 0);
6673                 add = BitIsSet (opcode, 23);
6674 
6675                 // if t == 13 then UNPREDICTABLE;
6676                 if (t == 13)
6677                     return false;
6678 
6679                 break;
6680 
6681             case eEncodingA1:
6682             {
6683                 uint32_t imm4H = Bits32 (opcode, 11, 8);
6684                 uint32_t imm4L = Bits32 (opcode, 3, 0);
6685 
6686                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6687                 t = Bits32 (opcode, 15, 12);
6688                 imm32 = (imm4H << 4) | imm4L;
6689                 add = BitIsSet (opcode, 23);
6690 
6691                 // if t == 15 then UNPREDICTABLE;
6692                 if (t == 15)
6693                     return false;
6694                 break;
6695             }
6696 
6697             default:
6698                 return false;
6699         }
6700 
6701         // base = Align(PC,4);
6702         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6703         if (!success)
6704             return false;
6705 
6706         addr_t base = AlignPC (pc_value);
6707         addr_t address;
6708 
6709         // address = if add then (base + imm32) else (base - imm32);
6710         if (add)
6711             address = base + imm32;
6712         else
6713             address = base - imm32;
6714 
6715         // data = MemU[address,2];
6716         RegisterInfo base_reg;
6717         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
6718 
6719         EmulateInstruction::Context context;
6720         context.type = eContextRegisterLoad;
6721         context.SetRegisterPlusOffset (base_reg, address - base);
6722 
6723         uint64_t data = MemURead (context, address, 2, 0, &success);
6724         if (!success)
6725             return false;
6726 
6727 
6728         // if UnalignedSupport() || address<0> = '0' then
6729         if (UnalignedSupport () || BitIsClear (address, 0))
6730         {
6731             // R[t] = ZeroExtend(data, 32);
6732             context.type = eContextRegisterLoad;
6733             context.SetRegisterPlusOffset (base_reg, address - base);
6734             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6735                 return false;
6736 
6737         }
6738         else // Can only apply before ARMv7
6739         {
6740             // R[t] = bits(32) UNKNOWN;
6741             WriteBits32Unknown (t);
6742         }
6743     }
6744     return true;
6745 }
6746 
6747 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword
6748 // from memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6749 // be shifted left by 0, 1, 2, or 3 bits.
6750 bool
6751 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding)
6752 {
6753 #if 0
6754     if ConditionPassed() then
6755         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6756         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6757         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6758         address = if index then offset_addr else R[n];
6759         data = MemU[address,2];
6760         if wback then R[n] = offset_addr;
6761         if UnalignedSupport() || address<0> = '0' then
6762             R[t] = ZeroExtend(data, 32);
6763         else // Can only apply before ARMv7
6764             R[t] = bits(32) UNKNOWN;
6765 #endif
6766 
6767     bool success = false;
6768 
6769     if (ConditionPassed(opcode))
6770     {
6771         uint32_t t;
6772         uint32_t n;
6773         uint32_t m;
6774         bool index;
6775         bool add;
6776         bool wback;
6777         ARM_ShifterType shift_t;
6778         uint32_t shift_n;
6779 
6780         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6781         switch (encoding)
6782         {
6783             case eEncodingT1:
6784                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6785                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6786                 t = Bits32 (opcode, 2, 0);
6787                 n = Bits32 (opcode, 5, 3);
6788                 m = Bits32 (opcode, 8, 6);
6789 
6790                 // index = TRUE; add = TRUE; wback = FALSE;
6791                 index = true;
6792                 add = true;
6793                 wback = false;
6794 
6795                 // (shift_t, shift_n) = (SRType_LSL, 0);
6796                 shift_t = SRType_LSL;
6797                 shift_n = 0;
6798 
6799                 break;
6800 
6801             case eEncodingT2:
6802                 // if Rn == '1111' then SEE LDRH (literal);
6803                 // if Rt == '1111' then SEE "Unallocated memory hints";
6804                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6805                 t = Bits32 (opcode, 15, 12);
6806                 n = Bits32 (opcode, 19, 16);
6807                 m = Bits32 (opcode, 3, 0);
6808 
6809                 // index = TRUE; add = TRUE; wback = FALSE;
6810                 index = true;
6811                 add = true;
6812                 wback = false;
6813 
6814                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6815                 shift_t = SRType_LSL;
6816                 shift_n = Bits32 (opcode, 5, 4);
6817 
6818                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6819                 if ((t == 13) || BadReg (m))
6820                     return false;
6821                 break;
6822 
6823             case eEncodingA1:
6824                 // if P == '0' && W == '1' then SEE LDRHT;
6825                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6826                 t = Bits32 (opcode, 15, 12);
6827                 n = Bits32 (opcode, 19, 16);
6828                 m = Bits32 (opcode, 3, 0);
6829 
6830                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6831                 index = BitIsSet (opcode, 24);
6832                 add = BitIsSet (opcode, 23);
6833                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6834 
6835                 // (shift_t, shift_n) = (SRType_LSL, 0);
6836                 shift_t = SRType_LSL;
6837                 shift_n = 0;
6838 
6839                 // if t == 15 || m == 15 then UNPREDICTABLE;
6840                 if ((t == 15) || (m == 15))
6841                     return false;
6842 
6843                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6844                 if (wback && ((n == 15) || (n == t)))
6845                     return false;
6846 
6847                 break;
6848 
6849             default:
6850                 return false;
6851         }
6852 
6853         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6854 
6855         uint64_t Rm  = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6856         if (!success)
6857             return false;
6858 
6859         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6860         if (!success)
6861             return false;
6862 
6863         addr_t offset_addr;
6864         addr_t address;
6865 
6866         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6867         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6868         if (!success)
6869             return false;
6870 
6871         if (add)
6872             offset_addr = Rn + offset;
6873         else
6874             offset_addr = Rn - offset;
6875 
6876         // address = if index then offset_addr else R[n];
6877         if (index)
6878             address = offset_addr;
6879         else
6880             address = Rn;
6881 
6882         // data = MemU[address,2];
6883         RegisterInfo base_reg;
6884         RegisterInfo offset_reg;
6885         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6886         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
6887 
6888         EmulateInstruction::Context context;
6889         context.type = eContextRegisterLoad;
6890         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6891         uint64_t data = MemURead (context, address, 2, 0, &success);
6892         if (!success)
6893             return false;
6894 
6895         // if wback then R[n] = offset_addr;
6896         if (wback)
6897         {
6898             context.type = eContextAdjustBaseRegister;
6899             context.SetAddress (offset_addr);
6900             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6901                 return false;
6902         }
6903 
6904         // if UnalignedSupport() || address<0> = '0' then
6905         if (UnalignedSupport() || BitIsClear (address, 0))
6906         {
6907             // R[t] = ZeroExtend(data, 32);
6908             context.type = eContextRegisterLoad;
6909             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6910             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6911                 return false;
6912         }
6913         else // Can only apply before ARMv7
6914         {
6915             // R[t] = bits(32) UNKNOWN;
6916             WriteBits32Unknown (t);
6917         }
6918     }
6919     return true;
6920 }
6921 
6922 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from
6923 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed,
6924 // or pre-indexed addressing.
6925 bool
6926 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6927 {
6928 #if 0
6929     if ConditionPassed() then
6930         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6931         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6932         address = if index then offset_addr else R[n];
6933         R[t] = SignExtend(MemU[address,1], 32);
6934         if wback then R[n] = offset_addr;
6935 #endif
6936 
6937     bool success = false;
6938 
6939     if (ConditionPassed(opcode))
6940     {
6941         uint32_t t;
6942         uint32_t n;
6943         uint32_t imm32;
6944         bool index;
6945         bool add;
6946         bool wback;
6947 
6948         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6949         switch (encoding)
6950         {
6951             case eEncodingT1:
6952                 // if Rt == '1111' then SEE PLI;
6953                 // if Rn == '1111' then SEE LDRSB (literal);
6954                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6955                 t = Bits32 (opcode, 15, 12);
6956                 n = Bits32 (opcode, 19, 16);
6957                 imm32 = Bits32 (opcode, 11, 0);
6958 
6959                 // index = TRUE; add = TRUE; wback = FALSE;
6960                 index = true;
6961                 add = true;
6962                 wback = false;
6963 
6964                 // if t == 13 then UNPREDICTABLE;
6965                 if (t == 13)
6966                     return false;
6967 
6968                 break;
6969 
6970             case eEncodingT2:
6971                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
6972                 // if Rn == '1111' then SEE LDRSB (literal);
6973                 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
6974                 // if P == '0' && W == '0' then UNDEFINED;
6975                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6976                     return false;
6977 
6978                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6979                 t = Bits32 (opcode, 15, 12);
6980                 n = Bits32 (opcode, 19, 16);
6981                 imm32 = Bits32 (opcode, 7, 0);
6982 
6983                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6984                 index = BitIsSet (opcode, 10);
6985                 add = BitIsSet (opcode, 9);
6986                 wback = BitIsSet (opcode, 8);
6987 
6988                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6989                   if (((t == 13) || ((t == 15)
6990                                      && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8))))
6991                       || (wback && (n == t)))
6992                     return false;
6993 
6994                 break;
6995 
6996             case eEncodingA1:
6997             {
6998                 // if Rn == '1111' then SEE LDRSB (literal);
6999                 // if P == '0' && W == '1' then SEE LDRSBT;
7000                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7001                 t = Bits32 (opcode, 15, 12);
7002                 n = Bits32 (opcode, 19, 16);
7003 
7004                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7005                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7006                 imm32 = (imm4H << 4) | imm4L;
7007 
7008                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7009                 index = BitIsSet (opcode, 24);
7010                 add = BitIsSet (opcode, 23);
7011                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
7012 
7013                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7014                 if ((t == 15) || (wback && (n == t)))
7015                     return false;
7016 
7017                 break;
7018             }
7019 
7020             default:
7021                 return false;
7022         }
7023 
7024         uint64_t Rn = ReadCoreReg (n, &success);
7025         if (!success)
7026             return false;
7027 
7028         addr_t offset_addr;
7029         addr_t address;
7030 
7031         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7032         if (add)
7033             offset_addr = Rn + imm32;
7034         else
7035             offset_addr = Rn - imm32;
7036 
7037         // address = if index then offset_addr else R[n];
7038         if (index)
7039             address = offset_addr;
7040         else
7041             address = Rn;
7042 
7043         // R[t] = SignExtend(MemU[address,1], 32);
7044         RegisterInfo base_reg;
7045         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7046 
7047         EmulateInstruction::Context context;
7048         context.type = eContextRegisterLoad;
7049         context.SetRegisterPlusOffset (base_reg, address - Rn);
7050 
7051         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7052         if (!success)
7053             return false;
7054 
7055         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7056         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7057             return false;
7058 
7059         // if wback then R[n] = offset_addr;
7060         if (wback)
7061         {
7062             context.type = eContextAdjustBaseRegister;
7063             context.SetAddress (offset_addr);
7064             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7065                 return false;
7066         }
7067     }
7068 
7069     return true;
7070 }
7071 
7072 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
7073 // sign-extends it to form a 32-bit word, and writes tit to a register.
7074 bool
7075 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding)
7076 {
7077 #if 0
7078     if ConditionPassed() then
7079         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7080         base = Align(PC,4);
7081         address = if add then (base + imm32) else (base - imm32);
7082         R[t] = SignExtend(MemU[address,1], 32);
7083 #endif
7084 
7085     bool success = false;
7086 
7087     if (ConditionPassed(opcode))
7088     {
7089         uint32_t t;
7090         uint32_t imm32;
7091         bool add;
7092 
7093         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7094         switch (encoding)
7095         {
7096             case eEncodingT1:
7097                 // if Rt == '1111' then SEE PLI;
7098                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7099                 t = Bits32 (opcode, 15, 12);
7100                 imm32 = Bits32 (opcode, 11, 0);
7101                 add = BitIsSet (opcode, 23);
7102 
7103                 // if t == 13 then UNPREDICTABLE;
7104                 if (t == 13)
7105                     return false;
7106 
7107                 break;
7108 
7109             case eEncodingA1:
7110             {
7111                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7112                 t = Bits32 (opcode, 15, 12);
7113                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7114                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7115                 imm32 = (imm4H << 4) | imm4L;
7116                 add = BitIsSet (opcode, 23);
7117 
7118                 // if t == 15 then UNPREDICTABLE;
7119                 if (t == 15)
7120                     return false;
7121 
7122                 break;
7123             }
7124 
7125             default:
7126                 return false;
7127         }
7128 
7129         // base = Align(PC,4);
7130         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7131         if (!success)
7132             return false;
7133         uint64_t base = AlignPC (pc_value);
7134 
7135         // address = if add then (base + imm32) else (base - imm32);
7136         addr_t address;
7137         if (add)
7138             address = base + imm32;
7139         else
7140             address = base - imm32;
7141 
7142         // R[t] = SignExtend(MemU[address,1], 32);
7143         RegisterInfo base_reg;
7144         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7145 
7146         EmulateInstruction::Context context;
7147         context.type = eContextRegisterLoad;
7148         context.SetRegisterPlusOffset (base_reg, address - base);
7149 
7150         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7151         if (!success)
7152             return false;
7153 
7154         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7155         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7156             return false;
7157     }
7158     return true;
7159 }
7160 
7161 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from
7162 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7163 // shifted left by 0, 1, 2, or 3 bits.
7164 bool
7165 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding)
7166 {
7167 #if 0
7168     if ConditionPassed() then
7169         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7170         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7171         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7172         address = if index then offset_addr else R[n];
7173         R[t] = SignExtend(MemU[address,1], 32);
7174         if wback then R[n] = offset_addr;
7175 #endif
7176 
7177     bool success = false;
7178 
7179     if (ConditionPassed(opcode))
7180     {
7181         uint32_t t;
7182         uint32_t n;
7183         uint32_t m;
7184         bool index;
7185         bool add;
7186         bool wback;
7187         ARM_ShifterType shift_t;
7188         uint32_t shift_n;
7189 
7190         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7191         switch (encoding)
7192         {
7193             case eEncodingT1:
7194                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7195                 t = Bits32 (opcode, 2, 0);
7196                 n = Bits32 (opcode, 5, 3);
7197                 m = Bits32 (opcode, 8, 6);
7198 
7199                 // index = TRUE; add = TRUE; wback = FALSE;
7200                 index = true;
7201                 add = true;
7202                 wback = false;
7203 
7204                 // (shift_t, shift_n) = (SRType_LSL, 0);
7205                 shift_t = SRType_LSL;
7206                 shift_n = 0;
7207 
7208                 break;
7209 
7210             case eEncodingT2:
7211                 // if Rt == '1111' then SEE PLI;
7212                 // if Rn == '1111' then SEE LDRSB (literal);
7213                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7214                 t = Bits32 (opcode, 15, 12);
7215                 n = Bits32 (opcode, 19, 16);
7216                 m = Bits32 (opcode, 3, 0);
7217 
7218                 // index = TRUE; add = TRUE; wback = FALSE;
7219                 index = true;
7220                 add = true;
7221                 wback = false;
7222 
7223                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7224                 shift_t = SRType_LSL;
7225                 shift_n = Bits32 (opcode, 5, 4);
7226 
7227                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7228                 if ((t == 13) || BadReg (m))
7229                     return false;
7230                 break;
7231 
7232             case eEncodingA1:
7233                 // if P == '0' && W == '1' then SEE LDRSBT;
7234                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7235                 t = Bits32 (opcode, 15, 12);
7236                 n = Bits32 (opcode, 19, 16);
7237                 m = Bits32 (opcode, 3, 0);
7238 
7239                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7240                 index = BitIsSet (opcode, 24);
7241                 add = BitIsSet (opcode, 23);
7242                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7243 
7244                 // (shift_t, shift_n) = (SRType_LSL, 0);
7245                 shift_t = SRType_LSL;
7246                 shift_n = 0;
7247 
7248                 // if t == 15 || m == 15 then UNPREDICTABLE;
7249                 if ((t == 15) || (m == 15))
7250                     return false;
7251 
7252                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7253                 if (wback && ((n == 15) || (n == t)))
7254                     return false;
7255                 break;
7256 
7257             default:
7258                 return false;
7259         }
7260 
7261         uint64_t Rm =  ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7262         if (!success)
7263             return false;
7264 
7265         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7266         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7267         if (!success)
7268             return false;
7269 
7270         addr_t offset_addr;
7271         addr_t address;
7272 
7273         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7274         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7275         if (!success)
7276             return false;
7277 
7278         if (add)
7279             offset_addr = Rn + offset;
7280         else
7281             offset_addr = Rn - offset;
7282 
7283         // address = if index then offset_addr else R[n];
7284         if (index)
7285             address = offset_addr;
7286         else
7287             address = Rn;
7288 
7289         // R[t] = SignExtend(MemU[address,1], 32);
7290         RegisterInfo base_reg;
7291         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7292         RegisterInfo offset_reg;
7293         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7294 
7295         EmulateInstruction::Context context;
7296         context.type = eContextRegisterLoad;
7297         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7298 
7299         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7300         if (!success)
7301             return false;
7302 
7303         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7304         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7305             return false;
7306 
7307         // if wback then R[n] = offset_addr;
7308         if (wback)
7309         {
7310             context.type = eContextAdjustBaseRegister;
7311             context.SetAddress (offset_addr);
7312             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7313                 return false;
7314         }
7315     }
7316     return true;
7317 }
7318 
7319 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from
7320 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed, or
7321 // pre-indexed addressing.
7322 bool
7323 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding)
7324 {
7325 #if 0
7326     if ConditionPassed() then
7327         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7328         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7329         address = if index then offset_addr else R[n];
7330         data = MemU[address,2];
7331         if wback then R[n] = offset_addr;
7332         if UnalignedSupport() || address<0> = '0' then
7333             R[t] = SignExtend(data, 32);
7334         else // Can only apply before ARMv7
7335             R[t] = bits(32) UNKNOWN;
7336 #endif
7337 
7338     bool success = false;
7339 
7340     if (ConditionPassed(opcode))
7341     {
7342         uint32_t t;
7343         uint32_t n;
7344         uint32_t imm32;
7345         bool index;
7346         bool add;
7347         bool wback;
7348 
7349         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7350         switch (encoding)
7351         {
7352             case eEncodingT1:
7353                 // if Rn == '1111' then SEE LDRSH (literal);
7354                 // if Rt == '1111' then SEE "Unallocated memory hints";
7355                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7356                 t = Bits32 (opcode, 15, 12);
7357                 n = Bits32 (opcode, 19, 16);
7358                 imm32 = Bits32 (opcode, 11, 0);
7359 
7360                 // index = TRUE; add = TRUE; wback = FALSE;
7361                 index = true;
7362                 add = true;
7363                 wback = false;
7364 
7365                 // if t == 13 then UNPREDICTABLE;
7366                 if (t == 13)
7367                     return false;
7368 
7369                 break;
7370 
7371             case eEncodingT2:
7372                 // if Rn == '1111' then SEE LDRSH (literal);
7373                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
7374                 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7375                 // if P == '0' && W == '0' then UNDEFINED;
7376                   if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7377                   return false;
7378 
7379                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7380                 t = Bits32 (opcode, 15, 12);
7381                 n = Bits32 (opcode, 19, 16);
7382                 imm32 = Bits32 (opcode, 7, 0);
7383 
7384                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7385                 index = BitIsSet (opcode, 10);
7386                 add = BitIsSet (opcode, 9);
7387                 wback = BitIsSet (opcode, 8);
7388 
7389                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7390                 if (BadReg (t) || (wback && (n == t)))
7391                     return false;
7392 
7393                 break;
7394 
7395             case eEncodingA1:
7396             {
7397                 // if Rn == '1111' then SEE LDRSH (literal);
7398                 // if P == '0' && W == '1' then SEE LDRSHT;
7399                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7400                 t = Bits32 (opcode, 15, 12);
7401                 n = Bits32 (opcode, 19, 16);
7402                 uint32_t imm4H = Bits32 (opcode, 11,8);
7403                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7404                 imm32 = (imm4H << 4) | imm4L;
7405 
7406                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7407                 index = BitIsSet (opcode, 24);
7408                 add = BitIsSet (opcode, 23);
7409                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7410 
7411                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7412                 if ((t == 15) || (wback && (n == t)))
7413                     return false;
7414 
7415                 break;
7416             }
7417 
7418             default:
7419                 return false;
7420         }
7421 
7422         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7423         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7424         if (!success)
7425             return false;
7426 
7427         addr_t offset_addr;
7428         if (add)
7429             offset_addr = Rn + imm32;
7430         else
7431             offset_addr = Rn - imm32;
7432 
7433         // address = if index then offset_addr else R[n];
7434         addr_t address;
7435         if (index)
7436             address = offset_addr;
7437         else
7438             address = Rn;
7439 
7440         // data = MemU[address,2];
7441         RegisterInfo base_reg;
7442         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7443 
7444         EmulateInstruction::Context context;
7445         context.type = eContextRegisterLoad;
7446         context.SetRegisterPlusOffset (base_reg, address - Rn);
7447 
7448         uint64_t data = MemURead (context, address, 2, 0, &success);
7449         if (!success)
7450             return false;
7451 
7452         // if wback then R[n] = offset_addr;
7453         if (wback)
7454         {
7455             context.type = eContextAdjustBaseRegister;
7456             context.SetAddress (offset_addr);
7457             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7458                 return false;
7459         }
7460 
7461         // if UnalignedSupport() || address<0> = '0' then
7462         if (UnalignedSupport() || BitIsClear (address, 0))
7463         {
7464             // R[t] = SignExtend(data, 32);
7465             int64_t signed_data = llvm::SignExtend64<16>(data);
7466             context.type = eContextRegisterLoad;
7467             context.SetRegisterPlusOffset (base_reg, address - Rn);
7468             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7469                 return false;
7470         }
7471         else // Can only apply before ARMv7
7472         {
7473             // R[t] = bits(32) UNKNOWN;
7474             WriteBits32Unknown (t);
7475         }
7476     }
7477     return true;
7478 }
7479 
7480 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory,
7481 // sign-extends it to from a 32-bit word, and writes it to a register.
7482 bool
7483 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding)
7484 {
7485 #if 0
7486     if ConditionPassed() then
7487         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7488         base = Align(PC,4);
7489         address = if add then (base + imm32) else (base - imm32);
7490         data = MemU[address,2];
7491         if UnalignedSupport() || address<0> = '0' then
7492             R[t] = SignExtend(data, 32);
7493         else // Can only apply before ARMv7
7494             R[t] = bits(32) UNKNOWN;
7495 #endif
7496 
7497     bool success = false;
7498 
7499     if (ConditionPassed(opcode))
7500     {
7501         uint32_t t;
7502         uint32_t imm32;
7503         bool add;
7504 
7505         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7506         switch (encoding)
7507         {
7508             case eEncodingT1:
7509                 // if Rt == '1111' then SEE "Unallocated memory hints";
7510                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7511                 t = Bits32  (opcode, 15, 12);
7512                 imm32 = Bits32 (opcode, 11, 0);
7513                 add = BitIsSet (opcode, 23);
7514 
7515                 // if t == 13 then UNPREDICTABLE;
7516                 if (t == 13)
7517                     return false;
7518 
7519                 break;
7520 
7521             case eEncodingA1:
7522             {
7523                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7524                 t = Bits32 (opcode, 15, 12);
7525                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7526                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7527                 imm32 = (imm4H << 4) | imm4L;
7528                 add = BitIsSet (opcode, 23);
7529 
7530                 // if t == 15 then UNPREDICTABLE;
7531                 if (t == 15)
7532                     return false;
7533 
7534                 break;
7535             }
7536             default:
7537                 return false;
7538         }
7539 
7540         // base = Align(PC,4);
7541         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7542         if (!success)
7543             return false;
7544 
7545         uint64_t base = AlignPC (pc_value);
7546 
7547         addr_t address;
7548         // address = if add then (base + imm32) else (base - imm32);
7549         if (add)
7550             address = base + imm32;
7551         else
7552             address = base - imm32;
7553 
7554         // data = MemU[address,2];
7555         RegisterInfo base_reg;
7556         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7557 
7558         EmulateInstruction::Context context;
7559         context.type = eContextRegisterLoad;
7560         context.SetRegisterPlusOffset (base_reg, imm32);
7561 
7562         uint64_t data = MemURead (context, address, 2, 0, &success);
7563         if (!success)
7564             return false;
7565 
7566         // if UnalignedSupport() || address<0> = '0' then
7567         if (UnalignedSupport() || BitIsClear (address, 0))
7568         {
7569             // R[t] = SignExtend(data, 32);
7570             int64_t signed_data = llvm::SignExtend64<16>(data);
7571             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7572                 return false;
7573         }
7574         else // Can only apply before ARMv7
7575         {
7576             // R[t] = bits(32) UNKNOWN;
7577             WriteBits32Unknown (t);
7578         }
7579     }
7580     return true;
7581 }
7582 
7583 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword
7584 // from memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7585 // shifted left by 0, 1, 2, or 3 bits.
7586 bool
7587 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding)
7588 {
7589 #if 0
7590     if ConditionPassed() then
7591         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7592         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7593         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7594         address = if index then offset_addr else R[n];
7595         data = MemU[address,2];
7596         if wback then R[n] = offset_addr;
7597         if UnalignedSupport() || address<0> = '0' then
7598             R[t] = SignExtend(data, 32);
7599         else // Can only apply before ARMv7
7600             R[t] = bits(32) UNKNOWN;
7601 #endif
7602 
7603     bool success = false;
7604 
7605     if (ConditionPassed(opcode))
7606     {
7607         uint32_t t;
7608         uint32_t n;
7609         uint32_t m;
7610         bool index;
7611         bool add;
7612         bool wback;
7613         ARM_ShifterType shift_t;
7614         uint32_t shift_n;
7615 
7616         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7617         switch (encoding)
7618         {
7619             case eEncodingT1:
7620                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
7621                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7622                 t = Bits32 (opcode, 2, 0);
7623                 n = Bits32 (opcode, 5, 3);
7624                 m = Bits32 (opcode, 8, 6);
7625 
7626                 // index = TRUE; add = TRUE; wback = FALSE;
7627                 index = true;
7628                 add = true;
7629                 wback = false;
7630 
7631                 // (shift_t, shift_n) = (SRType_LSL, 0);
7632                 shift_t = SRType_LSL;
7633                 shift_n = 0;
7634 
7635                 break;
7636 
7637             case eEncodingT2:
7638                 // if Rn == '1111' then SEE LDRSH (literal);
7639                 // if Rt == '1111' then SEE "Unallocated memory hints";
7640                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7641                 t = Bits32 (opcode, 15, 12);
7642                 n = Bits32 (opcode, 19, 16);
7643                 m = Bits32 (opcode, 3, 0);
7644 
7645                 // index = TRUE; add = TRUE; wback = FALSE;
7646                 index = true;
7647                 add = true;
7648                 wback = false;
7649 
7650                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7651                 shift_t = SRType_LSL;
7652                 shift_n = Bits32 (opcode, 5, 4);
7653 
7654                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7655                 if ((t == 13) || BadReg (m))
7656                     return false;
7657 
7658                 break;
7659 
7660             case eEncodingA1:
7661                 // if P == '0' && W == '1' then SEE LDRSHT;
7662                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7663                 t = Bits32 (opcode, 15, 12);
7664                 n = Bits32 (opcode, 19, 16);
7665                 m = Bits32 (opcode, 3, 0);
7666 
7667                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7668                 index = BitIsSet (opcode, 24);
7669                 add = BitIsSet (opcode, 23);
7670                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7671 
7672                 // (shift_t, shift_n) = (SRType_LSL, 0);
7673                 shift_t = SRType_LSL;
7674                 shift_n = 0;
7675 
7676                 // if t == 15 || m == 15 then UNPREDICTABLE;
7677                 if ((t == 15) || (m == 15))
7678                     return false;
7679 
7680                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7681                 if (wback && ((n == 15) || (n == t)))
7682                     return false;
7683 
7684                 break;
7685 
7686             default:
7687                 return false;
7688         }
7689 
7690         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7691         if (!success)
7692             return false;
7693 
7694         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7695         if (!success)
7696             return false;
7697 
7698         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7699         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7700         if (!success)
7701             return false;
7702 
7703         addr_t offset_addr;
7704         addr_t address;
7705 
7706         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7707         if (add)
7708             offset_addr = Rn + offset;
7709         else
7710             offset_addr = Rn - offset;
7711 
7712         // address = if index then offset_addr else R[n];
7713         if (index)
7714             address = offset_addr;
7715         else
7716             address = Rn;
7717 
7718         // data = MemU[address,2];
7719         RegisterInfo base_reg;
7720         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7721 
7722         RegisterInfo offset_reg;
7723         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7724 
7725         EmulateInstruction::Context context;
7726         context.type = eContextRegisterLoad;
7727         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7728 
7729         uint64_t data = MemURead (context, address, 2, 0, &success);
7730         if (!success)
7731             return false;
7732 
7733         // if wback then R[n] = offset_addr;
7734         if (wback)
7735         {
7736             context.type = eContextAdjustBaseRegister;
7737             context.SetAddress (offset_addr);
7738             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7739                 return false;
7740         }
7741 
7742         // if UnalignedSupport() || address<0> = '0' then
7743         if (UnalignedSupport() || BitIsClear (address, 0))
7744         {
7745             // R[t] = SignExtend(data, 32);
7746             context.type = eContextRegisterLoad;
7747             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7748 
7749             int64_t signed_data = llvm::SignExtend64<16>(data);
7750             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7751                 return false;
7752         }
7753         else // Can only apply before ARMv7
7754         {
7755             // R[t] = bits(32) UNKNOWN;
7756             WriteBits32Unknown (t);
7757         }
7758     }
7759     return true;
7760 }
7761 
7762 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7763 // register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7764 bool
7765 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding)
7766 {
7767 #if 0
7768     if ConditionPassed() then
7769         EncodingSpecificOperations();
7770         rotated = ROR(R[m], rotation);
7771         R[d] = SignExtend(rotated<7:0>, 32);
7772 #endif
7773 
7774     bool success = false;
7775 
7776     if (ConditionPassed(opcode))
7777     {
7778         uint32_t d;
7779         uint32_t m;
7780         uint32_t rotation;
7781 
7782         // EncodingSpecificOperations();
7783         switch (encoding)
7784         {
7785             case eEncodingT1:
7786                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7787                 d = Bits32 (opcode, 2, 0);
7788                 m = Bits32 (opcode, 5, 3);
7789                 rotation = 0;
7790 
7791                 break;
7792 
7793             case eEncodingT2:
7794                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7795                 d = Bits32 (opcode, 11, 8);
7796                 m = Bits32 (opcode, 3, 0);
7797                 rotation = Bits32 (opcode, 5, 4) << 3;
7798 
7799                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7800                 if (BadReg (d) || BadReg (m))
7801                     return false;
7802 
7803                 break;
7804 
7805             case eEncodingA1:
7806                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7807                 d = Bits32 (opcode, 15, 12);
7808                 m = Bits32 (opcode, 3, 0);
7809                 rotation = Bits32 (opcode, 11, 10) << 3;
7810 
7811                 // if d == 15 || m == 15 then UNPREDICTABLE;
7812                 if ((d == 15) || (m == 15))
7813                     return false;
7814 
7815                 break;
7816 
7817             default:
7818                 return false;
7819         }
7820 
7821         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7822         if (!success)
7823             return false;
7824 
7825         // rotated = ROR(R[m], rotation);
7826         uint64_t rotated = ROR (Rm, rotation, &success);
7827         if (!success)
7828             return false;
7829 
7830         // R[d] = SignExtend(rotated<7:0>, 32);
7831         int64_t data = llvm::SignExtend64<8>(rotated);
7832 
7833         RegisterInfo source_reg;
7834         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7835 
7836         EmulateInstruction::Context context;
7837         context.type = eContextRegisterLoad;
7838         context.SetRegister (source_reg);
7839 
7840         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7841             return false;
7842     }
7843     return true;
7844 }
7845 
7846 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7847 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7848 bool
7849 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding)
7850 {
7851 #if 0
7852     if ConditionPassed() then
7853         EncodingSpecificOperations();
7854         rotated = ROR(R[m], rotation);
7855         R[d] = SignExtend(rotated<15:0>, 32);
7856 #endif
7857 
7858     bool success = false;
7859 
7860     if (ConditionPassed(opcode))
7861     {
7862         uint32_t d;
7863         uint32_t m;
7864         uint32_t rotation;
7865 
7866         // EncodingSpecificOperations();
7867         switch (encoding)
7868         {
7869             case eEncodingT1:
7870                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7871                 d = Bits32 (opcode, 2, 0);
7872                 m = Bits32 (opcode, 5, 3);
7873                 rotation = 0;
7874 
7875                 break;
7876 
7877             case eEncodingT2:
7878                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7879                 d = Bits32 (opcode, 11, 8);
7880                 m = Bits32 (opcode, 3, 0);
7881                 rotation = Bits32 (opcode, 5, 4) << 3;
7882 
7883                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7884                 if (BadReg (d) || BadReg (m))
7885                     return false;
7886 
7887                 break;
7888 
7889             case eEncodingA1:
7890                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7891                 d = Bits32 (opcode, 15, 12);
7892                 m = Bits32 (opcode, 3, 0);
7893                 rotation = Bits32 (opcode, 11, 10) << 3;
7894 
7895                 // if d == 15 || m == 15 then UNPREDICTABLE;
7896                 if ((d == 15) || (m == 15))
7897                     return false;
7898 
7899                 break;
7900 
7901             default:
7902                 return false;
7903         }
7904 
7905         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7906         if (!success)
7907             return false;
7908 
7909         // rotated = ROR(R[m], rotation);
7910         uint64_t rotated = ROR (Rm, rotation, &success);
7911         if (!success)
7912             return false;
7913 
7914         // R[d] = SignExtend(rotated<15:0>, 32);
7915         RegisterInfo source_reg;
7916         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7917 
7918         EmulateInstruction::Context context;
7919         context.type = eContextRegisterLoad;
7920         context.SetRegister (source_reg);
7921 
7922         int64_t data = llvm::SignExtend64<16> (rotated);
7923         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7924             return false;
7925     }
7926 
7927     return true;
7928 }
7929 
7930 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination
7931 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7932 bool
7933 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding)
7934 {
7935 #if 0
7936     if ConditionPassed() then
7937         EncodingSpecificOperations();
7938         rotated = ROR(R[m], rotation);
7939         R[d] = ZeroExtend(rotated<7:0>, 32);
7940 #endif
7941 
7942     bool success = false;
7943 
7944     if (ConditionPassed(opcode))
7945     {
7946         uint32_t d;
7947         uint32_t m;
7948         uint32_t rotation;
7949 
7950         // EncodingSpecificOperations();
7951         switch (encoding)
7952         {
7953             case eEncodingT1:
7954                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7955                 d = Bits32 (opcode, 2, 0);
7956                 m = Bits32 (opcode, 5, 3);
7957                 rotation = 0;
7958 
7959                 break;
7960 
7961             case eEncodingT2:
7962                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7963                 d = Bits32 (opcode, 11, 8);
7964                 m = Bits32 (opcode, 3, 0);
7965                   rotation = Bits32 (opcode, 5, 4) << 3;
7966 
7967                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7968                 if (BadReg (d) || BadReg (m))
7969                   return false;
7970 
7971                 break;
7972 
7973             case eEncodingA1:
7974                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7975                 d = Bits32 (opcode, 15, 12);
7976                 m = Bits32 (opcode, 3, 0);
7977                 rotation = Bits32 (opcode, 11, 10) << 3;
7978 
7979                 // if d == 15 || m == 15 then UNPREDICTABLE;
7980                 if ((d == 15) || (m == 15))
7981                     return false;
7982 
7983                 break;
7984 
7985             default:
7986                 return false;
7987         }
7988 
7989         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7990         if (!success)
7991             return false;
7992 
7993         // rotated = ROR(R[m], rotation);
7994         uint64_t rotated = ROR (Rm, rotation, &success);
7995         if (!success)
7996             return false;
7997 
7998         // R[d] = ZeroExtend(rotated<7:0>, 32);
7999         RegisterInfo source_reg;
8000         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8001 
8002         EmulateInstruction::Context context;
8003         context.type = eContextRegisterLoad;
8004         context.SetRegister (source_reg);
8005 
8006         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0)))
8007             return false;
8008     }
8009     return true;
8010 }
8011 
8012 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination
8013 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
8014 bool
8015 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding)
8016 {
8017 #if 0
8018     if ConditionPassed() then
8019         EncodingSpecificOperations();
8020         rotated = ROR(R[m], rotation);
8021         R[d] = ZeroExtend(rotated<15:0>, 32);
8022 #endif
8023 
8024     bool success = false;
8025 
8026     if (ConditionPassed(opcode))
8027     {
8028         uint32_t d;
8029         uint32_t m;
8030         uint32_t rotation;
8031 
8032         switch (encoding)
8033         {
8034             case eEncodingT1:
8035                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8036                 d = Bits32 (opcode, 2, 0);
8037                 m = Bits32 (opcode, 5, 3);
8038                 rotation = 0;
8039 
8040                 break;
8041 
8042             case eEncodingT2:
8043                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8044                 d = Bits32 (opcode, 11, 8);
8045                 m = Bits32 (opcode, 3, 0);
8046                 rotation = Bits32 (opcode, 5, 4) << 3;
8047 
8048                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8049                 if (BadReg (d) || BadReg (m))
8050                   return false;
8051 
8052                 break;
8053 
8054             case eEncodingA1:
8055                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8056                 d = Bits32 (opcode, 15, 12);
8057                 m = Bits32 (opcode, 3, 0);
8058                 rotation = Bits32 (opcode, 11, 10) << 3;
8059 
8060                 // if d == 15 || m == 15 then UNPREDICTABLE;
8061                 if ((d == 15) || (m == 15))
8062                     return false;
8063 
8064                 break;
8065 
8066             default:
8067                 return false;
8068         }
8069 
8070         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8071         if (!success)
8072             return false;
8073 
8074         // rotated = ROR(R[m], rotation);
8075         uint64_t rotated = ROR (Rm, rotation, &success);
8076         if (!success)
8077             return false;
8078 
8079         // R[d] = ZeroExtend(rotated<15:0>, 32);
8080         RegisterInfo source_reg;
8081         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8082 
8083         EmulateInstruction::Context context;
8084         context.type = eContextRegisterLoad;
8085         context.SetRegister (source_reg);
8086 
8087         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0)))
8088             return false;
8089     }
8090     return true;
8091 }
8092 
8093 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following
8094 // word respectively.
8095 bool
8096 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding)
8097 {
8098 #if 0
8099     if ConditionPassed() then
8100         EncodingSpecificOperations();
8101         if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8102             UNPREDICTABLE;
8103         else
8104             address = if increment then R[n] else R[n]-8;
8105             if wordhigher then address = address+4;
8106             CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8107             BranchWritePC(MemA[address,4]);
8108             if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8109 #endif
8110 
8111     bool success = false;
8112 
8113     if (ConditionPassed(opcode))
8114     {
8115         uint32_t n;
8116         bool wback;
8117         bool increment;
8118         bool wordhigher;
8119 
8120         // EncodingSpecificOperations();
8121         switch (encoding)
8122         {
8123             case eEncodingT1:
8124                 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE;
8125                 n = Bits32 (opcode, 19, 16);
8126                 wback = BitIsSet (opcode, 21);
8127                 increment = false;
8128                 wordhigher = false;
8129 
8130                 // if n == 15 then UNPREDICTABLE;
8131                 if (n == 15)
8132                     return false;
8133 
8134                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8135                 if (InITBlock() && !LastInITBlock())
8136                     return false;
8137 
8138                 break;
8139 
8140             case eEncodingT2:
8141                 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8142                 n = Bits32 (opcode, 19, 16);
8143                 wback = BitIsSet (opcode, 21);
8144                 increment = true;
8145                 wordhigher = false;
8146 
8147                 // if n == 15 then UNPREDICTABLE;
8148                 if (n == 15)
8149                     return false;
8150 
8151                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8152                 if (InITBlock() && !LastInITBlock())
8153                     return false;
8154 
8155                 break;
8156 
8157             case eEncodingA1:
8158                 // n = UInt(Rn);
8159                 n = Bits32 (opcode, 19, 16);
8160 
8161                 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8162                 wback = BitIsSet (opcode, 21);
8163                 increment = BitIsSet (opcode, 23);
8164                 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23));
8165 
8166                 // if n == 15 then UNPREDICTABLE;
8167                 if (n == 15)
8168                     return false;
8169 
8170                 break;
8171 
8172             default:
8173                 return false;
8174         }
8175 
8176         // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8177         if (!CurrentModeIsPrivileged ())
8178             // UNPREDICTABLE;
8179             return false;
8180         else
8181         {
8182             uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8183             if (!success)
8184                 return false;
8185 
8186             addr_t address;
8187             // address = if increment then R[n] else R[n]-8;
8188             if (increment)
8189                 address = Rn;
8190             else
8191                 address = Rn - 8;
8192 
8193             // if wordhigher then address = address+4;
8194             if (wordhigher)
8195                 address = address + 4;
8196 
8197             // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8198             RegisterInfo base_reg;
8199             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8200 
8201             EmulateInstruction::Context context;
8202             context.type = eContextReturnFromException;
8203             context.SetRegisterPlusOffset (base_reg, address - Rn);
8204 
8205             uint64_t data = MemARead (context, address + 4, 4, 0, &success);
8206             if (!success)
8207                 return false;
8208 
8209             CPSRWriteByInstr (data, 15, true);
8210 
8211             // BranchWritePC(MemA[address,4]);
8212             uint64_t data2 = MemARead (context, address, 4, 0, &success);
8213             if (!success)
8214                 return false;
8215 
8216             BranchWritePC (context, data2);
8217 
8218             // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8219             if (wback)
8220             {
8221                 context.type = eContextAdjustBaseRegister;
8222                 if (increment)
8223                 {
8224                     context.SetOffset (8);
8225                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8))
8226                         return false;
8227                 }
8228                 else
8229                 {
8230                     context.SetOffset (-8);
8231                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8))
8232                         return false;
8233                 }
8234             } // if wback
8235         }
8236     } // if ConditionPassed()
8237     return true;
8238 }
8239 
8240 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
8241 // and writes the result to the destination register.  It can optionally update the condition flags based on
8242 // the result.
8243 bool
8244 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding)
8245 {
8246 #if 0
8247     // ARM pseudo code...
8248     if ConditionPassed() then
8249         EncodingSpecificOperations();
8250         result = R[n] EOR imm32;
8251         if d == 15 then         // Can only occur for ARM encoding
8252             ALUWritePC(result); // setflags is always FALSE here
8253         else
8254             R[d] = result;
8255             if setflags then
8256                 APSR.N = result<31>;
8257                 APSR.Z = IsZeroBit(result);
8258                 APSR.C = carry;
8259                 // APSR.V unchanged
8260 #endif
8261 
8262     bool success = false;
8263 
8264     if (ConditionPassed(opcode))
8265     {
8266         uint32_t Rd, Rn;
8267         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8268         bool setflags;
8269         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8270         switch (encoding)
8271         {
8272         case eEncodingT1:
8273             Rd = Bits32(opcode, 11, 8);
8274             Rn = Bits32(opcode, 19, 16);
8275             setflags = BitIsSet(opcode, 20);
8276             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8277             // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8278             if (Rd == 15 && setflags)
8279                 return EmulateTEQImm (opcode, eEncodingT1);
8280             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8281                 return false;
8282             break;
8283         case eEncodingA1:
8284             Rd = Bits32(opcode, 15, 12);
8285             Rn = Bits32(opcode, 19, 16);
8286             setflags = BitIsSet(opcode, 20);
8287             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8288 
8289             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8290             if (Rd == 15 && setflags)
8291                 return EmulateSUBSPcLrEtc (opcode, encoding);
8292             break;
8293         default:
8294             return false;
8295         }
8296 
8297         // Read the first operand.
8298         uint32_t val1 = ReadCoreReg(Rn, &success);
8299         if (!success)
8300             return false;
8301 
8302         uint32_t result = val1 ^ imm32;
8303 
8304         EmulateInstruction::Context context;
8305         context.type = EmulateInstruction::eContextImmediate;
8306         context.SetNoArgs ();
8307 
8308         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8309             return false;
8310     }
8311     return true;
8312 }
8313 
8314 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an
8315 // optionally-shifted register value, and writes the result to the destination register.
8316 // It can optionally update the condition flags based on the result.
8317 bool
8318 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding)
8319 {
8320 #if 0
8321     // ARM pseudo code...
8322     if ConditionPassed() then
8323         EncodingSpecificOperations();
8324         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8325         result = R[n] EOR shifted;
8326         if d == 15 then         // Can only occur for ARM encoding
8327             ALUWritePC(result); // setflags is always FALSE here
8328         else
8329             R[d] = result;
8330             if setflags then
8331                 APSR.N = result<31>;
8332                 APSR.Z = IsZeroBit(result);
8333                 APSR.C = carry;
8334                 // APSR.V unchanged
8335 #endif
8336 
8337     bool success = false;
8338 
8339     if (ConditionPassed(opcode))
8340     {
8341         uint32_t Rd, Rn, Rm;
8342         ARM_ShifterType shift_t;
8343         uint32_t shift_n; // the shift applied to the value read from Rm
8344         bool setflags;
8345         uint32_t carry;
8346         switch (encoding)
8347         {
8348         case eEncodingT1:
8349             Rd = Rn = Bits32(opcode, 2, 0);
8350             Rm = Bits32(opcode, 5, 3);
8351             setflags = !InITBlock();
8352             shift_t = SRType_LSL;
8353             shift_n = 0;
8354             break;
8355         case eEncodingT2:
8356             Rd = Bits32(opcode, 11, 8);
8357             Rn = Bits32(opcode, 19, 16);
8358             Rm = Bits32(opcode, 3, 0);
8359             setflags = BitIsSet(opcode, 20);
8360             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8361             // if Rd == '1111' && S == '1' then SEE TEQ (register);
8362             if (Rd == 15 && setflags)
8363                 return EmulateTEQReg (opcode, eEncodingT1);
8364             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8365                 return false;
8366             break;
8367         case eEncodingA1:
8368             Rd = Bits32(opcode, 15, 12);
8369             Rn = Bits32(opcode, 19, 16);
8370             Rm = Bits32(opcode, 3, 0);
8371             setflags = BitIsSet(opcode, 20);
8372             shift_n = DecodeImmShiftARM(opcode, shift_t);
8373 
8374             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8375             if (Rd == 15 && setflags)
8376                 return EmulateSUBSPcLrEtc (opcode, encoding);
8377             break;
8378         default:
8379             return false;
8380         }
8381 
8382         // Read the first operand.
8383         uint32_t val1 = ReadCoreReg(Rn, &success);
8384         if (!success)
8385             return false;
8386 
8387         // Read the second operand.
8388         uint32_t val2 = ReadCoreReg(Rm, &success);
8389         if (!success)
8390             return false;
8391 
8392         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8393         if (!success)
8394             return false;
8395         uint32_t result = val1 ^ shifted;
8396 
8397         EmulateInstruction::Context context;
8398         context.type = EmulateInstruction::eContextImmediate;
8399         context.SetNoArgs ();
8400 
8401         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8402             return false;
8403     }
8404     return true;
8405 }
8406 
8407 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and
8408 // writes the result to the destination register.  It can optionally update the condition flags based
8409 // on the result.
8410 bool
8411 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding)
8412 {
8413 #if 0
8414     // ARM pseudo code...
8415     if ConditionPassed() then
8416         EncodingSpecificOperations();
8417         result = R[n] OR imm32;
8418         if d == 15 then         // Can only occur for ARM encoding
8419             ALUWritePC(result); // setflags is always FALSE here
8420         else
8421             R[d] = result;
8422             if setflags then
8423                 APSR.N = result<31>;
8424                 APSR.Z = IsZeroBit(result);
8425                 APSR.C = carry;
8426                 // APSR.V unchanged
8427 #endif
8428 
8429     bool success = false;
8430 
8431     if (ConditionPassed(opcode))
8432     {
8433         uint32_t Rd, Rn;
8434         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8435         bool setflags;
8436         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8437         switch (encoding)
8438         {
8439         case eEncodingT1:
8440             Rd = Bits32(opcode, 11, 8);
8441             Rn = Bits32(opcode, 19, 16);
8442             setflags = BitIsSet(opcode, 20);
8443             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8444             // if Rn == '1111' then SEE MOV (immediate);
8445             if (Rn == 15)
8446                 return EmulateMOVRdImm (opcode, eEncodingT2);
8447             if (BadReg(Rd) || Rn == 13)
8448                 return false;
8449             break;
8450         case eEncodingA1:
8451             Rd = Bits32(opcode, 15, 12);
8452             Rn = Bits32(opcode, 19, 16);
8453             setflags = BitIsSet(opcode, 20);
8454             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8455 
8456             if (Rd == 15 && setflags)
8457                 return EmulateSUBSPcLrEtc (opcode, encoding);
8458             break;
8459         default:
8460             return false;
8461         }
8462 
8463         // Read the first operand.
8464         uint32_t val1 = ReadCoreReg(Rn, &success);
8465         if (!success)
8466             return false;
8467 
8468         uint32_t result = val1 | imm32;
8469 
8470         EmulateInstruction::Context context;
8471         context.type = EmulateInstruction::eContextImmediate;
8472         context.SetNoArgs ();
8473 
8474         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8475             return false;
8476     }
8477     return true;
8478 }
8479 
8480 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register
8481 // value, and writes the result to the destination register.  It can optionally update the condition flags based
8482 // on the result.
8483 bool
8484 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding)
8485 {
8486 #if 0
8487     // ARM pseudo code...
8488     if ConditionPassed() then
8489         EncodingSpecificOperations();
8490         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8491         result = R[n] OR shifted;
8492         if d == 15 then         // Can only occur for ARM encoding
8493             ALUWritePC(result); // setflags is always FALSE here
8494         else
8495             R[d] = result;
8496             if setflags then
8497                 APSR.N = result<31>;
8498                 APSR.Z = IsZeroBit(result);
8499                 APSR.C = carry;
8500                 // APSR.V unchanged
8501 #endif
8502 
8503     bool success = false;
8504 
8505     if (ConditionPassed(opcode))
8506     {
8507         uint32_t Rd, Rn, Rm;
8508         ARM_ShifterType shift_t;
8509         uint32_t shift_n; // the shift applied to the value read from Rm
8510         bool setflags;
8511         uint32_t carry;
8512         switch (encoding)
8513         {
8514         case eEncodingT1:
8515             Rd = Rn = Bits32(opcode, 2, 0);
8516             Rm = Bits32(opcode, 5, 3);
8517             setflags = !InITBlock();
8518             shift_t = SRType_LSL;
8519             shift_n = 0;
8520             break;
8521         case eEncodingT2:
8522             Rd = Bits32(opcode, 11, 8);
8523             Rn = Bits32(opcode, 19, 16);
8524             Rm = Bits32(opcode, 3, 0);
8525             setflags = BitIsSet(opcode, 20);
8526             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8527             // if Rn == '1111' then SEE MOV (register);
8528             if (Rn == 15)
8529                 return EmulateMOVRdRm (opcode, eEncodingT3);
8530             if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
8531                 return false;
8532             break;
8533         case eEncodingA1:
8534             Rd = Bits32(opcode, 15, 12);
8535             Rn = Bits32(opcode, 19, 16);
8536             Rm = Bits32(opcode, 3, 0);
8537             setflags = BitIsSet(opcode, 20);
8538             shift_n = DecodeImmShiftARM(opcode, shift_t);
8539 
8540             if (Rd == 15 && setflags)
8541                 return EmulateSUBSPcLrEtc (opcode, encoding);
8542             break;
8543         default:
8544             return false;
8545         }
8546 
8547         // Read the first operand.
8548         uint32_t val1 = ReadCoreReg(Rn, &success);
8549         if (!success)
8550             return false;
8551 
8552         // Read the second operand.
8553         uint32_t val2 = ReadCoreReg(Rm, &success);
8554         if (!success)
8555             return false;
8556 
8557         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8558         if (!success)
8559             return false;
8560         uint32_t result = val1 | shifted;
8561 
8562         EmulateInstruction::Context context;
8563         context.type = EmulateInstruction::eContextImmediate;
8564         context.SetNoArgs ();
8565 
8566         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8567             return false;
8568     }
8569     return true;
8570 }
8571 
8572 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to
8573 // the destination register. It can optionally update the condition flags based on the result.
8574 bool
8575 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding)
8576 {
8577 #if 0
8578     // ARM pseudo code...
8579     if ConditionPassed() then
8580         EncodingSpecificOperations();
8581         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
8582         if d == 15 then         // Can only occur for ARM encoding
8583             ALUWritePC(result); // setflags is always FALSE here
8584         else
8585             R[d] = result;
8586             if setflags then
8587                 APSR.N = result<31>;
8588                 APSR.Z = IsZeroBit(result);
8589                 APSR.C = carry;
8590                 APSR.V = overflow;
8591 #endif
8592 
8593     bool success = false;
8594 
8595     uint32_t Rd; // the destination register
8596     uint32_t Rn; // the first operand
8597     bool setflags;
8598     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8599     switch (encoding) {
8600     case eEncodingT1:
8601         Rd = Bits32(opcode, 2, 0);
8602         Rn = Bits32(opcode, 5, 3);
8603         setflags = !InITBlock();
8604         imm32 = 0;
8605         break;
8606     case eEncodingT2:
8607         Rd = Bits32(opcode, 11, 8);
8608         Rn = Bits32(opcode, 19, 16);
8609         setflags = BitIsSet(opcode, 20);
8610         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8611         if (BadReg(Rd) || BadReg(Rn))
8612             return false;
8613         break;
8614     case eEncodingA1:
8615         Rd = Bits32(opcode, 15, 12);
8616         Rn = Bits32(opcode, 19, 16);
8617         setflags = BitIsSet(opcode, 20);
8618         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8619 
8620         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8621         if (Rd == 15 && setflags)
8622             return EmulateSUBSPcLrEtc (opcode, encoding);
8623         break;
8624     default:
8625         return false;
8626     }
8627     // Read the register value from the operand register Rn.
8628     uint32_t reg_val = ReadCoreReg(Rn, &success);
8629     if (!success)
8630         return false;
8631 
8632     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
8633 
8634     EmulateInstruction::Context context;
8635     context.type = EmulateInstruction::eContextImmediate;
8636     context.SetNoArgs ();
8637 
8638     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8639         return false;
8640 
8641     return true;
8642 }
8643 
8644 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the
8645 // result to the destination register. It can optionally update the condition flags based on the result.
8646 bool
8647 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding)
8648 {
8649 #if 0
8650     // ARM pseudo code...
8651     if ConditionPassed() then
8652         EncodingSpecificOperations();
8653         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8654         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
8655         if d == 15 then         // Can only occur for ARM encoding
8656             ALUWritePC(result); // setflags is always FALSE here
8657         else
8658             R[d] = result;
8659             if setflags then
8660                 APSR.N = result<31>;
8661                 APSR.Z = IsZeroBit(result);
8662                 APSR.C = carry;
8663                 APSR.V = overflow;
8664 #endif
8665 
8666     bool success = false;
8667 
8668     uint32_t Rd; // the destination register
8669     uint32_t Rn; // the first operand
8670     uint32_t Rm; // the second operand
8671     bool setflags;
8672     ARM_ShifterType shift_t;
8673     uint32_t shift_n; // the shift applied to the value read from Rm
8674     switch (encoding) {
8675     case eEncodingT1:
8676         Rd = Bits32(opcode, 11, 8);
8677         Rn = Bits32(opcode, 19, 16);
8678         Rm = Bits32(opcode, 3, 0);
8679         setflags = BitIsSet(opcode, 20);
8680         shift_n = DecodeImmShiftThumb(opcode, shift_t);
8681         // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
8682         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8683             return false;
8684         break;
8685     case eEncodingA1:
8686         Rd = Bits32(opcode, 15, 12);
8687         Rn = Bits32(opcode, 19, 16);
8688         Rm = Bits32(opcode, 3, 0);
8689         setflags = BitIsSet(opcode, 20);
8690         shift_n = DecodeImmShiftARM(opcode, shift_t);
8691 
8692         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8693         if (Rd == 15 && setflags)
8694             return EmulateSUBSPcLrEtc (opcode, encoding);
8695         break;
8696     default:
8697         return false;
8698     }
8699     // Read the register value from register Rn.
8700     uint32_t val1 = ReadCoreReg(Rn, &success);
8701     if (!success)
8702         return false;
8703 
8704     // Read the register value from register Rm.
8705     uint32_t val2 = ReadCoreReg(Rm, &success);
8706     if (!success)
8707         return false;
8708 
8709     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8710     if (!success)
8711         return false;
8712     AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
8713 
8714     EmulateInstruction::Context context;
8715     context.type = EmulateInstruction::eContextImmediate;
8716     context.SetNoArgs();
8717     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8718         return false;
8719 
8720     return true;
8721 }
8722 
8723 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from
8724 // an immediate value, and writes the result to the destination register. It can optionally update the condition
8725 // flags based on the result.
8726 bool
8727 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding)
8728 {
8729 #if 0
8730     // ARM pseudo code...
8731     if ConditionPassed() then
8732         EncodingSpecificOperations();
8733         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
8734         if d == 15 then
8735             ALUWritePC(result); // setflags is always FALSE here
8736         else
8737             R[d] = result;
8738             if setflags then
8739                 APSR.N = result<31>;
8740                 APSR.Z = IsZeroBit(result);
8741                 APSR.C = carry;
8742                 APSR.V = overflow;
8743 #endif
8744 
8745     bool success = false;
8746 
8747     uint32_t Rd; // the destination register
8748     uint32_t Rn; // the first operand
8749     bool setflags;
8750     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8751     switch (encoding) {
8752     case eEncodingA1:
8753         Rd = Bits32(opcode, 15, 12);
8754         Rn = Bits32(opcode, 19, 16);
8755         setflags = BitIsSet(opcode, 20);
8756         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8757 
8758         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8759         if (Rd == 15 && setflags)
8760             return EmulateSUBSPcLrEtc  (opcode, encoding);
8761         break;
8762     default:
8763         return false;
8764     }
8765     // Read the register value from the operand register Rn.
8766     uint32_t reg_val = ReadCoreReg(Rn, &success);
8767     if (!success)
8768         return false;
8769 
8770     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
8771 
8772     EmulateInstruction::Context context;
8773     context.type = EmulateInstruction::eContextImmediate;
8774     context.SetNoArgs ();
8775 
8776     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8777         return false;
8778 
8779     return true;
8780 }
8781 
8782 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an
8783 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the
8784 // condition flags based on the result.
8785 bool
8786 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding)
8787 {
8788 #if 0
8789     // ARM pseudo code...
8790     if ConditionPassed() then
8791         EncodingSpecificOperations();
8792         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8793         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
8794         if d == 15 then
8795             ALUWritePC(result); // setflags is always FALSE here
8796         else
8797             R[d] = result;
8798             if setflags then
8799                 APSR.N = result<31>;
8800                 APSR.Z = IsZeroBit(result);
8801                 APSR.C = carry;
8802                 APSR.V = overflow;
8803 #endif
8804 
8805     bool success = false;
8806 
8807     uint32_t Rd; // the destination register
8808     uint32_t Rn; // the first operand
8809     uint32_t Rm; // the second operand
8810     bool setflags;
8811     ARM_ShifterType shift_t;
8812     uint32_t shift_n; // the shift applied to the value read from Rm
8813     switch (encoding) {
8814     case eEncodingA1:
8815         Rd = Bits32(opcode, 15, 12);
8816         Rn = Bits32(opcode, 19, 16);
8817         Rm = Bits32(opcode, 3, 0);
8818         setflags = BitIsSet(opcode, 20);
8819         shift_n = DecodeImmShiftARM(opcode, shift_t);
8820 
8821         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8822         if (Rd == 15 && setflags)
8823             return EmulateSUBSPcLrEtc (opcode, encoding);
8824         break;
8825     default:
8826         return false;
8827     }
8828     // Read the register value from register Rn.
8829     uint32_t val1 = ReadCoreReg(Rn, &success);
8830     if (!success)
8831         return false;
8832 
8833     // Read the register value from register Rm.
8834     uint32_t val2 = ReadCoreReg(Rm, &success);
8835     if (!success)
8836         return false;
8837 
8838     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8839     if (!success)
8840         return false;
8841     AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
8842 
8843     EmulateInstruction::Context context;
8844     context.type = EmulateInstruction::eContextImmediate;
8845     context.SetNoArgs();
8846     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8847         return false;
8848 
8849     return true;
8850 }
8851 
8852 // Subtract with Carry (immediate) subtracts an immediate value and the value of
8853 // NOT (Carry flag) from a register value, and writes the result to the destination register.
8854 // It can optionally update the condition flags based on the result.
8855 bool
8856 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding)
8857 {
8858 #if 0
8859     // ARM pseudo code...
8860     if ConditionPassed() then
8861         EncodingSpecificOperations();
8862         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
8863         if d == 15 then         // Can only occur for ARM encoding
8864             ALUWritePC(result); // setflags is always FALSE here
8865         else
8866             R[d] = result;
8867             if setflags then
8868                 APSR.N = result<31>;
8869                 APSR.Z = IsZeroBit(result);
8870                 APSR.C = carry;
8871                 APSR.V = overflow;
8872 #endif
8873 
8874     bool success = false;
8875 
8876     uint32_t Rd; // the destination register
8877     uint32_t Rn; // the first operand
8878     bool setflags;
8879     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8880     switch (encoding) {
8881     case eEncodingT1:
8882         Rd = Bits32(opcode, 11, 8);
8883         Rn = Bits32(opcode, 19, 16);
8884         setflags = BitIsSet(opcode, 20);
8885         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8886         if (BadReg(Rd) || BadReg(Rn))
8887             return false;
8888         break;
8889     case eEncodingA1:
8890         Rd = Bits32(opcode, 15, 12);
8891         Rn = Bits32(opcode, 19, 16);
8892         setflags = BitIsSet(opcode, 20);
8893         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8894 
8895         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8896         if (Rd == 15 && setflags)
8897             return EmulateSUBSPcLrEtc (opcode, encoding);
8898         break;
8899     default:
8900         return false;
8901     }
8902     // Read the register value from the operand register Rn.
8903     uint32_t reg_val = ReadCoreReg(Rn, &success);
8904     if (!success)
8905         return false;
8906 
8907     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
8908 
8909     EmulateInstruction::Context context;
8910     context.type = EmulateInstruction::eContextImmediate;
8911     context.SetNoArgs ();
8912 
8913     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8914         return false;
8915 
8916     return true;
8917 }
8918 
8919 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of
8920 // NOT (Carry flag) from a register value, and writes the result to the destination register.
8921 // It can optionally update the condition flags based on the result.
8922 bool
8923 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding)
8924 {
8925 #if 0
8926     // ARM pseudo code...
8927     if ConditionPassed() then
8928         EncodingSpecificOperations();
8929         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8930         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
8931         if d == 15 then         // Can only occur for ARM encoding
8932             ALUWritePC(result); // setflags is always FALSE here
8933         else
8934             R[d] = result;
8935             if setflags then
8936                 APSR.N = result<31>;
8937                 APSR.Z = IsZeroBit(result);
8938                 APSR.C = carry;
8939                 APSR.V = overflow;
8940 #endif
8941 
8942     bool success = false;
8943 
8944     uint32_t Rd; // the destination register
8945     uint32_t Rn; // the first operand
8946     uint32_t Rm; // the second operand
8947     bool setflags;
8948     ARM_ShifterType shift_t;
8949     uint32_t shift_n; // the shift applied to the value read from Rm
8950     switch (encoding) {
8951     case eEncodingT1:
8952         Rd = Rn = Bits32(opcode, 2, 0);
8953         Rm = Bits32(opcode, 5, 3);
8954         setflags = !InITBlock();
8955         shift_t = SRType_LSL;
8956         shift_n = 0;
8957         break;
8958     case eEncodingT2:
8959         Rd = Bits32(opcode, 11, 8);
8960         Rn = Bits32(opcode, 19, 16);
8961         Rm = Bits32(opcode, 3, 0);
8962         setflags = BitIsSet(opcode, 20);
8963         shift_n = DecodeImmShiftThumb(opcode, shift_t);
8964         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8965             return false;
8966         break;
8967     case eEncodingA1:
8968         Rd = Bits32(opcode, 15, 12);
8969         Rn = Bits32(opcode, 19, 16);
8970         Rm = Bits32(opcode, 3, 0);
8971         setflags = BitIsSet(opcode, 20);
8972         shift_n = DecodeImmShiftARM(opcode, shift_t);
8973 
8974         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8975         if (Rd == 15 && setflags)
8976             return EmulateSUBSPcLrEtc (opcode, encoding);
8977         break;
8978     default:
8979         return false;
8980     }
8981     // Read the register value from register Rn.
8982     uint32_t val1 = ReadCoreReg(Rn, &success);
8983     if (!success)
8984         return false;
8985 
8986     // Read the register value from register Rm.
8987     uint32_t val2 = ReadCoreReg(Rm, &success);
8988     if (!success)
8989         return false;
8990 
8991     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8992     if (!success)
8993         return false;
8994     AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
8995 
8996     EmulateInstruction::Context context;
8997     context.type = EmulateInstruction::eContextImmediate;
8998     context.SetNoArgs();
8999     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9000         return false;
9001 
9002     return true;
9003 }
9004 
9005 // This instruction subtracts an immediate value from a register value, and writes the result
9006 // to the destination register.  It can optionally update the condition flags based on the result.
9007 bool
9008 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding)
9009 {
9010 #if 0
9011     // ARM pseudo code...
9012     if ConditionPassed() then
9013         EncodingSpecificOperations();
9014         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9015         R[d] = result;
9016         if setflags then
9017             APSR.N = result<31>;
9018             APSR.Z = IsZeroBit(result);
9019             APSR.C = carry;
9020             APSR.V = overflow;
9021 #endif
9022 
9023     bool success = false;
9024 
9025     uint32_t Rd; // the destination register
9026     uint32_t Rn; // the first operand
9027     bool setflags;
9028     uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9029     switch (encoding) {
9030     case eEncodingT1:
9031         Rd = Bits32(opcode, 2, 0);
9032         Rn = Bits32(opcode, 5, 3);
9033         setflags = !InITBlock();
9034         imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9035         break;
9036     case eEncodingT2:
9037         Rd = Rn = Bits32(opcode, 10, 8);
9038         setflags = !InITBlock();
9039         imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9040         break;
9041     case eEncodingT3:
9042         Rd = Bits32(opcode, 11, 8);
9043         Rn = Bits32(opcode, 19, 16);
9044         setflags = BitIsSet(opcode, 20);
9045         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9046 
9047         // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9048         if (Rd == 15 && setflags)
9049             return EmulateCMPImm (opcode, eEncodingT2);
9050 
9051         // if Rn == '1101' then SEE SUB (SP minus immediate);
9052         if (Rn == 13)
9053             return EmulateSUBSPImm (opcode, eEncodingT2);
9054 
9055         // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9056         if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9057             return false;
9058         break;
9059     case eEncodingT4:
9060         Rd = Bits32(opcode, 11, 8);
9061         Rn = Bits32(opcode, 19, 16);
9062         setflags = BitIsSet(opcode, 20);
9063         imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9064 
9065         // if Rn == '1111' then SEE ADR;
9066         if (Rn == 15)
9067             return EmulateADR (opcode, eEncodingT2);
9068 
9069         // if Rn == '1101' then SEE SUB (SP minus immediate);
9070         if (Rn == 13)
9071             return EmulateSUBSPImm (opcode, eEncodingT3);
9072 
9073         if (BadReg(Rd))
9074             return false;
9075         break;
9076     default:
9077         return false;
9078     }
9079     // Read the register value from the operand register Rn.
9080     uint32_t reg_val = ReadCoreReg(Rn, &success);
9081     if (!success)
9082         return false;
9083 
9084     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9085 
9086     EmulateInstruction::Context context;
9087     context.type = EmulateInstruction::eContextImmediate;
9088     context.SetNoArgs ();
9089 
9090     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9091         return false;
9092 
9093     return true;
9094 }
9095 
9096 // This instruction subtracts an immediate value from a register value, and writes the result
9097 // to the destination register.  It can optionally update the condition flags based on the result.
9098 bool
9099 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9100 {
9101 #if 0
9102     // ARM pseudo code...
9103     if ConditionPassed() then
9104         EncodingSpecificOperations();
9105         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9106         if d == 15 then
9107             ALUWritePC(result); // setflags is always FALSE here
9108         else
9109             R[d] = result;
9110             if setflags then
9111                 APSR.N = result<31>;
9112                 APSR.Z = IsZeroBit(result);
9113                 APSR.C = carry;
9114                 APSR.V = overflow;
9115 #endif
9116 
9117     bool success = false;
9118 
9119     uint32_t Rd; // the destination register
9120     uint32_t Rn; // the first operand
9121     bool setflags;
9122     uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9123     switch (encoding) {
9124     case eEncodingA1:
9125         Rd = Bits32(opcode, 15, 12);
9126         Rn = Bits32(opcode, 19, 16);
9127         setflags = BitIsSet(opcode, 20);
9128         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9129 
9130         // if Rn == '1111' && S == '0' then SEE ADR;
9131         if (Rn == 15 && !setflags)
9132             return EmulateADR (opcode, eEncodingA2);
9133 
9134         // if Rn == '1101' then SEE SUB (SP minus immediate);
9135         if (Rn == 13)
9136             return EmulateSUBSPImm (opcode, eEncodingA1);
9137 
9138         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9139         if (Rd == 15 && setflags)
9140             return EmulateSUBSPcLrEtc (opcode, encoding);
9141         break;
9142     default:
9143         return false;
9144     }
9145     // Read the register value from the operand register Rn.
9146     uint32_t reg_val = ReadCoreReg(Rn, &success);
9147     if (!success)
9148         return false;
9149 
9150     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9151 
9152     EmulateInstruction::Context context;
9153     context.type = EmulateInstruction::eContextImmediate;
9154     context.SetNoArgs ();
9155 
9156     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9157         return false;
9158 
9159     return true;
9160 }
9161 
9162 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an
9163 // immediate value.  It updates the condition flags based on the result, and discards the result.
9164 bool
9165 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding)
9166 {
9167 #if 0
9168     // ARM pseudo code...
9169     if ConditionPassed() then
9170         EncodingSpecificOperations();
9171         result = R[n] EOR imm32;
9172         APSR.N = result<31>;
9173         APSR.Z = IsZeroBit(result);
9174         APSR.C = carry;
9175         // APSR.V unchanged
9176 #endif
9177 
9178     bool success = false;
9179 
9180     if (ConditionPassed(opcode))
9181     {
9182         uint32_t Rn;
9183         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9184         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9185         switch (encoding)
9186         {
9187         case eEncodingT1:
9188             Rn = Bits32(opcode, 19, 16);
9189             imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9190             if (BadReg(Rn))
9191                 return false;
9192             break;
9193         case eEncodingA1:
9194             Rn = Bits32(opcode, 19, 16);
9195             imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9196             break;
9197         default:
9198             return false;
9199         }
9200 
9201         // Read the first operand.
9202         uint32_t val1 = ReadCoreReg(Rn, &success);
9203         if (!success)
9204             return false;
9205 
9206         uint32_t result = val1 ^ imm32;
9207 
9208         EmulateInstruction::Context context;
9209         context.type = EmulateInstruction::eContextImmediate;
9210         context.SetNoArgs ();
9211 
9212         if (!WriteFlags(context, result, carry))
9213             return false;
9214     }
9215     return true;
9216 }
9217 
9218 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an
9219 // optionally-shifted register value.  It updates the condition flags based on the result, and discards
9220 // the result.
9221 bool
9222 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding)
9223 {
9224 #if 0
9225     // ARM pseudo code...
9226     if ConditionPassed() then
9227         EncodingSpecificOperations();
9228         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9229         result = R[n] EOR shifted;
9230         APSR.N = result<31>;
9231         APSR.Z = IsZeroBit(result);
9232         APSR.C = carry;
9233         // APSR.V unchanged
9234 #endif
9235 
9236     bool success = false;
9237 
9238     if (ConditionPassed(opcode))
9239     {
9240         uint32_t Rn, Rm;
9241         ARM_ShifterType shift_t;
9242         uint32_t shift_n; // the shift applied to the value read from Rm
9243         uint32_t carry;
9244         switch (encoding)
9245         {
9246         case eEncodingT1:
9247             Rn = Bits32(opcode, 19, 16);
9248             Rm = Bits32(opcode, 3, 0);
9249             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9250             if (BadReg(Rn) || BadReg(Rm))
9251                 return false;
9252             break;
9253         case eEncodingA1:
9254             Rn = Bits32(opcode, 19, 16);
9255             Rm = Bits32(opcode, 3, 0);
9256             shift_n = DecodeImmShiftARM(opcode, shift_t);
9257             break;
9258         default:
9259             return false;
9260         }
9261 
9262         // Read the first operand.
9263         uint32_t val1 = ReadCoreReg(Rn, &success);
9264         if (!success)
9265             return false;
9266 
9267         // Read the second operand.
9268         uint32_t val2 = ReadCoreReg(Rm, &success);
9269         if (!success)
9270             return false;
9271 
9272         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9273         if (!success)
9274             return false;
9275         uint32_t result = val1 ^ shifted;
9276 
9277         EmulateInstruction::Context context;
9278         context.type = EmulateInstruction::eContextImmediate;
9279         context.SetNoArgs ();
9280 
9281         if (!WriteFlags(context, result, carry))
9282             return false;
9283     }
9284     return true;
9285 }
9286 
9287 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value.
9288 // It updates the condition flags based on the result, and discards the result.
9289 bool
9290 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding)
9291 {
9292 #if 0
9293     // ARM pseudo code...
9294     if ConditionPassed() then
9295         EncodingSpecificOperations();
9296         result = R[n] AND imm32;
9297         APSR.N = result<31>;
9298         APSR.Z = IsZeroBit(result);
9299         APSR.C = carry;
9300         // APSR.V unchanged
9301 #endif
9302 
9303     bool success = false;
9304 
9305     if (ConditionPassed(opcode))
9306     {
9307         uint32_t Rn;
9308         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9309         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9310         switch (encoding)
9311         {
9312         case eEncodingT1:
9313             Rn = Bits32(opcode, 19, 16);
9314             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9315             if (BadReg(Rn))
9316                 return false;
9317             break;
9318         case eEncodingA1:
9319             Rn = Bits32(opcode, 19, 16);
9320             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9321             break;
9322         default:
9323             return false;
9324         }
9325 
9326         // Read the first operand.
9327         uint32_t val1 = ReadCoreReg(Rn, &success);
9328         if (!success)
9329             return false;
9330 
9331         uint32_t result = val1 & imm32;
9332 
9333         EmulateInstruction::Context context;
9334         context.type = EmulateInstruction::eContextImmediate;
9335         context.SetNoArgs ();
9336 
9337         if (!WriteFlags(context, result, carry))
9338             return false;
9339     }
9340     return true;
9341 }
9342 
9343 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value.
9344 // It updates the condition flags based on the result, and discards the result.
9345 bool
9346 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding)
9347 {
9348 #if 0
9349     // ARM pseudo code...
9350     if ConditionPassed() then
9351         EncodingSpecificOperations();
9352         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9353         result = R[n] AND shifted;
9354         APSR.N = result<31>;
9355         APSR.Z = IsZeroBit(result);
9356         APSR.C = carry;
9357         // APSR.V unchanged
9358 #endif
9359 
9360     bool success = false;
9361 
9362     if (ConditionPassed(opcode))
9363     {
9364         uint32_t Rn, Rm;
9365         ARM_ShifterType shift_t;
9366         uint32_t shift_n; // the shift applied to the value read from Rm
9367         uint32_t carry;
9368         switch (encoding)
9369         {
9370         case eEncodingT1:
9371             Rn = Bits32(opcode, 2, 0);
9372             Rm = Bits32(opcode, 5, 3);
9373             shift_t = SRType_LSL;
9374             shift_n = 0;
9375             break;
9376         case eEncodingT2:
9377             Rn = Bits32(opcode, 19, 16);
9378             Rm = Bits32(opcode, 3, 0);
9379             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9380             if (BadReg(Rn) || BadReg(Rm))
9381                 return false;
9382             break;
9383         case eEncodingA1:
9384             Rn = Bits32(opcode, 19, 16);
9385             Rm = Bits32(opcode, 3, 0);
9386             shift_n = DecodeImmShiftARM(opcode, shift_t);
9387             break;
9388         default:
9389             return false;
9390         }
9391 
9392         // Read the first operand.
9393         uint32_t val1 = ReadCoreReg(Rn, &success);
9394         if (!success)
9395             return false;
9396 
9397         // Read the second operand.
9398         uint32_t val2 = ReadCoreReg(Rm, &success);
9399         if (!success)
9400             return false;
9401 
9402         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9403         if (!success)
9404             return false;
9405         uint32_t result = val1 & shifted;
9406 
9407         EmulateInstruction::Context context;
9408         context.type = EmulateInstruction::eContextImmediate;
9409         context.SetNoArgs ();
9410 
9411         if (!WriteFlags(context, result, carry))
9412             return false;
9413     }
9414     return true;
9415 }
9416 
9417 // A8.6.216 SUB (SP minus register)
9418 bool
9419 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding)
9420 {
9421 #if 0
9422     if ConditionPassed() then
9423         EncodingSpecificOperations();
9424         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9425         (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9426         if d == 15 then // Can only occur for ARM encoding
9427             ALUWritePC(result); // setflags is always FALSE here
9428         else
9429             R[d] = result;
9430             if setflags then
9431                 APSR.N = result<31>;
9432                 APSR.Z = IsZeroBit(result);
9433                 APSR.C = carry;
9434                 APSR.V = overflow;
9435 #endif
9436 
9437     bool success = false;
9438 
9439     if (ConditionPassed(opcode))
9440     {
9441         uint32_t d;
9442         uint32_t m;
9443         bool setflags;
9444         ARM_ShifterType shift_t;
9445         uint32_t shift_n;
9446 
9447         switch (encoding)
9448         {
9449             case eEncodingT1:
9450                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9451                 d = Bits32 (opcode, 11, 8);
9452                 m = Bits32 (opcode, 3, 0);
9453                 setflags = BitIsSet (opcode, 20);
9454 
9455                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9456                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9457 
9458                 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE;
9459                 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
9460                     return false;
9461 
9462                 // if d == 15 || BadReg(m) then UNPREDICTABLE;
9463                 if ((d == 15) || BadReg (m))
9464                     return false;
9465                 break;
9466 
9467             case eEncodingA1:
9468                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9469                 d = Bits32 (opcode, 15, 12);
9470                 m = Bits32 (opcode, 3, 0);
9471                 setflags = BitIsSet (opcode, 20);
9472 
9473                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9474                 if (d == 15 && setflags)
9475                     EmulateSUBSPcLrEtc (opcode, encoding);
9476 
9477                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9478                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9479                 break;
9480 
9481             default:
9482                 return false;
9483         }
9484 
9485         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9486         uint32_t Rm = ReadCoreReg (m, &success);
9487         if (!success)
9488             return false;
9489 
9490         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9491         if (!success)
9492             return false;
9493 
9494         // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9495         uint32_t sp_val = ReadCoreReg (SP_REG, &success);
9496         if (!success)
9497             return false;
9498 
9499         AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1);
9500 
9501         EmulateInstruction::Context context;
9502         context.type = eContextArithmetic;
9503         RegisterInfo sp_reg;
9504         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
9505         RegisterInfo dwarf_reg;
9506         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
9507         context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
9508 
9509         if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9510             return false;
9511     }
9512     return true;
9513 }
9514 
9515 
9516 // A8.6.7 ADD (register-shifted register)
9517 bool
9518 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding)
9519 {
9520 #if 0
9521     if ConditionPassed() then
9522         EncodingSpecificOperations();
9523         shift_n = UInt(R[s]<7:0>);
9524         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9525         (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9526         R[d] = result;
9527         if setflags then
9528             APSR.N = result<31>;
9529             APSR.Z = IsZeroBit(result);
9530             APSR.C = carry;
9531             APSR.V = overflow;
9532 #endif
9533 
9534     bool success = false;
9535 
9536     if (ConditionPassed(opcode))
9537     {
9538         uint32_t d;
9539         uint32_t n;
9540         uint32_t m;
9541         uint32_t s;
9542         bool setflags;
9543         ARM_ShifterType shift_t;
9544 
9545         switch (encoding)
9546         {
9547             case eEncodingA1:
9548                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
9549                 d = Bits32 (opcode, 15, 12);
9550                 n = Bits32 (opcode, 19, 16);
9551                 m = Bits32 (opcode, 3, 0);
9552                 s = Bits32 (opcode, 11, 8);
9553 
9554                 // setflags = (S == �1�); shift_t = DecodeRegShift(type);
9555                 setflags = BitIsSet (opcode, 20);
9556                 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5));
9557 
9558                 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
9559                 if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
9560                     return false;
9561                 break;
9562 
9563             default:
9564                 return false;
9565         }
9566 
9567         // shift_n = UInt(R[s]<7:0>);
9568         uint32_t Rs = ReadCoreReg (s, &success);
9569         if (!success)
9570             return false;
9571 
9572         uint32_t shift_n = Bits32 (Rs, 7, 0);
9573 
9574         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9575         uint32_t Rm = ReadCoreReg (m, &success);
9576         if (!success)
9577             return false;
9578 
9579         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9580         if (!success)
9581             return false;
9582 
9583         // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9584         uint32_t Rn = ReadCoreReg (n, &success);
9585         if (!success)
9586             return false;
9587 
9588         AddWithCarryResult res = AddWithCarry (Rn, shifted, 0);
9589 
9590         // R[d] = result;
9591         EmulateInstruction::Context context;
9592         context.type = eContextArithmetic;
9593         RegisterInfo reg_n;
9594         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9595         RegisterInfo reg_m;
9596         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9597 
9598         context.SetRegisterRegisterOperands (reg_n, reg_m);
9599 
9600         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result))
9601             return false;
9602 
9603         // if setflags then
9604             // APSR.N = result<31>;
9605             // APSR.Z = IsZeroBit(result);
9606             // APSR.C = carry;
9607             // APSR.V = overflow;
9608         if (setflags)
9609             return WriteFlags (context, res.result, res.carry_out, res.overflow);
9610     }
9611     return true;
9612 }
9613 
9614 // A8.6.213 SUB (register)
9615 bool
9616 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding)
9617 {
9618 #if 0
9619     if ConditionPassed() then
9620         EncodingSpecificOperations();
9621         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9622         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9623         if d == 15 then // Can only occur for ARM encoding
9624             ALUWritePC(result); // setflags is always FALSE here
9625         else
9626             R[d] = result;
9627             if setflags then
9628                 APSR.N = result<31>;
9629                 APSR.Z = IsZeroBit(result);
9630                 APSR.C = carry;
9631                 APSR.V = overflow;
9632 #endif
9633 
9634     bool success = false;
9635 
9636     if (ConditionPassed(opcode))
9637     {
9638         uint32_t d;
9639         uint32_t n;
9640         uint32_t m;
9641         bool setflags;
9642         ARM_ShifterType shift_t;
9643         uint32_t shift_n;
9644 
9645         switch (encoding)
9646         {
9647             case eEncodingT1:
9648                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
9649                 d = Bits32 (opcode, 2, 0);
9650                 n = Bits32 (opcode, 5, 3);
9651                 m = Bits32 (opcode, 8, 6);
9652                 setflags = !InITBlock();
9653 
9654                 // (shift_t, shift_n) = (SRType_LSL, 0);
9655                 shift_t = SRType_LSL;
9656                 shift_n = 0;
9657 
9658                 break;
9659 
9660             case eEncodingT2:
9661                 // if Rd == �1111� && S == �1� then SEE CMP (register);
9662                 // if Rn == �1101� then SEE SUB (SP minus register);
9663                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9664                 d = Bits32 (opcode, 11, 8);
9665                 n = Bits32 (opcode, 19, 16);
9666                 m = Bits32 (opcode, 3, 0);
9667                 setflags = BitIsSet (opcode, 20);
9668 
9669                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9670                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9671 
9672                 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE;
9673                 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m))
9674                     return false;
9675 
9676                 break;
9677 
9678             case eEncodingA1:
9679                 // if Rn == �1101� then SEE SUB (SP minus register);
9680                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9681                 d = Bits32 (opcode, 15, 12);
9682                 n = Bits32 (opcode, 19, 16);
9683                 m = Bits32 (opcode, 3, 0);
9684                 setflags = BitIsSet (opcode, 20);
9685 
9686                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9687                 if ((d == 15) && setflags)
9688                     EmulateSUBSPcLrEtc (opcode, encoding);
9689 
9690                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9691                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9692 
9693                 break;
9694 
9695             default:
9696                 return false;
9697         }
9698 
9699         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9700         uint32_t Rm = ReadCoreReg (m, &success);
9701         if (!success)
9702             return false;
9703 
9704         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9705         if (!success)
9706             return false;
9707 
9708         // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9709         uint32_t Rn = ReadCoreReg (n, &success);
9710         if (!success)
9711             return false;
9712 
9713         AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1);
9714 
9715         // if d == 15 then // Can only occur for ARM encoding
9716             // ALUWritePC(result); // setflags is always FALSE here
9717         // else
9718             // R[d] = result;
9719             // if setflags then
9720                 // APSR.N = result<31>;
9721                 // APSR.Z = IsZeroBit(result);
9722                 // APSR.C = carry;
9723                 // APSR.V = overflow;
9724 
9725         EmulateInstruction::Context context;
9726         context.type = eContextArithmetic;
9727         RegisterInfo reg_n;
9728         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9729         RegisterInfo reg_m;
9730         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9731         context.SetRegisterRegisterOperands (reg_n, reg_m);
9732 
9733         if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9734             return false;
9735     }
9736     return true;
9737 }
9738 
9739 // A8.6.202 STREX
9740 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a
9741 // word from a register to memory if the executing processor has exclusive access to the memory addressed.
9742 bool
9743 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding)
9744 {
9745 #if 0
9746     if ConditionPassed() then
9747         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9748         address = R[n] + imm32;
9749         if ExclusiveMonitorsPass(address,4) then
9750             MemA[address,4] = R[t];
9751             R[d] = 0;
9752         else
9753             R[d] = 1;
9754 #endif
9755 
9756     bool success = false;
9757 
9758     if (ConditionPassed(opcode))
9759     {
9760         uint32_t d;
9761         uint32_t t;
9762         uint32_t n;
9763         uint32_t imm32;
9764         const uint32_t addr_byte_size = GetAddressByteSize();
9765 
9766         switch (encoding)
9767         {
9768             case eEncodingT1:
9769                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
9770                 d = Bits32 (opcode, 11, 8);
9771                 t = Bits32 (opcode, 15, 12);
9772                 n = Bits32 (opcode, 19, 16);
9773                 imm32 = Bits32 (opcode, 7, 0) << 2;
9774 
9775                 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
9776                 if (BadReg (d) || BadReg (t) || (n == 15))
9777                   return false;
9778 
9779                 // if d == n || d == t then UNPREDICTABLE;
9780                 if ((d == n) || (d == t))
9781                   return false;
9782 
9783                 break;
9784 
9785             case eEncodingA1:
9786                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset
9787                 d = Bits32 (opcode, 15, 12);
9788                 t = Bits32 (opcode, 3, 0);
9789                 n = Bits32 (opcode, 19, 16);
9790                 imm32 = 0;
9791 
9792                 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
9793                 if ((d == 15) || (t == 15) || (n == 15))
9794                     return false;
9795 
9796                 // if d == n || d == t then UNPREDICTABLE;
9797                 if ((d == n) || (d == t))
9798                     return false;
9799 
9800                 break;
9801 
9802             default:
9803                 return false;
9804         }
9805 
9806         // address = R[n] + imm32;
9807         uint32_t Rn = ReadCoreReg (n, &success);
9808         if (!success)
9809             return false;
9810 
9811         addr_t address = Rn + imm32;
9812 
9813         RegisterInfo base_reg;
9814         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9815         RegisterInfo data_reg;
9816         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9817         EmulateInstruction::Context context;
9818         context.type = eContextRegisterStore;
9819         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32);
9820 
9821         // if ExclusiveMonitorsPass(address,4) then
9822         // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this
9823         //                                                         always return true.
9824         if (true)
9825         {
9826             // MemA[address,4] = R[t];
9827             uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
9828             if (!success)
9829                 return false;
9830 
9831             if (!MemAWrite (context, address, Rt, addr_byte_size))
9832                 return false;
9833 
9834             // R[d] = 0;
9835             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0))
9836                 return false;
9837         }
9838         else
9839         {
9840             // R[d] = 1;
9841             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
9842                 return false;
9843         }
9844     }
9845     return true;
9846 }
9847 
9848 // A8.6.197 STRB (immediate, ARM)
9849 bool
9850 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9851 {
9852 #if 0
9853     if ConditionPassed() then
9854         EncodingSpecificOperations();
9855         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9856         address = if index then offset_addr else R[n];
9857         MemU[address,1] = R[t]<7:0>;
9858         if wback then R[n] = offset_addr;
9859 #endif
9860 
9861     bool success = false;
9862 
9863     if (ConditionPassed(opcode))
9864     {
9865         uint32_t t;
9866         uint32_t n;
9867         uint32_t imm32;
9868         bool index;
9869         bool add;
9870         bool wback;
9871 
9872         switch (encoding)
9873         {
9874             case eEncodingA1:
9875                 // if P == �0� && W == �1� then SEE STRBT;
9876                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9877                 t = Bits32 (opcode, 15, 12);
9878                 n = Bits32 (opcode, 19, 16);
9879                 imm32 = Bits32 (opcode, 11, 0);
9880 
9881                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9882                 index = BitIsSet (opcode, 24);
9883                 add = BitIsSet (opcode, 23);
9884                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9885 
9886                 // if t == 15 then UNPREDICTABLE;
9887                 if (t == 15)
9888                     return false;
9889 
9890                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9891                 if (wback && ((n == 15) || (n == t)))
9892                     return false;
9893 
9894                 break;
9895 
9896             default:
9897                 return false;
9898         }
9899 
9900         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9901         uint32_t Rn = ReadCoreReg (n, &success);
9902         if (!success)
9903             return false;
9904 
9905         addr_t offset_addr;
9906         if (add)
9907             offset_addr = Rn + imm32;
9908         else
9909             offset_addr = Rn - imm32;
9910 
9911         // address = if index then offset_addr else R[n];
9912         addr_t address;
9913         if (index)
9914             address = offset_addr;
9915         else
9916             address = Rn;
9917 
9918         // MemU[address,1] = R[t]<7:0>;
9919         uint32_t Rt = ReadCoreReg (t, &success);
9920         if (!success)
9921             return false;
9922 
9923         RegisterInfo base_reg;
9924         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9925         RegisterInfo data_reg;
9926         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9927         EmulateInstruction::Context context;
9928         context.type = eContextRegisterStore;
9929         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
9930 
9931         if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1))
9932             return false;
9933 
9934         // if wback then R[n] = offset_addr;
9935         if (wback)
9936         {
9937             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
9938                 return false;
9939         }
9940     }
9941     return true;
9942 }
9943 
9944 // A8.6.194 STR (immediate, ARM)
9945 bool
9946 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding)
9947 {
9948 #if 0
9949     if ConditionPassed() then
9950         EncodingSpecificOperations();
9951         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9952         address = if index then offset_addr else R[n];
9953         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
9954         if wback then R[n] = offset_addr;
9955 #endif
9956 
9957     bool success = false;
9958 
9959     if (ConditionPassed(opcode))
9960     {
9961         uint32_t t;
9962         uint32_t n;
9963         uint32_t imm32;
9964         bool index;
9965         bool add;
9966         bool wback;
9967 
9968         const uint32_t addr_byte_size = GetAddressByteSize();
9969 
9970         switch (encoding)
9971         {
9972             case eEncodingA1:
9973                 // if P == �0� && W == �1� then SEE STRT;
9974                 // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH;
9975                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9976                 t = Bits32 (opcode, 15, 12);
9977                 n = Bits32 (opcode, 19, 16);
9978                 imm32 = Bits32 (opcode, 11, 0);
9979 
9980                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9981                 index = BitIsSet (opcode, 24);
9982                 add = BitIsSet (opcode, 23);
9983                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9984 
9985                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9986                 if (wback && ((n == 15) || (n == t)))
9987                     return false;
9988 
9989                 break;
9990 
9991             default:
9992                 return false;
9993         }
9994 
9995         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9996         uint32_t Rn = ReadCoreReg (n, &success);
9997         if (!success)
9998             return false;
9999 
10000         addr_t offset_addr;
10001         if (add)
10002             offset_addr = Rn + imm32;
10003         else
10004             offset_addr = Rn - imm32;
10005 
10006         // address = if index then offset_addr else R[n];
10007         addr_t address;
10008         if (index)
10009             address = offset_addr;
10010         else
10011             address = Rn;
10012 
10013         RegisterInfo base_reg;
10014         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10015         RegisterInfo data_reg;
10016         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10017         EmulateInstruction::Context context;
10018         context.type = eContextRegisterStore;
10019         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10020 
10021         // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10022         uint32_t Rt = ReadCoreReg (t, &success);
10023         if (!success)
10024             return false;
10025 
10026         if (t == 15)
10027         {
10028             uint32_t pc_value = ReadCoreReg (PC_REG, &success);
10029             if (!success)
10030                 return false;
10031 
10032             if (!MemUWrite (context, address, pc_value, addr_byte_size))
10033                 return false;
10034         }
10035         else
10036         {
10037             if (!MemUWrite (context, address, Rt, addr_byte_size))
10038                   return false;
10039         }
10040 
10041         // if wback then R[n] = offset_addr;
10042         if (wback)
10043         {
10044             context.type = eContextAdjustBaseRegister;
10045             context.SetImmediate (offset_addr);
10046 
10047             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10048                 return false;
10049         }
10050     }
10051     return true;
10052 }
10053 
10054 // A8.6.66 LDRD (immediate)
10055 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two
10056 // words from memory, and writes them to two registers.  It can use offset, post-indexed, or pre-indexed addressing.
10057 bool
10058 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding)
10059 {
10060 #if 0
10061     if ConditionPassed() then
10062         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10063         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10064         address = if index then offset_addr else R[n];
10065         R[t] = MemA[address,4];
10066         R[t2] = MemA[address+4,4];
10067         if wback then R[n] = offset_addr;
10068 #endif
10069 
10070     bool success = false;
10071 
10072     if (ConditionPassed(opcode))
10073     {
10074         uint32_t t;
10075         uint32_t t2;
10076         uint32_t n;
10077         uint32_t imm32;
10078         bool index;
10079         bool add;
10080         bool wback;
10081 
10082         switch (encoding)
10083         {
10084             case eEncodingT1:
10085                 //if P == �0� && W == �0� then SEE �Related encodings�;
10086                 //if Rn == �1111� then SEE LDRD (literal);
10087                 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10088                 t = Bits32 (opcode, 15, 12);
10089                 t2 = Bits32 (opcode, 11, 8);
10090                 n = Bits32 (opcode, 19, 16);
10091                 imm32 = Bits32 (opcode, 7, 0) << 2;
10092 
10093                 //index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10094                 index = BitIsSet (opcode, 24);
10095                 add = BitIsSet (opcode, 23);
10096                 wback = BitIsSet (opcode, 21);
10097 
10098                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10099                 if (wback && ((n == t) || (n == t2)))
10100                     return false;
10101 
10102                 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10103                 if (BadReg (t) || BadReg (t2) || (t == t2))
10104                     return false;
10105 
10106                 break;
10107 
10108             case eEncodingA1:
10109                 //if Rn == �1111� then SEE LDRD (literal);
10110                 //if Rt<0> == �1� then UNPREDICTABLE;
10111                 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10112                 t = Bits32 (opcode, 15, 12);
10113                 if (BitIsSet (t, 0))
10114                     return false;
10115                 t2 = t + 1;
10116                 n = Bits32 (opcode, 19, 16);
10117                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10118 
10119                 //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10120                 index = BitIsSet (opcode, 24);
10121                 add = BitIsSet (opcode, 23);
10122                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10123 
10124                 //if P == �0� && W == �1� then UNPREDICTABLE;
10125                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10126                     return false;
10127 
10128                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10129                 if (wback && ((n == t) || (n == t2)))
10130                     return false;
10131 
10132                 //if t2 == 15 then UNPREDICTABLE;
10133                 if (t2 == 15)
10134                     return false;
10135 
10136                 break;
10137 
10138             default:
10139                 return false;
10140         }
10141 
10142         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10143         uint32_t Rn = ReadCoreReg (n, &success);
10144         if (!success)
10145             return false;
10146 
10147         addr_t offset_addr;
10148         if (add)
10149                   offset_addr = Rn + imm32;
10150         else
10151             offset_addr = Rn - imm32;
10152 
10153         //address = if index then offset_addr else R[n];
10154         addr_t address;
10155         if (index)
10156             address = offset_addr;
10157         else
10158             address = Rn;
10159 
10160         //R[t] = MemA[address,4];
10161         RegisterInfo base_reg;
10162         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10163 
10164         EmulateInstruction::Context context;
10165         context.type = eContextRegisterLoad;
10166         context.SetRegisterPlusOffset (base_reg, address - Rn);
10167 
10168         const uint32_t addr_byte_size = GetAddressByteSize();
10169         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10170         if (!success)
10171             return false;
10172 
10173         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10174             return false;
10175 
10176         //R[t2] = MemA[address+4,4];
10177 
10178         context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10179         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10180         if (!success)
10181             return false;
10182 
10183         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10184             return false;
10185 
10186         //if wback then R[n] = offset_addr;
10187         if (wback)
10188         {
10189             context.type = eContextAdjustBaseRegister;
10190             context.SetAddress (offset_addr);
10191 
10192             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10193                 return false;
10194         }
10195     }
10196     return true;
10197 }
10198 
10199 // A8.6.68 LDRD (register)
10200 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two
10201 // words from memory, and writes them to two registers.  It can use offset, post-indexed or pre-indexed addressing.
10202 bool
10203 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding)
10204 {
10205 #if 0
10206     if ConditionPassed() then
10207         EncodingSpecificOperations();
10208         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10209         address = if index then offset_addr else R[n];
10210         R[t] = MemA[address,4];
10211         R[t2] = MemA[address+4,4];
10212         if wback then R[n] = offset_addr;
10213 #endif
10214 
10215     bool success = false;
10216 
10217     if (ConditionPassed(opcode))
10218     {
10219         uint32_t t;
10220         uint32_t t2;
10221         uint32_t n;
10222         uint32_t m;
10223         bool index;
10224         bool add;
10225         bool wback;
10226 
10227         switch (encoding)
10228         {
10229             case eEncodingA1:
10230                 // if Rt<0> == �1� then UNPREDICTABLE;
10231                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10232                 t = Bits32 (opcode, 15, 12);
10233                 if (BitIsSet (t, 0))
10234                     return false;
10235                 t2 = t + 1;
10236                 n = Bits32 (opcode, 19, 16);
10237                 m = Bits32 (opcode, 3, 0);
10238 
10239                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10240                 index = BitIsSet (opcode, 24);
10241                 add = BitIsSet (opcode, 23);
10242                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10243 
10244                 // if P == �0� && W == �1� then UNPREDICTABLE;
10245                   if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10246                   return false;
10247 
10248                 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10249                   if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10250                   return false;
10251 
10252                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10253                   if (wback && ((n == 15) || (n == t) || (n == t2)))
10254                   return false;
10255 
10256                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10257                 if ((ArchVersion() < 6) && wback && (m == n))
10258                   return false;
10259                 break;
10260 
10261             default:
10262                 return false;
10263         }
10264 
10265         uint32_t Rn = ReadCoreReg (n, &success);
10266         if (!success)
10267             return false;
10268         RegisterInfo base_reg;
10269         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10270 
10271         uint32_t Rm = ReadCoreReg (m, &success);
10272         if (!success)
10273             return false;
10274         RegisterInfo offset_reg;
10275         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10276 
10277         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10278         addr_t offset_addr;
10279         if (add)
10280             offset_addr = Rn + Rm;
10281         else
10282             offset_addr = Rn - Rm;
10283 
10284         // address = if index then offset_addr else R[n];
10285         addr_t address;
10286         if (index)
10287             address = offset_addr;
10288         else
10289             address = Rn;
10290 
10291         EmulateInstruction::Context context;
10292         context.type = eContextRegisterLoad;
10293         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
10294 
10295         // R[t] = MemA[address,4];
10296         const uint32_t addr_byte_size = GetAddressByteSize();
10297         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10298         if (!success)
10299             return false;
10300 
10301         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10302             return false;
10303 
10304         // R[t2] = MemA[address+4,4];
10305 
10306         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10307         if (!success)
10308             return false;
10309 
10310         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10311             return false;
10312 
10313         // if wback then R[n] = offset_addr;
10314         if (wback)
10315         {
10316             context.type = eContextAdjustBaseRegister;
10317             context.SetAddress (offset_addr);
10318 
10319             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10320                 return false;
10321         }
10322     }
10323     return true;
10324 }
10325 
10326 // A8.6.200 STRD (immediate)
10327 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and
10328 // stores two words from two registers to memory.  It can use offset, post-indexed, or pre-indexed addressing.
10329 bool
10330 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding)
10331 {
10332 #if 0
10333     if ConditionPassed() then
10334         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10335         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10336         address = if index then offset_addr else R[n];
10337         MemA[address,4] = R[t];
10338         MemA[address+4,4] = R[t2];
10339         if wback then R[n] = offset_addr;
10340 #endif
10341 
10342     bool success = false;
10343 
10344     if (ConditionPassed(opcode))
10345     {
10346         uint32_t t;
10347         uint32_t t2;
10348         uint32_t n;
10349         uint32_t imm32;
10350         bool index;
10351         bool add;
10352         bool wback;
10353 
10354         switch (encoding)
10355         {
10356             case eEncodingT1:
10357                 // if P == �0� && W == �0� then SEE �Related encodings�;
10358                 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10359                 t = Bits32 (opcode, 15, 12);
10360                 t2 = Bits32 (opcode, 11, 8);
10361                 n = Bits32 (opcode, 19, 16);
10362                 imm32 = Bits32 (opcode, 7, 0) << 2;
10363 
10364                 // index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10365                 index = BitIsSet (opcode, 24);
10366                 add = BitIsSet (opcode, 23);
10367                 wback = BitIsSet (opcode, 21);
10368 
10369                 // if wback && (n == t || n == t2) then UNPREDICTABLE;
10370                 if (wback && ((n == t) || (n == t2)))
10371                     return false;
10372 
10373                 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10374                 if ((n == 15) || BadReg (t) || BadReg (t2))
10375                     return false;
10376 
10377                 break;
10378 
10379             case eEncodingA1:
10380                 // if Rt<0> == �1� then UNPREDICTABLE;
10381                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10382                 t = Bits32 (opcode, 15, 12);
10383                 if (BitIsSet (t, 0))
10384                     return false;
10385 
10386                 t2 = t + 1;
10387                 n = Bits32 (opcode, 19, 16);
10388                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10389 
10390                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10391                 index = BitIsSet (opcode, 24);
10392                 add = BitIsSet (opcode, 23);
10393                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10394 
10395                 // if P == �0� && W == �1� then UNPREDICTABLE;
10396                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10397                     return false;
10398 
10399                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10400                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10401                     return false;
10402 
10403                 // if t2 == 15 then UNPREDICTABLE;
10404                 if (t2 == 15)
10405                     return false;
10406 
10407                 break;
10408 
10409             default:
10410                 return false;
10411         }
10412 
10413         RegisterInfo base_reg;
10414         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10415 
10416         uint32_t Rn = ReadCoreReg (n, &success);
10417         if (!success)
10418             return false;
10419 
10420         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10421         addr_t offset_addr;
10422         if (add)
10423             offset_addr = Rn + imm32;
10424         else
10425             offset_addr = Rn - imm32;
10426 
10427         //address = if index then offset_addr else R[n];
10428         addr_t address;
10429         if (index)
10430             address = offset_addr;
10431         else
10432             address = Rn;
10433 
10434         //MemA[address,4] = R[t];
10435         RegisterInfo data_reg;
10436         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10437 
10438         uint32_t data = ReadCoreReg (t, &success);
10439         if (!success)
10440             return false;
10441 
10442         EmulateInstruction::Context context;
10443         context.type = eContextRegisterStore;
10444         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10445 
10446         const uint32_t addr_byte_size = GetAddressByteSize();
10447 
10448         if (!MemAWrite (context, address, data, addr_byte_size))
10449             return false;
10450 
10451         //MemA[address+4,4] = R[t2];
10452         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10453         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10454 
10455         data = ReadCoreReg (t2, &success);
10456         if (!success)
10457             return false;
10458 
10459         if (!MemAWrite (context, address + 4, data, addr_byte_size))
10460             return false;
10461 
10462         //if wback then R[n] = offset_addr;
10463         if (wback)
10464         {
10465             context.type = eContextAdjustBaseRegister;
10466             context.SetAddress (offset_addr);
10467 
10468             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10469                 return false;
10470         }
10471     }
10472     return true;
10473 }
10474 
10475 
10476 // A8.6.201 STRD (register)
10477 bool
10478 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding)
10479 {
10480 #if 0
10481     if ConditionPassed() then
10482         EncodingSpecificOperations();
10483         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10484         address = if index then offset_addr else R[n];
10485         MemA[address,4] = R[t];
10486         MemA[address+4,4] = R[t2];
10487         if wback then R[n] = offset_addr;
10488 #endif
10489 
10490     bool success = false;
10491 
10492     if (ConditionPassed(opcode))
10493     {
10494         uint32_t t;
10495         uint32_t t2;
10496         uint32_t n;
10497         uint32_t m;
10498         bool index;
10499         bool add;
10500         bool wback;
10501 
10502         switch (encoding)
10503         {
10504             case eEncodingA1:
10505                 // if Rt<0> == �1� then UNPREDICTABLE;
10506                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10507                 t = Bits32 (opcode, 15, 12);
10508                 if (BitIsSet (t, 0))
10509                    return false;
10510 
10511                 t2 = t+1;
10512                 n = Bits32 (opcode, 19, 16);
10513                 m = Bits32 (opcode, 3, 0);
10514 
10515                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10516                 index = BitIsSet (opcode, 24);
10517                 add = BitIsSet (opcode, 23);
10518                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10519 
10520                 // if P == �0� && W == �1� then UNPREDICTABLE;
10521                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10522                    return false;
10523 
10524                 // if t2 == 15 || m == 15 then UNPREDICTABLE;
10525                 if ((t2 == 15) || (m == 15))
10526                    return false;
10527 
10528                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10529                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10530                    return false;
10531 
10532                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10533                 if ((ArchVersion() < 6) && wback && (m == n))
10534                    return false;
10535 
10536                 break;
10537 
10538             default:
10539                 return false;
10540         }
10541 
10542         RegisterInfo base_reg;
10543         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10544         RegisterInfo offset_reg;
10545         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10546         RegisterInfo data_reg;
10547 
10548         uint32_t Rn = ReadCoreReg (n, &success);
10549         if (!success)
10550             return false;
10551 
10552         uint32_t Rm = ReadCoreReg (m, &success);
10553         if (!success)
10554             return false;
10555 
10556         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10557         addr_t offset_addr;
10558         if (add)
10559             offset_addr = Rn + Rm;
10560         else
10561             offset_addr = Rn - Rm;
10562 
10563         // address = if index then offset_addr else R[n];
10564         addr_t address;
10565         if (index)
10566             address = offset_addr;
10567         else
10568             address = Rn;
10569                           // MemA[address,4] = R[t];
10570         uint32_t Rt = ReadCoreReg (t, &success);
10571         if (!success)
10572             return false;
10573 
10574         EmulateInstruction::Context context;
10575         context.type = eContextRegisterStore;
10576         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10577         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10578 
10579         const uint32_t addr_byte_size = GetAddressByteSize();
10580 
10581         if (!MemAWrite (context, address, Rt, addr_byte_size))
10582             return false;
10583 
10584         // MemA[address+4,4] = R[t2];
10585         uint32_t Rt2 = ReadCoreReg (t2, &success);
10586         if (!success)
10587             return false;
10588 
10589         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10590 
10591         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10592 
10593         if (!MemAWrite (context, address + 4, Rt2, addr_byte_size))
10594             return false;
10595 
10596         // if wback then R[n] = offset_addr;
10597         if (wback)
10598         {
10599             context.type = eContextAdjustBaseRegister;
10600             context.SetAddress (offset_addr);
10601 
10602             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10603                 return false;
10604 
10605         }
10606     }
10607     return true;
10608 }
10609 
10610 // A8.6.319 VLDM
10611 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from
10612 // an ARM core register.
10613 bool
10614 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding)
10615 {
10616 #if 0
10617     if ConditionPassed() then
10618         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10619         address = if add then R[n] else R[n]-imm32;
10620         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10621         for r = 0 to regs-1
10622             if single_regs then
10623                 S[d+r] = MemA[address,4]; address = address+4;
10624             else
10625                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10626                 // Combine the word-aligned words in the correct order for current endianness.
10627                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10628 #endif
10629 
10630     bool success = false;
10631 
10632     if (ConditionPassed(opcode))
10633     {
10634         bool single_regs;
10635         bool add;
10636         bool wback;
10637         uint32_t d;
10638         uint32_t n;
10639         uint32_t imm32;
10640         uint32_t regs;
10641 
10642         switch (encoding)
10643         {
10644             case eEncodingT1:
10645             case eEncodingA1:
10646                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10647                 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10648                 // if P == �1� && W == �0� then SEE VLDR;
10649                 // if P == U && W == �1� then UNDEFINED;
10650                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10651                     return false;
10652 
10653                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10654                 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10655                 single_regs = false;
10656                 add = BitIsSet (opcode, 23);
10657                 wback = BitIsSet (opcode, 21);
10658 
10659                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10660                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10661                 n = Bits32 (opcode, 19, 16);
10662                 imm32 = Bits32 (opcode, 7, 0) << 2;
10663 
10664                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�.
10665                 regs = Bits32 (opcode, 7, 0) / 2;
10666 
10667                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10668                 if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
10669                     return false;
10670 
10671                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10672                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10673                     return false;
10674 
10675                 break;
10676 
10677             case eEncodingT2:
10678             case eEncodingA2:
10679                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10680                 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10681                 // if P == �1� && W == �0� then SEE VLDR;
10682                 // if P == U && W == �1� then UNDEFINED;
10683                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10684                     return false;
10685 
10686                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10687                 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10688                 single_regs = true;
10689                 add = BitIsSet (opcode, 23);
10690                 wback = BitIsSet (opcode, 21);
10691                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10692                 n = Bits32 (opcode, 19, 16);
10693 
10694                 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10695                 imm32 = Bits32 (opcode, 7, 0) << 2;
10696                 regs = Bits32 (opcode, 7, 0);
10697 
10698                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10699                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10700                     return false;
10701 
10702                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10703                 if ((regs == 0) || ((d + regs) > 32))
10704                     return false;
10705                 break;
10706 
10707             default:
10708                 return false;
10709         }
10710 
10711         RegisterInfo base_reg;
10712         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10713 
10714         uint32_t Rn = ReadCoreReg (n, &success);
10715         if (!success)
10716             return false;
10717 
10718         // address = if add then R[n] else R[n]-imm32;
10719         addr_t address;
10720         if (add)
10721             address = Rn;
10722         else
10723             address = Rn - imm32;
10724 
10725         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10726         EmulateInstruction::Context context;
10727 
10728         if (wback)
10729         {
10730             uint32_t value;
10731             if (add)
10732                 value = Rn + imm32;
10733             else
10734                 value = Rn - imm32;
10735 
10736             context.type = eContextAdjustBaseRegister;
10737             context.SetImmediateSigned (value - Rn);
10738             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10739                 return false;
10740 
10741         }
10742 
10743         const uint32_t addr_byte_size = GetAddressByteSize();
10744         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10745 
10746         context.type = eContextRegisterLoad;
10747 
10748         // for r = 0 to regs-1
10749         for (uint32_t r = 0; r < regs; ++r)
10750         {
10751             if (single_regs)
10752             {
10753                 // S[d+r] = MemA[address,4]; address = address+4;
10754                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10755 
10756                 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10757                 if (!success)
10758                     return false;
10759 
10760                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10761                     return false;
10762 
10763                 address = address + 4;
10764             }
10765             else
10766             {
10767                 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10768                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10769                 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10770                 if (!success)
10771                     return false;
10772 
10773                 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10774                 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10775                 if (!success)
10776                     return false;
10777 
10778                 address = address + 8;
10779                 // // Combine the word-aligned words in the correct order for current endianness.
10780                 // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10781                 uint64_t data;
10782                 if (GetByteOrder() == eByteOrderBig)
10783                 {
10784                     data = word1;
10785                     data = (data << 32) | word2;
10786                 }
10787                 else
10788                 {
10789                     data = word2;
10790                     data = (data << 32) | word1;
10791                 }
10792 
10793                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10794                     return false;
10795             }
10796         }
10797     }
10798     return true;
10799 }
10800 
10801 // A8.6.399 VSTM
10802 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an
10803 // ARM core register.
10804 bool
10805 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding)
10806 {
10807 #if 0
10808     if ConditionPassed() then
10809         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10810         address = if add then R[n] else R[n]-imm32;
10811         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10812         for r = 0 to regs-1
10813             if single_regs then
10814                 MemA[address,4] = S[d+r]; address = address+4;
10815             else
10816                 // Store as two word-aligned words in the correct order for current endianness.
10817                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10818                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10819                 address = address+8;
10820 #endif
10821 
10822     bool success = false;
10823 
10824     if (ConditionPassed (opcode))
10825     {
10826         bool single_regs;
10827         bool add;
10828         bool wback;
10829         uint32_t d;
10830         uint32_t n;
10831         uint32_t imm32;
10832         uint32_t regs;
10833 
10834         switch (encoding)
10835         {
10836             case eEncodingT1:
10837             case eEncodingA1:
10838                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10839                 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10840                 // if P == �1� && W == �0� then SEE VSTR;
10841                 // if P == U && W == �1� then UNDEFINED;
10842                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10843                     return false;
10844 
10845                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10846                 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10847                 single_regs = false;
10848                 add = BitIsSet (opcode, 23);
10849                 wback = BitIsSet (opcode, 21);
10850 
10851                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10852                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10853                 n = Bits32 (opcode, 19, 16);
10854                 imm32 = Bits32 (opcode, 7, 0) << 2;
10855 
10856                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�.
10857                 regs = Bits32 (opcode, 7, 0) / 2;
10858 
10859                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10860                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10861                     return false;
10862 
10863                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10864                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10865                     return false;
10866 
10867                 break;
10868 
10869             case eEncodingT2:
10870             case eEncodingA2:
10871                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10872                 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10873                 // if P == �1� && W == �0� then SEE VSTR;
10874                 // if P == U && W == �1� then UNDEFINED;
10875                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10876                     return false;
10877 
10878                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10879                 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10880                 single_regs = true;
10881                 add = BitIsSet (opcode, 23);
10882                 wback = BitIsSet (opcode, 21);
10883                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10884                 n = Bits32 (opcode, 19, 16);
10885 
10886                 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10887                 imm32 = Bits32 (opcode, 7, 0) << 2;
10888                 regs = Bits32 (opcode, 7, 0);
10889 
10890                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10891                 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM)))
10892                     return false;
10893 
10894                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10895                 if ((regs == 0) || ((d + regs) > 32))
10896                     return false;
10897 
10898                 break;
10899 
10900             default:
10901                 return false;
10902         }
10903 
10904         RegisterInfo base_reg;
10905         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10906 
10907         uint32_t Rn = ReadCoreReg (n, &success);
10908         if (!success)
10909             return false;
10910 
10911         // address = if add then R[n] else R[n]-imm32;
10912         addr_t address;
10913         if (add)
10914             address = Rn;
10915         else
10916             address = Rn - imm32;
10917 
10918         EmulateInstruction::Context context;
10919         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10920         if (wback)
10921         {
10922             uint32_t value;
10923             if (add)
10924                 value = Rn + imm32;
10925             else
10926                 value = Rn - imm32;
10927 
10928             context.type = eContextAdjustBaseRegister;
10929             context.SetRegisterPlusOffset (base_reg, value - Rn);
10930 
10931             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10932                 return false;
10933         }
10934 
10935         const uint32_t addr_byte_size = GetAddressByteSize();
10936         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10937 
10938         context.type = eContextRegisterStore;
10939         // for r = 0 to regs-1
10940         for (int r = 0; r < regs; ++r)
10941         {
10942 
10943             if (single_regs)
10944             {
10945                 // MemA[address,4] = S[d+r]; address = address+4;
10946                 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10947                 if (!success)
10948                     return false;
10949 
10950                 RegisterInfo data_reg;
10951                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
10952                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10953                 if (!MemAWrite (context, address, data, addr_byte_size))
10954                     return false;
10955 
10956                 address = address + 4;
10957             }
10958             else
10959             {
10960                 // // Store as two word-aligned words in the correct order for current endianness.
10961                 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10962                 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10963                 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10964                 if (!success)
10965                     return false;
10966 
10967                 RegisterInfo data_reg;
10968                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
10969 
10970                 if (GetByteOrder() == eByteOrderBig)
10971                 {
10972                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10973                     if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
10974                         return false;
10975 
10976                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10977                     if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size))
10978                         return false;
10979                 }
10980                 else
10981                 {
10982                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10983                     if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
10984                         return false;
10985 
10986                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10987                     if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
10988                         return false;
10989                 }
10990                 // address = address+8;
10991                 address = address + 8;
10992             }
10993         }
10994     }
10995     return true;
10996 }
10997 
10998 // A8.6.320
10999 // This instruciton loads a single extension register fronm memory, using an address from an ARM core register, with
11000 // an optional offset.
11001 bool
11002 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
11003 {
11004 #if 0
11005     if ConditionPassed() then
11006         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11007         base = if n == 15 then Align(PC,4) else R[n];
11008         address = if add then (base + imm32) else (base - imm32);
11009         if single_reg then
11010             S[d] = MemA[address,4];
11011         else
11012             word1 = MemA[address,4]; word2 = MemA[address+4,4];
11013             // Combine the word-aligned words in the correct order for current endianness.
11014             D[d] = if BigEndian() then word1:word2 else word2:word1;
11015 #endif
11016 
11017     bool success = false;
11018 
11019     if (ConditionPassed (opcode))
11020     {
11021         bool single_reg;
11022         bool add;
11023         uint32_t imm32;
11024         uint32_t d;
11025         uint32_t n;
11026 
11027         switch (encoding)
11028         {
11029             case eEncodingT1:
11030             case eEncodingA1:
11031                 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11032                 single_reg = false;
11033                 add = BitIsSet (opcode, 23);
11034                 imm32 = Bits32 (opcode, 7, 0) << 2;
11035 
11036                 // d = UInt(D:Vd); n = UInt(Rn);
11037                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11038                 n = Bits32 (opcode, 19, 16);
11039 
11040                 break;
11041 
11042             case eEncodingT2:
11043             case eEncodingA2:
11044                 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11045                 single_reg = true;
11046                 add = BitIsSet (opcode, 23);
11047                 imm32 = Bits32 (opcode, 7, 0) << 2;
11048 
11049                 // d = UInt(Vd:D); n = UInt(Rn);
11050                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11051                 n = Bits32 (opcode, 19, 16);
11052 
11053                 break;
11054 
11055             default:
11056                 return false;
11057         }
11058         RegisterInfo base_reg;
11059         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11060 
11061         uint32_t Rn = ReadCoreReg (n, &success);
11062         if (!success)
11063             return false;
11064 
11065         // base = if n == 15 then Align(PC,4) else R[n];
11066         uint32_t base;
11067         if (n == 15)
11068             base = AlignPC (Rn);
11069         else
11070             base = Rn;
11071 
11072         // address = if add then (base + imm32) else (base - imm32);
11073         addr_t address;
11074         if (add)
11075             address = base + imm32;
11076         else
11077             address = base - imm32;
11078 
11079         const uint32_t addr_byte_size = GetAddressByteSize();
11080         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11081 
11082         EmulateInstruction::Context context;
11083         context.type = eContextRegisterLoad;
11084         context.SetRegisterPlusOffset (base_reg, address - base);
11085 
11086         if (single_reg)
11087         {
11088             // S[d] = MemA[address,4];
11089             uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
11090             if (!success)
11091                 return false;
11092 
11093             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data))
11094                 return false;
11095         }
11096         else
11097         {
11098             // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11099             uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
11100             if (!success)
11101                 return false;
11102 
11103             context.SetRegisterPlusOffset (base_reg, (address + 4) - base);
11104             uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
11105             if (!success)
11106                 return false;
11107             // // Combine the word-aligned words in the correct order for current endianness.
11108             // D[d] = if BigEndian() then word1:word2 else word2:word1;
11109             uint64_t data64;
11110             if (GetByteOrder() == eByteOrderBig)
11111             {
11112                 data64 = word1;
11113                 data64 = (data64 << 32) | word2;
11114             }
11115             else
11116             {
11117                 data64 = word2;
11118                 data64 = (data64 << 32) | word1;
11119             }
11120 
11121             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64))
11122                 return false;
11123         }
11124     }
11125     return true;
11126 }
11127 
11128 // A8.6.400 VSTR
11129 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an
11130 // optional offset.
11131 bool
11132 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
11133 {
11134 #if 0
11135     if ConditionPassed() then
11136         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11137         address = if add then (R[n] + imm32) else (R[n] - imm32);
11138         if single_reg then
11139             MemA[address,4] = S[d];
11140         else
11141             // Store as two word-aligned words in the correct order for current endianness.
11142             MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11143             MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11144 #endif
11145 
11146     bool success = false;
11147 
11148     if (ConditionPassed (opcode))
11149     {
11150         bool single_reg;
11151         bool add;
11152         uint32_t imm32;
11153         uint32_t d;
11154         uint32_t n;
11155 
11156         switch (encoding)
11157         {
11158             case eEncodingT1:
11159             case eEncodingA1:
11160                 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11161                 single_reg = false;
11162                 add = BitIsSet (opcode, 23);
11163                 imm32 = Bits32 (opcode, 7, 0) << 2;
11164 
11165                 // d = UInt(D:Vd); n = UInt(Rn);
11166                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11167                 n = Bits32 (opcode, 19, 16);
11168 
11169                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11170                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11171                     return false;
11172 
11173                 break;
11174 
11175             case eEncodingT2:
11176             case eEncodingA2:
11177                 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11178                 single_reg = true;
11179                 add = BitIsSet (opcode, 23);
11180                 imm32 = Bits32 (opcode, 7, 0) << 2;
11181 
11182                 // d = UInt(Vd:D); n = UInt(Rn);
11183                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11184                 n = Bits32 (opcode, 19, 16);
11185 
11186                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11187                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11188                     return false;
11189 
11190                 break;
11191 
11192             default:
11193                 return false;
11194         }
11195 
11196         RegisterInfo base_reg;
11197         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11198 
11199         uint32_t Rn = ReadCoreReg (n, &success);
11200         if (!success)
11201             return false;
11202 
11203         // address = if add then (R[n] + imm32) else (R[n] - imm32);
11204         addr_t address;
11205         if (add)
11206             address = Rn + imm32;
11207         else
11208             address = Rn - imm32;
11209 
11210         const uint32_t addr_byte_size = GetAddressByteSize();
11211         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11212 
11213         RegisterInfo data_reg;
11214         GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg);
11215         EmulateInstruction::Context context;
11216         context.type = eContextRegisterStore;
11217         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11218 
11219         if (single_reg)
11220         {
11221             // MemA[address,4] = S[d];
11222             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11223             if (!success)
11224                 return false;
11225 
11226             if (!MemAWrite (context, address, data, addr_byte_size))
11227                 return false;
11228         }
11229         else
11230         {
11231             // // Store as two word-aligned words in the correct order for current endianness.
11232             // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11233             // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11234             uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11235             if (!success)
11236                 return false;
11237 
11238             if (GetByteOrder() == eByteOrderBig)
11239             {
11240                 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11241                     return false;
11242 
11243                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11244                 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size))
11245                     return false;
11246             }
11247             else
11248             {
11249                 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11250                     return false;
11251 
11252                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11253                 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11254                     return false;
11255             }
11256         }
11257     }
11258     return true;
11259 }
11260 
11261 // A8.6.307 VLDI1 (multiple single elements)
11262 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving.  Every
11263 // element of each register is loaded.
11264 bool
11265 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding)
11266 {
11267 #if 0
11268     if ConditionPassed() then
11269         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11270         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11271         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11272         for r = 0 to regs-1
11273             for e = 0 to elements-1
11274                 Elem[D[d+r],e,esize] = MemU[address,ebytes];
11275                 address = address + ebytes;
11276 #endif
11277 
11278     bool success = false;
11279 
11280     if (ConditionPassed (opcode))
11281     {
11282         uint32_t regs;
11283         uint32_t alignment;
11284         uint32_t ebytes;
11285         uint32_t esize;
11286         uint32_t elements;
11287         uint32_t d;
11288         uint32_t n;
11289         uint32_t m;
11290         bool wback;
11291         bool register_index;
11292 
11293         switch (encoding)
11294         {
11295             case eEncodingT1:
11296             case eEncodingA1:
11297             {
11298                 // case type of
11299                     // when �0111�
11300                         // regs = 1; if align<1> == �1� then UNDEFINED;
11301                     // when �1010�
11302                         // regs = 2; if align == �11� then UNDEFINED;
11303                     // when �0110�
11304                         // regs = 3; if align<1> == �1� then UNDEFINED;
11305                     // when �0010�
11306                         // regs = 4;
11307                     // otherwise
11308                         // SEE �Related encodings�;
11309                 uint32_t type = Bits32 (opcode, 11, 8);
11310                 uint32_t align = Bits32 (opcode, 5, 4);
11311                 if (type == 7) // '0111'
11312                 {
11313                     regs = 1;
11314                     if (BitIsSet (align, 1))
11315                         return false;
11316                 }
11317                 else if (type == 10) // '1010'
11318                 {
11319                     regs = 2;
11320                     if (align == 3)
11321                         return false;
11322 
11323                 }
11324                 else if (type == 6) // '0110'
11325                 {
11326                     regs = 3;
11327                     if (BitIsSet (align, 1))
11328                         return false;
11329                 }
11330                 else if (type == 2) // '0010'
11331                 {
11332                     regs = 4;
11333                 }
11334                 else
11335                     return false;
11336 
11337                 // alignment = if align == �00� then 1 else 4 << UInt(align);
11338                 if (align == 0)
11339                     alignment = 1;
11340                 else
11341                     alignment = 4 << align;
11342 
11343                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11344                 ebytes = 1 << Bits32 (opcode, 7, 6);
11345                 esize = 8 * ebytes;
11346                 elements = 8 / ebytes;
11347 
11348                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11349                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11350                 n = Bits32 (opcode, 19, 15);
11351                 m = Bits32 (opcode, 3, 0);
11352 
11353                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11354                 wback = (m != 15);
11355                 register_index = ((m != 15) && (m != 13));
11356 
11357                 // if d+regs > 32 then UNPREDICTABLE;
11358                 if ((d + regs) > 32)
11359                     return false;
11360             }
11361                 break;
11362 
11363             default:
11364                 return false;
11365         }
11366 
11367         RegisterInfo base_reg;
11368         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11369 
11370         uint32_t Rn = ReadCoreReg (n, &success);
11371         if (!success)
11372             return false;
11373 
11374         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11375         addr_t address = Rn;
11376         if ((address % alignment) != 0)
11377             return false;
11378 
11379         EmulateInstruction::Context context;
11380         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11381         if (wback)
11382         {
11383             uint32_t Rm = ReadCoreReg (m, &success);
11384             if (!success)
11385                 return false;
11386 
11387             uint32_t offset;
11388             if (register_index)
11389                 offset = Rm;
11390             else
11391                 offset = 8 * regs;
11392 
11393             uint32_t value = Rn + offset;
11394             context.type = eContextAdjustBaseRegister;
11395             context.SetRegisterPlusOffset (base_reg, offset);
11396 
11397             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11398                 return false;
11399 
11400         }
11401 
11402         // for r = 0 to regs-1
11403         for (int r = 0; r < regs; ++r)
11404         {
11405             // for e = 0 to elements-1
11406             uint64_t assembled_data = 0;
11407             for (int e = 0; e < elements; ++e)
11408             {
11409                 // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11410                 context.type = eContextRegisterLoad;
11411                 context.SetRegisterPlusOffset (base_reg, address - Rn);
11412                 uint64_t data = MemURead (context, address, ebytes, 0, &success);
11413                 if (!success)
11414                     return false;
11415 
11416                 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data
11417 
11418                 // address = address + ebytes;
11419                 address = address + ebytes;
11420             }
11421             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data))
11422                 return false;
11423         }
11424     }
11425     return true;
11426 }
11427 
11428 // A8.6.308 VLD1 (single element to one lane)
11429 //
11430 bool
11431 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding)
11432 {
11433 #if 0
11434     if ConditionPassed() then
11435         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11436         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11437         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11438         Elem[D[d],index,esize] = MemU[address,ebytes];
11439 #endif
11440 
11441     bool success = false;
11442 
11443     if (ConditionPassed (opcode))
11444     {
11445         uint32_t ebytes;
11446         uint32_t esize;
11447         uint32_t index;
11448         uint32_t alignment;
11449         uint32_t d;
11450         uint32_t n;
11451         uint32_t m;
11452         bool wback;
11453         bool register_index;
11454 
11455         switch (encoding)
11456         {
11457             case eEncodingT1:
11458             case eEncodingA1:
11459             {
11460                 uint32_t size = Bits32 (opcode, 11, 10);
11461                 uint32_t index_align = Bits32 (opcode, 7, 4);
11462                 // if size == �11� then SEE VLD1 (single element to all lanes);
11463                 if (size == 3)
11464                    return EmulateVLD1SingleAll (opcode, encoding);
11465                 // case size of
11466                 if (size == 0) // when '00'
11467                 {
11468                     // if index_align<0> != �0� then UNDEFINED;
11469                     if (BitIsClear (index_align, 0))
11470                         return false;
11471 
11472                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11473                     ebytes = 1;
11474                     esize = 8;
11475                     index = Bits32 (index_align, 3, 1);
11476                     alignment = 1;
11477                 }
11478                 else if (size == 1) // when �01�
11479                 {
11480                     // if index_align<1> != �0� then UNDEFINED;
11481                     if (BitIsClear (index_align, 1))
11482                         return false;
11483 
11484                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11485                     ebytes = 2;
11486                     esize = 16;
11487                     index = Bits32 (index_align, 3, 2);
11488 
11489                     // alignment = if index_align<0> == �0� then 1 else 2;
11490                     if (BitIsClear (index_align, 0))
11491                         alignment = 1;
11492                     else
11493                         alignment = 2;
11494                 }
11495                 else if (size == 2) // when �10�
11496                 {
11497                     // if index_align<2> != �0� then UNDEFINED;
11498                     if (BitIsClear (index_align, 2))
11499                         return false;
11500 
11501                     // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11502                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11503                         return false;
11504 
11505                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11506                     ebytes = 4;
11507                     esize = 32;
11508                     index = Bit32 (index_align, 3);
11509 
11510                     // alignment = if index_align<1:0> == �00� then 1 else 4;
11511                     if (Bits32 (index_align, 1, 0) == 0)
11512                         alignment = 1;
11513                     else
11514                         alignment = 4;
11515                 }
11516                 else
11517                 {
11518                     return false;
11519                 }
11520                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11521                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11522                 n = Bits32 (opcode, 19, 16);
11523                 m = Bits32 (opcode, 3, 0);
11524 
11525                 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
11526                 wback = (m != 15);
11527                 register_index = ((m != 15) && (m != 13));
11528 
11529                 if (n == 15)
11530                     return false;
11531 
11532             }
11533                 break;
11534 
11535             default:
11536                 return false;
11537         }
11538 
11539         RegisterInfo base_reg;
11540         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11541 
11542         uint32_t Rn = ReadCoreReg (n, &success);
11543         if (!success)
11544             return false;
11545 
11546         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11547         addr_t address = Rn;
11548         if ((address % alignment) != 0)
11549             return false;
11550 
11551         EmulateInstruction::Context context;
11552         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11553         if (wback)
11554         {
11555             uint32_t Rm = ReadCoreReg (m, &success);
11556             if (!success)
11557                 return false;
11558 
11559             uint32_t offset;
11560             if (register_index)
11561                 offset = Rm;
11562             else
11563                 offset = ebytes;
11564 
11565             uint32_t value = Rn + offset;
11566 
11567             context.type = eContextAdjustBaseRegister;
11568             context.SetRegisterPlusOffset (base_reg, offset);
11569 
11570             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11571                 return false;
11572         }
11573 
11574         // Elem[D[d],index,esize] = MemU[address,ebytes];
11575         uint32_t element = MemURead (context, address, esize, 0, &success);
11576         if (!success)
11577             return false;
11578 
11579         element = element << (index * esize);
11580 
11581         uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11582         if (!success)
11583             return false;
11584 
11585         uint64_t all_ones = -1;
11586         uint64_t mask = all_ones << ((index+1) * esize);  // mask is all 1's to left of where 'element' goes, & all 0's
11587                                                           // at element & to the right of element.
11588         if (index > 0)
11589             mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes.
11590                                                                      // now mask should be 0's where element goes & 1's
11591                                                                      // everywhere else.
11592 
11593         uint64_t masked_reg = reg_data & mask;  // Take original reg value & zero out 'element' bits
11594         reg_data = masked_reg & element;        // Put 'element' into those bits in reg_data.
11595 
11596         context.type = eContextRegisterLoad;
11597         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data))
11598             return false;
11599     }
11600     return true;
11601 }
11602 
11603 // A8.6.391 VST1 (multiple single elements)
11604 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four regsiters, without
11605 // interleaving.  Every element of each register is stored.
11606 bool
11607 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding)
11608 {
11609 #if 0
11610     if ConditionPassed() then
11611         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11612         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11613         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11614         for r = 0 to regs-1
11615             for e = 0 to elements-1
11616                 MemU[address,ebytes] = Elem[D[d+r],e,esize];
11617                 address = address + ebytes;
11618 #endif
11619 
11620     bool success = false;
11621 
11622     if (ConditionPassed (opcode))
11623     {
11624         uint32_t regs;
11625         uint32_t alignment;
11626         uint32_t ebytes;
11627         uint32_t esize;
11628         uint32_t elements;
11629         uint32_t d;
11630         uint32_t n;
11631         uint32_t m;
11632         bool wback;
11633         bool register_index;
11634 
11635         switch (encoding)
11636         {
11637             case eEncodingT1:
11638             case eEncodingA1:
11639             {
11640                 uint32_t type = Bits32 (opcode, 11, 8);
11641                 uint32_t align = Bits32 (opcode, 5, 4);
11642 
11643                 // case type of
11644                 if (type == 7)    // when �0111�
11645                 {
11646                     // regs = 1; if align<1> == �1� then UNDEFINED;
11647                     regs = 1;
11648                     if (BitIsSet (align, 1))
11649                         return false;
11650                 }
11651                 else if (type == 10) // when �1010�
11652                 {
11653                     // regs = 2; if align == �11� then UNDEFINED;
11654                     regs = 2;
11655                     if (align == 3)
11656                         return false;
11657                 }
11658                 else if (type == 6) // when �0110�
11659                 {
11660                     // regs = 3; if align<1> == �1� then UNDEFINED;
11661                     regs = 3;
11662                     if (BitIsSet (align, 1))
11663                         return false;
11664                 }
11665                 else if (type == 2) // when �0010�
11666                     // regs = 4;
11667                     regs = 4;
11668                 else // otherwise
11669                     // SEE �Related encodings�;
11670                     return false;
11671 
11672                 // alignment = if align == �00� then 1 else 4 << UInt(align);
11673                 if (align == 0)
11674                     alignment = 1;
11675                 else
11676                     alignment = 4 << align;
11677 
11678                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11679                 ebytes = 1 << Bits32 (opcode,7, 6);
11680                 esize = 8 * ebytes;
11681                 elements = 8 / ebytes;
11682 
11683                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11684                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11685                 n = Bits32 (opcode, 19, 16);
11686                 m = Bits32 (opcode, 3, 0);
11687 
11688                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11689                 wback = (m != 15);
11690                 register_index = ((m != 15) && (m != 13));
11691 
11692                 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11693                 if ((d + regs) > 32)
11694                     return false;
11695 
11696                 if (n == 15)
11697                     return false;
11698 
11699             }
11700                 break;
11701 
11702             default:
11703                 return false;
11704         }
11705 
11706         RegisterInfo base_reg;
11707         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11708 
11709         uint32_t Rn = ReadCoreReg (n, &success);
11710         if (!success)
11711             return false;
11712 
11713         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11714         addr_t address = Rn;
11715         if ((address % alignment) != 0)
11716             return false;
11717 
11718         EmulateInstruction::Context context;
11719         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11720         if (wback)
11721         {
11722             uint32_t Rm = ReadCoreReg (m, &success);
11723             if (!success)
11724                 return false;
11725 
11726             uint32_t offset;
11727             if (register_index)
11728                 offset = Rm;
11729             else
11730                 offset = 8 * regs;
11731 
11732             context.type = eContextAdjustBaseRegister;
11733             context.SetRegisterPlusOffset (base_reg, offset);
11734 
11735             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11736                 return false;
11737         }
11738 
11739         RegisterInfo data_reg;
11740         context.type = eContextRegisterStore;
11741         // for r = 0 to regs-1
11742         for (int r = 0; r < regs; ++r)
11743         {
11744             GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
11745             uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
11746             if (!success)
11747                 return false;
11748 
11749              // for e = 0 to elements-1
11750             for (int e = 0; e < elements; ++e)
11751             {
11752                 // MemU[address,ebytes] = Elem[D[d+r],e,esize];
11753                 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize);
11754 
11755                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11756                 if (!MemUWrite (context, address, word, ebytes))
11757                     return false;
11758 
11759                 // address = address + ebytes;
11760                 address = address + ebytes;
11761             }
11762         }
11763     }
11764     return true;
11765 }
11766 
11767 // A8.6.392 VST1 (single element from one lane)
11768 // This instruction stores one element to memory from one element of a register.
11769 bool
11770 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding)
11771 {
11772 #if 0
11773     if ConditionPassed() then
11774         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11775         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11776         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11777         MemU[address,ebytes] = Elem[D[d],index,esize];
11778 #endif
11779 
11780     bool success = false;
11781 
11782     if (ConditionPassed (opcode))
11783     {
11784         uint32_t ebytes;
11785         uint32_t esize;
11786         uint32_t index;
11787         uint32_t alignment;
11788         uint32_t d;
11789         uint32_t n;
11790         uint32_t m;
11791         bool wback;
11792         bool register_index;
11793 
11794         switch (encoding)
11795         {
11796             case eEncodingT1:
11797             case eEncodingA1:
11798             {
11799                 uint32_t size = Bits32 (opcode, 11, 10);
11800                 uint32_t index_align = Bits32 (opcode, 7, 4);
11801 
11802                 // if size == �11� then UNDEFINED;
11803                 if (size == 3)
11804                     return false;
11805 
11806                 // case size of
11807                 if (size == 0) // when �00�
11808                 {
11809                     // if index_align<0> != �0� then UNDEFINED;
11810                     if (BitIsClear (index_align, 0))
11811                         return false;
11812                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11813                     ebytes = 1;
11814                     esize = 8;
11815                     index = Bits32 (index_align, 3, 1);
11816                     alignment = 1;
11817                 }
11818                 else if (size == 1) // when �01�
11819                 {
11820                     // if index_align<1> != �0� then UNDEFINED;
11821                     if (BitIsClear (index_align, 1))
11822                         return false;
11823 
11824                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11825                     ebytes = 2;
11826                     esize = 16;
11827                     index = Bits32 (index_align, 3, 2);
11828 
11829                     // alignment = if index_align<0> == �0� then 1 else 2;
11830                     if (BitIsClear (index_align, 0))
11831                         alignment = 1;
11832                     else
11833                         alignment = 2;
11834                 }
11835                 else if (size == 2) // when �10�
11836                 {
11837                     // if index_align<2> != �0� then UNDEFINED;
11838                     if (BitIsClear (index_align, 2))
11839                         return false;
11840 
11841                     // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11842                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11843                         return false;
11844 
11845                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11846                     ebytes = 4;
11847                     esize = 32;
11848                     index = Bit32 (index_align, 3);
11849 
11850                     // alignment = if index_align<1:0> == �00� then 1 else 4;
11851                     if (Bits32 (index_align, 1, 0) == 0)
11852                         alignment = 1;
11853                     else
11854                         alignment = 4;
11855                 }
11856                 else
11857                 {
11858                     return false;
11859                 }
11860                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11861                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11862                 n = Bits32 (opcode, 19, 16);
11863                 m = Bits32 (opcode, 3, 0);
11864 
11865                 // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15 then UNPREDICTABLE;
11866                 wback = (m != 15);
11867                 register_index = ((m != 15) && (m != 13));
11868 
11869                 if (n == 15)
11870                     return false;
11871             }
11872                 break;
11873 
11874             default:
11875                 return false;
11876         }
11877 
11878         RegisterInfo base_reg;
11879         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11880 
11881         uint32_t Rn = ReadCoreReg (n, &success);
11882         if (!success)
11883             return false;
11884 
11885         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11886         addr_t address = Rn;
11887         if ((address % alignment) != 0)
11888             return false;
11889 
11890         EmulateInstruction::Context context;
11891         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11892         if (wback)
11893         {
11894             uint32_t Rm = ReadCoreReg (m, &success);
11895             if (!success)
11896                 return false;
11897 
11898             uint32_t offset;
11899             if (register_index)
11900                 offset = Rm;
11901             else
11902                 offset = ebytes;
11903 
11904             context.type = eContextAdjustBaseRegister;
11905             context.SetRegisterPlusOffset (base_reg, offset);
11906 
11907             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11908                 return false;
11909         }
11910 
11911         // MemU[address,ebytes] = Elem[D[d],index,esize];
11912         uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11913         if (!success)
11914             return false;
11915 
11916         uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1,  index * esize);
11917 
11918         RegisterInfo data_reg;
11919         GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg);
11920         context.type = eContextRegisterStore;
11921         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11922 
11923         if (!MemUWrite (context, address, word, ebytes))
11924             return false;
11925     }
11926     return true;
11927 }
11928 
11929 // A8.6.309 VLD1 (single element to all lanes)
11930 // This instruction loads one element from memory into every element of one or two vectors.
11931 bool
11932 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding)
11933 {
11934 #if 0
11935     if ConditionPassed() then
11936         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11937         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11938         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11939         replicated_element = Replicate(MemU[address,ebytes], elements);
11940         for r = 0 to regs-1
11941             D[d+r] = replicated_element;
11942 #endif
11943 
11944     bool success = false;
11945 
11946     if (ConditionPassed (opcode))
11947     {
11948         uint32_t ebytes;
11949         uint32_t elements;
11950         uint32_t regs;
11951         uint32_t alignment;
11952         uint32_t d;
11953         uint32_t n;
11954         uint32_t m;
11955         bool wback;
11956         bool register_index;
11957 
11958         switch (encoding)
11959         {
11960             case eEncodingT1:
11961             case eEncodingA1:
11962             {
11963                 //if size == �11� || (size == �00� && a == �1�) then UNDEFINED;
11964                 uint32_t size = Bits32 (opcode, 7, 6);
11965                 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4)))
11966                     return false;
11967 
11968                 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2;
11969                 ebytes = 1 << size;
11970                 elements = 8 / ebytes;
11971                 if (BitIsClear (opcode, 5))
11972                     regs = 1;
11973                 else
11974                     regs = 2;
11975 
11976                 //alignment = if a == �0� then 1 else ebytes;
11977                 if (BitIsClear (opcode, 4))
11978                     alignment = 1;
11979                 else
11980                     alignment = ebytes;
11981 
11982                 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11983                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11984                 n = Bits32 (opcode, 19, 16);
11985                 m = Bits32 (opcode, 3, 0);
11986 
11987                 //wback = (m != 15); register_index = (m != 15 && m != 13);
11988                 wback = (m != 15);
11989                 register_index = ((m != 15) && (m != 13));
11990 
11991                 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11992                 if ((d + regs) > 32)
11993                     return false;
11994 
11995                 if (n == 15)
11996                     return false;
11997             }
11998             break;
11999 
12000             default:
12001                 return false;
12002         }
12003 
12004         RegisterInfo base_reg;
12005         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12006 
12007         uint32_t Rn = ReadCoreReg (n, &success);
12008         if (!success)
12009             return false;
12010 
12011         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12012         addr_t address = Rn;
12013         if ((address % alignment) != 0)
12014             return false;
12015 
12016         EmulateInstruction::Context context;
12017         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12018         if (wback)
12019         {
12020             uint32_t Rm = ReadCoreReg (m, &success);
12021             if (!success)
12022                 return false;
12023 
12024             uint32_t offset;
12025             if (register_index)
12026                 offset = Rm;
12027             else
12028                 offset = ebytes;
12029 
12030             context.type = eContextAdjustBaseRegister;
12031             context.SetRegisterPlusOffset (base_reg, offset);
12032 
12033             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
12034                 return false;
12035         }
12036 
12037         // replicated_element = Replicate(MemU[address,ebytes], elements);
12038 
12039         context.type = eContextRegisterLoad;
12040         uint64_t word = MemURead (context, address, ebytes, 0, &success);
12041         if (!success)
12042             return false;
12043 
12044         uint64_t replicated_element = 0;
12045         uint32_t esize = ebytes * 8;
12046         for (int e = 0; e < elements; ++e)
12047             replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0);
12048 
12049         // for r = 0 to regs-1
12050         for (int r = 0; r < regs; ++r)
12051         {
12052             // D[d+r] = replicated_element;
12053             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element))
12054                 return false;
12055         }
12056     }
12057     return true;
12058 }
12059 
12060 // B6.2.13 SUBS PC, LR and related instructions
12061 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack.  It subtracts the
12062 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR.
12063 bool
12064 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding)
12065 {
12066 #if 0
12067     if ConditionPassed() then
12068         EncodingSpecificOperations();
12069         if CurrentInstrSet() == InstrSet_ThumbEE then
12070             UNPREDICTABLE;
12071         operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12072         case opcode of
12073             when0000result = R[n] AND operand2; // AND
12074             when0001result = R[n] EOR operand2; // EOR
12075             when0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12076             when0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12077             when0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12078             when0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12079             when0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12080             when0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12081             when1100result = R[n] OR operand2; // ORR
12082             when1101result = operand2; // MOV
12083             when1110result = R[n] AND NOT(operand2); // BIC
12084             when1111result = NOT(operand2); // MVN
12085         CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12086         BranchWritePC(result);
12087 #endif
12088 
12089     bool success = false;
12090 
12091     if (ConditionPassed (opcode))
12092     {
12093         uint32_t n;
12094         uint32_t m;
12095         uint32_t imm32;
12096         bool register_form;
12097         ARM_ShifterType shift_t;
12098         uint32_t shift_n;
12099         uint32_t code;
12100 
12101         switch (encoding)
12102         {
12103             case eEncodingT1:
12104                 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
12105                 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB
12106                 n = 14;
12107                 imm32 = Bits32 (opcode, 7, 0);
12108                 register_form = false;
12109                 code = 2;
12110 
12111                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12112                 if (InITBlock() && !LastInITBlock())
12113                     return false;
12114 
12115                 break;
12116 
12117             case eEncodingA1:
12118                 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12119                 n = Bits32 (opcode, 19, 16);
12120                 imm32 = ARMExpandImm (opcode);
12121                 register_form = false;
12122                 code = Bits32 (opcode, 24, 21);
12123 
12124                 break;
12125 
12126             case eEncodingA2:
12127                 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12128                 n = Bits32 (opcode, 19, 16);
12129                 m = Bits32 (opcode, 3, 0);
12130                 register_form = true;
12131 
12132                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12133                 shift_n = DecodeImmShiftARM (opcode, shift_t);
12134 
12135                 break;
12136 
12137             default:
12138                 return false;
12139         }
12140 
12141         // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12142         uint32_t operand2;
12143         if (register_form)
12144         {
12145             uint32_t Rm = ReadCoreReg (m, &success);
12146             if (!success)
12147                 return false;
12148 
12149             operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success);
12150             if (!success)
12151                 return false;
12152         }
12153         else
12154         {
12155             operand2 = imm32;
12156         }
12157 
12158         uint32_t Rn = ReadCoreReg (n, &success);
12159         if (!success)
12160             return false;
12161 
12162         AddWithCarryResult result;
12163 
12164         // case opcode of
12165         switch (code)
12166         {
12167             case 0: // when �0000�
12168                 // result = R[n] AND operand2; // AND
12169                 result.result = Rn & operand2;
12170                 break;
12171 
12172             case 1: // when �0001�
12173                 // result = R[n] EOR operand2; // EOR
12174                 result.result = Rn ^ operand2;
12175                 break;
12176 
12177             case 2: // when �0010�
12178                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12179                 result = AddWithCarry (Rn, ~(operand2), 1);
12180                 break;
12181 
12182             case 3: // when �0011�
12183                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12184                 result = AddWithCarry (~(Rn), operand2, 1);
12185                 break;
12186 
12187             case 4: // when �0100�
12188                 // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12189                 result = AddWithCarry (Rn, operand2, 0);
12190                 break;
12191 
12192             case 5: // when �0101�
12193                 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12194                 result = AddWithCarry (Rn, operand2, APSR_C);
12195                 break;
12196 
12197             case 6: // when �0110�
12198                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12199                 result = AddWithCarry (Rn, ~(operand2), APSR_C);
12200                 break;
12201 
12202             case 7: // when �0111�
12203                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12204                 result = AddWithCarry (~(Rn), operand2, APSR_C);
12205                 break;
12206 
12207             case 10: // when �1100�
12208                 // result = R[n] OR operand2; // ORR
12209                 result.result = Rn | operand2;
12210                 break;
12211 
12212             case 11: // when �1101�
12213                 // result = operand2; // MOV
12214                 result.result = operand2;
12215                 break;
12216 
12217             case 12: // when �1110�
12218                 // result = R[n] AND NOT(operand2); // BIC
12219                 result.result = Rn & ~(operand2);
12220                 break;
12221 
12222             case 15: // when �1111�
12223                 // result = NOT(operand2); // MVN
12224                 result.result = ~(operand2);
12225                 break;
12226 
12227             default:
12228                 return false;
12229         }
12230         // CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12231 
12232         // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for
12233         // the best.
12234         uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12235         if (!success)
12236             return false;
12237 
12238         CPSRWriteByInstr (spsr, 15, true);
12239 
12240         // BranchWritePC(result);
12241         EmulateInstruction::Context context;
12242         context.type = eContextAdjustPC;
12243         context.SetImmediate (result.result);
12244 
12245         BranchWritePC (context, result.result);
12246     }
12247     return true;
12248 }
12249 
12250 EmulateInstructionARM::ARMOpcode*
12251 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12252 {
12253     static ARMOpcode
12254     g_arm_opcodes[] =
12255     {
12256         //----------------------------------------------------------------------
12257         // Prologue instructions
12258         //----------------------------------------------------------------------
12259 
12260         // push register(s)
12261         { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12262         { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
12263 
12264         // set r7 to point to a stack offset
12265         { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
12266         { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12267         // copy the stack pointer to ip
12268         { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
12269         { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
12270         { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12271 
12272         // adjust the stack pointer
12273         { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12274         { 0x0fef0010, 0x004d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12275 
12276         // push one register
12277         // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12278         { 0x0e5f0000, 0x040d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
12279 
12280         // vector push consecutive extension register(s)
12281         { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12282         { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12283 
12284         //----------------------------------------------------------------------
12285         // Epilogue instructions
12286         //----------------------------------------------------------------------
12287 
12288         { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12289         { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12290         { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12291         { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12292 
12293         //----------------------------------------------------------------------
12294         // Supervisor Call (previously Software Interrupt)
12295         //----------------------------------------------------------------------
12296         { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12297 
12298         //----------------------------------------------------------------------
12299         // Branch instructions
12300         //----------------------------------------------------------------------
12301         { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
12302         // To resolve ambiguity, "blx <label>" should come before "bl <label>".
12303         { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12304         { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12305         { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12306         // for example, "bx lr"
12307         { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12308         // bxj
12309         { 0x0ffffff0, 0x012fff20, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12310 
12311         //----------------------------------------------------------------------
12312         // Data-processing instructions
12313         //----------------------------------------------------------------------
12314         // adc (immediate)
12315         { 0x0fe00000, 0x02a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12316         // adc (register)
12317         { 0x0fe00010, 0x00a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12318         // add (immediate)
12319         { 0x0fe00000, 0x02800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
12320         // add (register)
12321         { 0x0fe00010, 0x00800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12322         // add (register-shifted register)
12323         { 0x0fe00090, 0x00800010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12324         // adr
12325         { 0x0fff0000, 0x028f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12326         { 0x0fff0000, 0x024f0000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12327         // and (immediate)
12328         { 0x0fe00000, 0x02000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12329         // and (register)
12330         { 0x0fe00010, 0x00000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12331         // bic (immediate)
12332         { 0x0fe00000, 0x03c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12333         // bic (register)
12334         { 0x0fe00010, 0x01c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12335         // eor (immediate)
12336         { 0x0fe00000, 0x02200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12337         // eor (register)
12338         { 0x0fe00010, 0x00200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12339         // orr (immediate)
12340         { 0x0fe00000, 0x03800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12341         // orr (register)
12342         { 0x0fe00010, 0x01800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12343         // rsb (immediate)
12344         { 0x0fe00000, 0x02600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12345         // rsb (register)
12346         { 0x0fe00010, 0x00600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12347         // rsc (immediate)
12348         { 0x0fe00000, 0x02e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12349         // rsc (register)
12350         { 0x0fe00010, 0x00e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12351         // sbc (immediate)
12352         { 0x0fe00000, 0x02c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12353         // sbc (register)
12354         { 0x0fe00010, 0x00c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12355         // sub (immediate, ARM)
12356         { 0x0fe00000, 0x02400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
12357         // sub (sp minus immediate)
12358         { 0x0fef0000, 0x024d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12359         // sub (register)
12360         { 0x0fe00010, 0x00400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12361         // teq (immediate)
12362         { 0x0ff0f000, 0x03300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12363         // teq (register)
12364         { 0x0ff0f010, 0x01300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12365         // tst (immediate)
12366         { 0x0ff0f000, 0x03100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12367         // tst (register)
12368         { 0x0ff0f010, 0x01100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12369 
12370         // mov (immediate)
12371         { 0x0fef0000, 0x03a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12372         { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
12373         // mov (register)
12374         { 0x0fef0ff0, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12375         // mvn (immediate)
12376         { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12377         // mvn (register)
12378         { 0x0fef0010, 0x01e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12379         // cmn (immediate)
12380         { 0x0ff0f000, 0x03700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12381         // cmn (register)
12382         { 0x0ff0f010, 0x01700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12383         // cmp (immediate)
12384         { 0x0ff0f000, 0x03500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
12385         // cmp (register)
12386         { 0x0ff0f010, 0x01500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
12387         // asr (immediate)
12388         { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
12389         // asr (register)
12390         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
12391         // lsl (immediate)
12392         { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
12393         // lsl (register)
12394         { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
12395         // lsr (immediate)
12396         { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
12397         // lsr (register)
12398         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
12399         // rrx is a special case encoding of ror (immediate)
12400         { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
12401         // ror (immediate)
12402         { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
12403         // ror (register)
12404         { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
12405         // mul
12406         { 0x0fe000f0, 0x00000090, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
12407 
12408         // subs pc, lr and related instructions
12409         { 0x0e10f000, 0x0210f000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" },
12410         { 0x0e10f010, 0x0010f000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" },
12411 
12412         //----------------------------------------------------------------------
12413         // Load instructions
12414         //----------------------------------------------------------------------
12415         { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12416         { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
12417         { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12418         { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
12419         { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
12420         { 0x0e500010, 0x06100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
12421         { 0x0e5f0000, 0x045f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
12422         { 0xfe500010, 0x06500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
12423         { 0x0e5f00f0, 0x005f00b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12424         { 0x0e5000f0, 0x001000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"  },
12425         { 0x0e5000f0, 0x005000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
12426         { 0x0e5f00f0, 0x005f00d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
12427         { 0x0e5000f0, 0x001000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12428         { 0x0e5000f0, 0x005000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
12429         { 0x0e5f00f0, 0x005f00f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12430         { 0x0e5000f0, 0x001000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12431         { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
12432         { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12433         { 0x0e100f00, 0x0c100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12434         { 0x0e100f00, 0x0c100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12435         { 0x0f300f00, 0x0d100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12436         { 0x0f300f00, 0x0d100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12437         { 0xffb00000, 0xf4200000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12438         { 0xffb00300, 0xf4a00000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12439         { 0xffb00f00, 0xf4a00c00, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12440 
12441         //----------------------------------------------------------------------
12442         // Store instructions
12443         //----------------------------------------------------------------------
12444         { 0x0fd00000, 0x08800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12445         { 0x0fd00000, 0x08000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
12446         { 0x0fd00000, 0x09000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12447         { 0x0fd00000, 0x09800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
12448         { 0x0e500010, 0x06000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
12449         { 0x0e5000f0, 0x000000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
12450         { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
12451         { 0x0e500000, 0x04400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12452         { 0x0e500000, 0x04000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12453         { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
12454         { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12455         { 0x0e100f00, 0x0c000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12456         { 0x0e100f00, 0x0c000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12457         { 0x0f300f00, 0x0d000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
12458         { 0x0f300f00, 0x0d000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
12459         { 0xffb00000, 0xf4000000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12460         { 0xffb00300, 0xf4800000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12461 
12462         //----------------------------------------------------------------------
12463         // Other instructions
12464         //----------------------------------------------------------------------
12465         { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
12466         { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
12467         { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
12468         { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
12469         { 0xfe500000, 0xf8100000, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
12470 
12471     };
12472     static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode);
12473 
12474     for (size_t i=0; i<k_num_arm_opcodes; ++i)
12475     {
12476         if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
12477             (g_arm_opcodes[i].variants & arm_isa) != 0)
12478             return &g_arm_opcodes[i];
12479     }
12480     return NULL;
12481 }
12482 
12483 
12484 EmulateInstructionARM::ARMOpcode*
12485 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12486 {
12487 
12488     static ARMOpcode
12489     g_thumb_opcodes[] =
12490     {
12491         //----------------------------------------------------------------------
12492         // Prologue instructions
12493         //----------------------------------------------------------------------
12494 
12495         // push register(s)
12496         { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12497         { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
12498         { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
12499 
12500         // set r7 to point to a stack offset
12501         { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
12502         // copy the stack pointer to r7
12503         { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
12504         // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
12505         { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
12506 
12507         // PC-relative load into register (see also EmulateADDSPRm)
12508         { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
12509 
12510         // adjust the stack pointer
12511         { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
12512         { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
12513         { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
12514         { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
12515         { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12516 
12517         // vector push consecutive extension register(s)
12518         { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12519         { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12520 
12521         //----------------------------------------------------------------------
12522         // Epilogue instructions
12523         //----------------------------------------------------------------------
12524 
12525         { 0xfffff800, 0x0000a800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
12526         { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
12527         { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12528         { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
12529         { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
12530         { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12531         { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12532 
12533         //----------------------------------------------------------------------
12534         // Supervisor Call (previously Software Interrupt)
12535         //----------------------------------------------------------------------
12536         { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
12537 
12538         //----------------------------------------------------------------------
12539         // If Then makes up to four following instructions conditional.
12540         //----------------------------------------------------------------------
12541         // The next 5 opcode _must_ come before the if then instruction
12542         { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"},
12543         { 0xffffffff, 0x0000bf10, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
12544         { 0xffffffff, 0x0000bf20, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
12545         { 0xffffffff, 0x0000bf30, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
12546         { 0xffffffff, 0x0000bf40, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
12547         { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
12548 
12549         //----------------------------------------------------------------------
12550         // Branch instructions
12551         //----------------------------------------------------------------------
12552         // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
12553         { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
12554         { 0xfffff800, 0x0000e000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
12555         { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
12556         { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
12557         // J1 == J2 == 1
12558         { 0xf800d000, 0xf000d000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12559         // J1 == J2 == 1
12560         { 0xf800d001, 0xf000c000, ARMV5_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12561         { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12562         // for example, "bx lr"
12563         { 0xffffff87, 0x00004700, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12564         // bxj
12565         { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12566         // compare and branch
12567         { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
12568         // table branch byte
12569         { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
12570         // table branch halfword
12571         { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
12572 
12573         //----------------------------------------------------------------------
12574         // Data-processing instructions
12575         //----------------------------------------------------------------------
12576         // adc (immediate)
12577         { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
12578         // adc (register)
12579         { 0xffffffc0, 0x00004140, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
12580         { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12581         // add (register)
12582         { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
12583         // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
12584         { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
12585         // adr
12586         { 0xfffff800, 0x0000a000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12587         { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12588         { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12589         // and (immediate)
12590         { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
12591         // and (register)
12592         { 0xffffffc0, 0x00004000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
12593         { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12594         // bic (immediate)
12595         { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
12596         // bic (register)
12597         { 0xffffffc0, 0x00004380, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
12598         { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12599         // eor (immediate)
12600         { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
12601         // eor (register)
12602         { 0xffffffc0, 0x00004040, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
12603         { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12604         // orr (immediate)
12605         { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
12606         // orr (register)
12607         { 0xffffffc0, 0x00004300, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
12608         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12609         // rsb (immediate)
12610         { 0xffffffc0, 0x00004240, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
12611         { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
12612         // rsb (register)
12613         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12614         // sbc (immediate)
12615         { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12616         // sbc (register)
12617         { 0xffffffc0, 0x00004180, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
12618         { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12619         // add (immediate, Thumb)
12620         { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
12621         { 0xfffff800, 0x00003000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
12622         { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
12623         { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
12624         // sub (immediate, Thumb)
12625         { 0xfffffe00, 0x00001e00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
12626         { 0xfffff800, 0x00003800, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
12627         { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
12628         { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
12629         // sub (sp minus immediate)
12630         { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
12631         { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
12632         // sub (register)
12633         { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
12634         { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
12635         // teq (immediate)
12636         { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
12637         // teq (register)
12638         { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12639         // tst (immediate)
12640         { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
12641         // tst (register)
12642         { 0xffffffc0, 0x00004200, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
12643         { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
12644 
12645 
12646         // move from high register to high register
12647         { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
12648         // move from low register to low register
12649         { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
12650         // mov{s}<c>.w <Rd>, <Rm>
12651         { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
12652         // move immediate
12653         { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
12654         { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
12655         { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
12656         // mvn (immediate)
12657         { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
12658         // mvn (register)
12659         { 0xffffffc0, 0x000043c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
12660         { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
12661         // cmn (immediate)
12662         { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12663         // cmn (register)
12664         { 0xffffffc0, 0x000042c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
12665         { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12666         // cmp (immediate)
12667         { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
12668         { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
12669         // cmp (register) (Rn and Rm both from r0-r7)
12670         { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12671         // cmp (register) (Rn and Rm not both from r0-r7)
12672         { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12673         // asr (immediate)
12674         { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
12675         { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
12676         // asr (register)
12677         { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
12678         { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12679         // lsl (immediate)
12680         { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
12681         { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
12682         // lsl (register)
12683         { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
12684         { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
12685         // lsr (immediate)
12686         { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
12687         { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
12688         // lsr (register)
12689         { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
12690         { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12691         // rrx is a special case encoding of ror (immediate)
12692         { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
12693         // ror (immediate)
12694         { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
12695         // ror (register)
12696         { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
12697         { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
12698         // mul
12699         { 0xffffffc0, 0x00004340, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
12700         // mul
12701         { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
12702 
12703         // subs pc, lr and related instructions
12704         { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" },
12705 
12706         //----------------------------------------------------------------------
12707         // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table;
12708         // otherwise the wrong instructions will be selected.
12709         //----------------------------------------------------------------------
12710 
12711         { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
12712         { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
12713 
12714         //----------------------------------------------------------------------
12715         // Load instructions
12716         //----------------------------------------------------------------------
12717         { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12718         { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
12719         { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12720         { 0xfffff800, 0x00006800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
12721         { 0xfffff800, 0x00009800, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
12722         { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
12723         { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
12724                   // Thumb2 PC-relative load into register
12725         { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
12726         { 0xfffffe00, 0x00005800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
12727         { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
12728         { 0xfffff800, 0x00007800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
12729         { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12730         { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" },
12731         { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
12732         { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
12733         { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
12734         { 0xfffff800, 0x00008800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"  },
12735         { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12736         { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"  },
12737         { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12738         { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
12739         { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12740         { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
12741         { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12742         { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
12743         { 0xfffffe00, 0x00005600, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
12744         { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"  },
12745         { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
12746         { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12747         { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12748         { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
12749         { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12750         { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
12751         { 0xfe100f00, 0xec100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12752         { 0xfe100f00, 0xec100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
12753         { 0xffe00f00, 0xed100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12754         { 0xff300f00, 0xed100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
12755         { 0xffb00000, 0xf9200000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12756         { 0xffb00300, 0xf9a00000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12757         { 0xffb00f00, 0xf9a00c00, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12758 
12759         //----------------------------------------------------------------------
12760         // Store instructions
12761         //----------------------------------------------------------------------
12762         { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12763         { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
12764         { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12765         { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
12766         { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
12767         { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
12768         { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
12769         { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
12770         { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
12771         { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
12772         { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
12773         { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
12774         { 0xfffffe00, 0x00005200, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
12775         { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12776         { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
12777         { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
12778         { 0xfe100f00, 0xec000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12779         { 0xfea00f00, 0xec000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12780         { 0xff300f00, 0xed000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12781         { 0xff300f00, 0xed000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12782         { 0xffb00000, 0xfa000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12783         { 0xffb00300, 0xf9800000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12784 
12785         //----------------------------------------------------------------------
12786         // Other instructions
12787         //----------------------------------------------------------------------
12788         { 0xffffffc0, 0x0000b240, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
12789         { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12790         { 0xffffffc0, 0x0000b200, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
12791         { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12792         { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
12793         { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12794         { 0xffffffc0, 0x0000b280, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
12795         { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12796     };
12797 
12798     const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode);
12799     for (size_t i=0; i<k_num_thumb_opcodes; ++i)
12800     {
12801         if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
12802             (g_thumb_opcodes[i].variants & arm_isa) != 0)
12803             return &g_thumb_opcodes[i];
12804     }
12805     return NULL;
12806 }
12807 
12808 bool
12809 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
12810 {
12811     m_arch = arch;
12812     m_arm_isa = 0;
12813     const char *arch_cstr = arch.GetArchitectureName ();
12814     if (arch_cstr)
12815     {
12816         if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
12817         else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
12818         else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
12819         else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
12820         else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
12821         else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
12822         else if (0 == ::strcasecmp(arch_cstr, "armv7s"))    m_arm_isa = ARMv7S;
12823         else if (0 == ::strcasecmp(arch_cstr, "arm"))       m_arm_isa = ARMvAll;
12824         else if (0 == ::strcasecmp(arch_cstr, "thumb"))     m_arm_isa = ARMvAll;
12825         else if (0 == ::strncasecmp(arch_cstr,"armv4", 5))  m_arm_isa = ARMv4;
12826         else if (0 == ::strncasecmp(arch_cstr,"armv6", 5))  m_arm_isa = ARMv6;
12827         else if (0 == ::strncasecmp(arch_cstr,"armv7", 5))  m_arm_isa = ARMv7;
12828         else if (0 == ::strncasecmp(arch_cstr,"armv8", 5))  m_arm_isa = ARMv8;
12829     }
12830     return m_arm_isa != 0;
12831 }
12832 
12833 bool
12834 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
12835 {
12836     if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
12837     {
12838         if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
12839             m_opcode_mode = eModeThumb;
12840         else
12841         {
12842             AddressClass addr_class = inst_addr.GetAddressClass();
12843 
12844             if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
12845                 m_opcode_mode = eModeARM;
12846             else if (addr_class == eAddressClassCodeAlternateISA)
12847                 m_opcode_mode = eModeThumb;
12848             else
12849                 return false;
12850         }
12851         if (m_opcode_mode == eModeThumb)
12852             m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
12853         else
12854             m_opcode_cpsr = CPSR_MODE_USR;
12855         return true;
12856     }
12857     return false;
12858 }
12859 
12860 bool
12861 EmulateInstructionARM::ReadInstruction ()
12862 {
12863     bool success = false;
12864     m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
12865     if (success)
12866     {
12867         addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
12868         if (success)
12869         {
12870             Context read_inst_context;
12871             read_inst_context.type = eContextReadOpcode;
12872             read_inst_context.SetNoArgs ();
12873 
12874             if (m_opcode_cpsr & MASK_CPSR_T)
12875             {
12876                 m_opcode_mode = eModeThumb;
12877                 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
12878 
12879                 if (success)
12880                 {
12881                     if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
12882                     {
12883                         m_opcode.SetOpcode16 (thumb_opcode);
12884                     }
12885                     else
12886                     {
12887                         m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success));
12888                     }
12889                 }
12890             }
12891             else
12892             {
12893                 m_opcode_mode = eModeARM;
12894                 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success));
12895             }
12896         }
12897     }
12898     if (!success)
12899     {
12900         m_opcode_mode = eModeInvalid;
12901         m_addr = LLDB_INVALID_ADDRESS;
12902     }
12903     return success;
12904 }
12905 
12906 uint32_t
12907 EmulateInstructionARM::ArchVersion ()
12908 {
12909     return m_arm_isa;
12910 }
12911 
12912 bool
12913 EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional)
12914 {
12915    // If we are ignoring conditions, then always return true.
12916    // this allows us to iterate over disassembly code and still
12917    // emulate an instruction even if we don't have all the right
12918    // bits set in the CPSR register...
12919     if (m_ignore_conditions)
12920         return true;
12921 
12922     if (is_conditional)
12923         *is_conditional = true;
12924 
12925     const uint32_t cond = CurrentCond (opcode);
12926 
12927     if (cond == UINT32_MAX)
12928         return false;
12929 
12930     bool result = false;
12931     switch (UnsignedBits(cond, 3, 1))
12932     {
12933     case 0:
12934 		if (m_opcode_cpsr == 0)
12935 			result = true;
12936         else
12937             result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
12938 		break;
12939     case 1:
12940         if (m_opcode_cpsr == 0)
12941             result = true;
12942         else
12943             result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
12944 		break;
12945     case 2:
12946         if (m_opcode_cpsr == 0)
12947             result = true;
12948         else
12949             result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
12950 		break;
12951     case 3:
12952         if (m_opcode_cpsr == 0)
12953             result = true;
12954         else
12955             result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
12956 		break;
12957     case 4:
12958         if (m_opcode_cpsr == 0)
12959             result = true;
12960         else
12961             result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12962 		break;
12963     case 5:
12964         if (m_opcode_cpsr == 0)
12965             result = true;
12966         else
12967 		{
12968             bool n = (m_opcode_cpsr & MASK_CPSR_N);
12969             bool v = (m_opcode_cpsr & MASK_CPSR_V);
12970             result = n == v;
12971         }
12972         break;
12973     case 6:
12974         if (m_opcode_cpsr == 0)
12975             result = true;
12976         else
12977 		{
12978             bool n = (m_opcode_cpsr & MASK_CPSR_N);
12979             bool v = (m_opcode_cpsr & MASK_CPSR_V);
12980             result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12981         }
12982         break;
12983     case 7:
12984         // Always execute (cond == 0b1110, or the special 0b1111 which gives
12985         // opcodes different meanings, but always means execution happpens.
12986         if (is_conditional)
12987             *is_conditional = false;
12988         result = true;
12989         break;
12990     }
12991 
12992     if (cond & 1)
12993         result = !result;
12994     return result;
12995 }
12996 
12997 uint32_t
12998 EmulateInstructionARM::CurrentCond (const uint32_t opcode)
12999 {
13000     switch (m_opcode_mode)
13001     {
13002     default:
13003     case eModeInvalid:
13004         break;
13005 
13006     case eModeARM:
13007         return UnsignedBits(opcode, 31, 28);
13008 
13009     case eModeThumb:
13010         // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
13011         // 'cond' field of the encoding.
13012         {
13013             const uint32_t byte_size = m_opcode.GetByteSize();
13014             if (byte_size == 2)
13015             {
13016                 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f)
13017                     return Bits32(opcode, 11, 7);
13018             }
13019             else if (byte_size == 4)
13020             {
13021                 if (Bits32(opcode, 31, 27) == 0x1e &&
13022                     Bits32(opcode, 15, 14) == 0x02 &&
13023                     Bits32(opcode, 12, 12) == 0x00 &&
13024                     Bits32(opcode, 25, 22) <= 0x0d)
13025                 {
13026                     return Bits32(opcode, 25, 22);
13027                 }
13028             }
13029             else
13030                 // We have an invalid thumb instruction, let's bail out.
13031                 break;
13032 
13033             return m_it_session.GetCond();
13034         }
13035     }
13036     return UINT32_MAX;  // Return invalid value
13037 }
13038 
13039 bool
13040 EmulateInstructionARM::InITBlock()
13041 {
13042     return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13043 }
13044 
13045 bool
13046 EmulateInstructionARM::LastInITBlock()
13047 {
13048     return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13049 }
13050 
13051 bool
13052 EmulateInstructionARM::BadMode (uint32_t mode)
13053 {
13054 
13055     switch (mode)
13056     {
13057         case 16: return false; // '10000'
13058         case 17: return false; // '10001'
13059         case 18: return false; // '10010'
13060         case 19: return false; // '10011'
13061         case 22: return false; // '10110'
13062         case 23: return false; // '10111'
13063         case 27: return false; // '11011'
13064         case 31: return false; // '11111'
13065         default: return true;
13066     }
13067     return true;
13068 }
13069 
13070 bool
13071 EmulateInstructionARM::CurrentModeIsPrivileged ()
13072 {
13073     uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
13074 
13075     if (BadMode (mode))
13076         return false;
13077 
13078     if (mode == 16)
13079         return false;
13080 
13081     return true;
13082 }
13083 
13084 void
13085 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
13086 {
13087     bool privileged = CurrentModeIsPrivileged();
13088 
13089     uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20;
13090 
13091     if (BitIsSet (bytemask, 3))
13092     {
13093         tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
13094         if (affect_execstate)
13095             tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
13096     }
13097 
13098     if (BitIsSet (bytemask, 2))
13099     {
13100         tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
13101     }
13102 
13103     if (BitIsSet (bytemask, 1))
13104     {
13105         if (affect_execstate)
13106             tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
13107         tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
13108         if (privileged)
13109             tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
13110     }
13111 
13112     if (BitIsSet (bytemask, 0))
13113     {
13114         if (privileged)
13115             tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
13116         if (affect_execstate)
13117             tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
13118         if (privileged)
13119             tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
13120     }
13121 
13122     m_opcode_cpsr = tmp_cpsr;
13123 }
13124 
13125 
13126 bool
13127 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
13128 {
13129     addr_t target;
13130 
13131     // Check the current instruction set.
13132     if (CurrentInstrSet() == eModeARM)
13133         target = addr & 0xfffffffc;
13134     else
13135         target = addr & 0xfffffffe;
13136 
13137     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13138         return false;
13139 
13140     return true;
13141 }
13142 
13143 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
13144 bool
13145 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
13146 {
13147     addr_t target;
13148     // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
13149     // we want to record it and issue a WriteRegister callback so the clients
13150     // can track the mode changes accordingly.
13151     bool cpsr_changed = false;
13152 
13153     if (BitIsSet(addr, 0))
13154     {
13155         if (CurrentInstrSet() != eModeThumb)
13156         {
13157             SelectInstrSet(eModeThumb);
13158             cpsr_changed = true;
13159         }
13160         target = addr & 0xfffffffe;
13161         context.SetISA (eModeThumb);
13162     }
13163     else if (BitIsClear(addr, 1))
13164     {
13165         if (CurrentInstrSet() != eModeARM)
13166         {
13167             SelectInstrSet(eModeARM);
13168             cpsr_changed = true;
13169         }
13170         target = addr & 0xfffffffc;
13171         context.SetISA (eModeARM);
13172     }
13173     else
13174         return false; // address<1:0> == '10' => UNPREDICTABLE
13175 
13176     if (cpsr_changed)
13177     {
13178         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13179             return false;
13180     }
13181     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13182         return false;
13183 
13184     return true;
13185 }
13186 
13187 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
13188 bool
13189 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
13190 {
13191     if (ArchVersion() >= ARMv5T)
13192         return BXWritePC(context, addr);
13193     else
13194         return BranchWritePC((const Context)context, addr);
13195 }
13196 
13197 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
13198 bool
13199 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
13200 {
13201     if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
13202         return BXWritePC(context, addr);
13203     else
13204         return BranchWritePC((const Context)context, addr);
13205 }
13206 
13207 EmulateInstructionARM::Mode
13208 EmulateInstructionARM::CurrentInstrSet ()
13209 {
13210     return m_opcode_mode;
13211 }
13212 
13213 // Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
13214 // ReadInstruction() is performed.  This function has a side effect of updating
13215 // the m_new_inst_cpsr member variable if necessary.
13216 bool
13217 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
13218 {
13219     m_new_inst_cpsr = m_opcode_cpsr;
13220     switch (arm_or_thumb)
13221     {
13222     default:
13223         return false;
13224     case eModeARM:
13225         // Clear the T bit.
13226         m_new_inst_cpsr &= ~MASK_CPSR_T;
13227         break;
13228     case eModeThumb:
13229         // Set the T bit.
13230         m_new_inst_cpsr |= MASK_CPSR_T;
13231         break;
13232     }
13233     return true;
13234 }
13235 
13236 // This function returns TRUE if the processor currently provides support for
13237 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
13238 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
13239 bool
13240 EmulateInstructionARM::UnalignedSupport()
13241 {
13242     return (ArchVersion() >= ARMv7);
13243 }
13244 
13245 // The main addition and subtraction instructions can produce status information
13246 // about both unsigned carry and signed overflow conditions.  This status
13247 // information can be used to synthesize multi-word additions and subtractions.
13248 EmulateInstructionARM::AddWithCarryResult
13249 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
13250 {
13251     uint32_t result;
13252     uint8_t carry_out;
13253     uint8_t overflow;
13254 
13255     uint64_t unsigned_sum = x + y + carry_in;
13256     int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
13257 
13258     result = UnsignedBits(unsigned_sum, 31, 0);
13259 //    carry_out = (result == unsigned_sum ? 0 : 1);
13260     overflow = ((int32_t)result == signed_sum ? 0 : 1);
13261 
13262     if (carry_in)
13263         carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0;
13264     else
13265         carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0;
13266 
13267     AddWithCarryResult res = { result, carry_out, overflow };
13268     return res;
13269 }
13270 
13271 uint32_t
13272 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
13273 {
13274     uint32_t reg_kind, reg_num;
13275     switch (num)
13276     {
13277     case SP_REG:
13278         reg_kind = eRegisterKindGeneric;
13279         reg_num  = LLDB_REGNUM_GENERIC_SP;
13280         break;
13281     case LR_REG:
13282         reg_kind = eRegisterKindGeneric;
13283         reg_num  = LLDB_REGNUM_GENERIC_RA;
13284         break;
13285     case PC_REG:
13286         reg_kind = eRegisterKindGeneric;
13287         reg_num  = LLDB_REGNUM_GENERIC_PC;
13288         break;
13289     default:
13290         if (num < SP_REG)
13291         {
13292             reg_kind = eRegisterKindDWARF;
13293             reg_num  = dwarf_r0 + num;
13294         }
13295         else
13296         {
13297             //assert(0 && "Invalid register number");
13298             *success = false;
13299             return UINT32_MAX;
13300         }
13301         break;
13302     }
13303 
13304     // Read our register.
13305     uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
13306 
13307     // When executing an ARM instruction , PC reads as the address of the current
13308     // instruction plus 8.
13309     // When executing a Thumb instruction , PC reads as the address of the current
13310     // instruction plus 4.
13311     if (num == 15)
13312     {
13313         if (CurrentInstrSet() == eModeARM)
13314             val += 8;
13315         else
13316             val += 4;
13317     }
13318 
13319     return val;
13320 }
13321 
13322 // Write the result to the ARM core register Rd, and optionally update the
13323 // condition flags based on the result.
13324 //
13325 // This helper method tries to encapsulate the following pseudocode from the
13326 // ARM Architecture Reference Manual:
13327 //
13328 // if d == 15 then         // Can only occur for encoding A1
13329 //     ALUWritePC(result); // setflags is always FALSE here
13330 // else
13331 //     R[d] = result;
13332 //     if setflags then
13333 //         APSR.N = result<31>;
13334 //         APSR.Z = IsZeroBit(result);
13335 //         APSR.C = carry;
13336 //         // APSR.V unchanged
13337 //
13338 // In the above case, the API client does not pass in the overflow arg, which
13339 // defaults to ~0u.
13340 bool
13341 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
13342                                                   const uint32_t result,
13343                                                   const uint32_t Rd,
13344                                                   bool setflags,
13345                                                   const uint32_t carry,
13346                                                   const uint32_t overflow)
13347 {
13348     if (Rd == 15)
13349     {
13350         if (!ALUWritePC (context, result))
13351             return false;
13352     }
13353     else
13354     {
13355         uint32_t reg_kind, reg_num;
13356         switch (Rd)
13357         {
13358         case SP_REG:
13359             reg_kind = eRegisterKindGeneric;
13360             reg_num  = LLDB_REGNUM_GENERIC_SP;
13361             break;
13362         case LR_REG:
13363             reg_kind = eRegisterKindGeneric;
13364             reg_num  = LLDB_REGNUM_GENERIC_RA;
13365             break;
13366         default:
13367             reg_kind = eRegisterKindDWARF;
13368             reg_num  = dwarf_r0 + Rd;
13369         }
13370         if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
13371             return false;
13372         if (setflags)
13373             return WriteFlags (context, result, carry, overflow);
13374     }
13375     return true;
13376 }
13377 
13378 // This helper method tries to encapsulate the following pseudocode from the
13379 // ARM Architecture Reference Manual:
13380 //
13381 // APSR.N = result<31>;
13382 // APSR.Z = IsZeroBit(result);
13383 // APSR.C = carry;
13384 // APSR.V = overflow
13385 //
13386 // Default arguments can be specified for carry and overflow parameters, which means
13387 // not to update the respective flags.
13388 bool
13389 EmulateInstructionARM::WriteFlags (Context &context,
13390                                    const uint32_t result,
13391                                    const uint32_t carry,
13392                                    const uint32_t overflow)
13393 {
13394     m_new_inst_cpsr = m_opcode_cpsr;
13395     SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
13396     SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
13397     if (carry != ~0u)
13398         SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
13399     if (overflow != ~0u)
13400         SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
13401     if (m_new_inst_cpsr != m_opcode_cpsr)
13402     {
13403         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13404             return false;
13405     }
13406     return true;
13407 }
13408 
13409 bool
13410 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
13411 {
13412     // Advance the ITSTATE bits to their values for the next instruction.
13413     if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
13414         m_it_session.ITAdvance();
13415 
13416     ARMOpcode *opcode_data = NULL;
13417 
13418     if (m_opcode_mode == eModeThumb)
13419         opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13420     else if (m_opcode_mode == eModeARM)
13421         opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13422 
13423     if (opcode_data == NULL)
13424         return false;
13425 
13426     const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
13427     m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
13428 
13429     bool success = false;
13430     if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
13431     {
13432         m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF,
13433                                                 dwarf_cpsr,
13434                                                 0,
13435                                                 &success);
13436     }
13437 
13438     // Only return false if we are unable to read the CPSR if we care about conditions
13439     if (success == false && m_ignore_conditions == false)
13440         return false;
13441 
13442     uint32_t orig_pc_value = 0;
13443     if (auto_advance_pc)
13444     {
13445         orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13446         if (!success)
13447             return false;
13448     }
13449 
13450     // Call the Emulate... function.
13451     success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
13452     if (!success)
13453         return false;
13454 
13455     if (auto_advance_pc)
13456     {
13457         uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13458         if (!success)
13459             return false;
13460 
13461         if (auto_advance_pc && (after_pc_value == orig_pc_value))
13462         {
13463             if (opcode_data->size == eSize32)
13464                 after_pc_value += 4;
13465             else if (opcode_data->size == eSize16)
13466                 after_pc_value += 2;
13467 
13468             EmulateInstruction::Context context;
13469             context.type = eContextAdvancePC;
13470             context.SetNoArgs();
13471             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
13472                 return false;
13473 
13474         }
13475     }
13476     return true;
13477 }
13478 
13479 bool
13480 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data)
13481 {
13482     if (!test_data)
13483     {
13484         out_stream->Printf ("TestEmulation: Missing test data.\n");
13485         return false;
13486     }
13487 
13488     static ConstString opcode_key ("opcode");
13489     static ConstString before_key ("before_state");
13490     static ConstString after_key ("after_state");
13491 
13492     OptionValueSP value_sp = test_data->GetValueForKey (opcode_key);
13493 
13494     uint32_t test_opcode;
13495     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64))
13496     {
13497         out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n");
13498         return false;
13499     }
13500     test_opcode = value_sp->GetUInt64Value ();
13501 
13502     if (arch.GetTriple().getArch() == llvm::Triple::arm)
13503     {
13504         m_opcode_mode = eModeARM;
13505         m_opcode.SetOpcode32 (test_opcode);
13506     }
13507     else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
13508     {
13509         m_opcode_mode = eModeThumb;
13510         if (test_opcode < 0x10000)
13511             m_opcode.SetOpcode16 (test_opcode);
13512         else
13513             m_opcode.SetOpcode32 (test_opcode);
13514 
13515     }
13516     else
13517     {
13518         out_stream->Printf ("TestEmulation:  Invalid arch.\n");
13519         return false;
13520     }
13521 
13522     EmulationStateARM before_state;
13523     EmulationStateARM after_state;
13524 
13525     value_sp = test_data->GetValueForKey (before_key);
13526     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13527     {
13528         out_stream->Printf ("TestEmulation:  Failed to find 'before' state.\n");
13529         return false;
13530     }
13531 
13532     OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary ();
13533     if (!before_state.LoadStateFromDictionary (state_dictionary))
13534     {
13535         out_stream->Printf ("TestEmulation:  Failed loading 'before' state.\n");
13536         return false;
13537     }
13538 
13539     value_sp = test_data->GetValueForKey (after_key);
13540     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13541     {
13542         out_stream->Printf ("TestEmulation:  Failed to find 'after' state.\n");
13543         return false;
13544     }
13545 
13546     state_dictionary = value_sp->GetAsDictionary ();
13547     if (!after_state.LoadStateFromDictionary (state_dictionary))
13548     {
13549         out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n");
13550         return false;
13551     }
13552 
13553     SetBaton ((void *) &before_state);
13554     SetCallbacks (&EmulationStateARM::ReadPseudoMemory,
13555                   &EmulationStateARM::WritePseudoMemory,
13556                   &EmulationStateARM::ReadPseudoRegister,
13557                   &EmulationStateARM::WritePseudoRegister);
13558 
13559     bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC);
13560     if (!success)
13561     {
13562         out_stream->Printf ("TestEmulation:  EvaluateInstruction() failed.\n");
13563         return false;
13564     }
13565 
13566     success = before_state.CompareState (after_state);
13567     if (!success)
13568         out_stream->Printf ("TestEmulation:  'before' and 'after' states do not match.\n");
13569 
13570     return success;
13571 }
13572 //
13573 //
13574 //const char *
13575 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
13576 //{
13577 //    if (reg_kind == eRegisterKindGeneric)
13578 //    {
13579 //        switch (reg_num)
13580 //        {
13581 //        case LLDB_REGNUM_GENERIC_PC:    return "pc";
13582 //        case LLDB_REGNUM_GENERIC_SP:    return "sp";
13583 //        case LLDB_REGNUM_GENERIC_FP:    return "fp";
13584 //        case LLDB_REGNUM_GENERIC_RA:    return "lr";
13585 //        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
13586 //        default: return NULL;
13587 //        }
13588 //    }
13589 //    else if (reg_kind == eRegisterKindDWARF)
13590 //    {
13591 //        return GetARMDWARFRegisterName (reg_num);
13592 //    }
13593 //    return NULL;
13594 //}
13595 //
13596 bool
13597 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
13598 {
13599     unwind_plan.Clear();
13600     unwind_plan.SetRegisterKind (eRegisterKindDWARF);
13601 
13602     UnwindPlan::RowSP row(new UnwindPlan::Row);
13603 
13604     // Our previous Call Frame Address is the stack pointer
13605     row->SetCFARegister (dwarf_sp);
13606 
13607     // Our previous PC is in the LR
13608     row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true);
13609     unwind_plan.AppendRow (row);
13610 
13611     // All other registers are the same.
13612 
13613     unwind_plan.SetSourceName ("EmulateInstructionARM");
13614     return true;
13615 }
13616 
13617 
13618 
13619 
13620