1 //===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include <stdlib.h>
11 
12 #include "EmulateInstructionARM.h"
13 #include "EmulationStateARM.h"
14 #include "lldb/Core/ArchSpec.h"
15 #include "lldb/Core/Address.h"
16 #include "lldb/Core/ConstString.h"
17 #include "lldb/Core/PluginManager.h"
18 #include "lldb/Core/Stream.h"
19 #include "lldb/Interpreter/OptionValueArray.h"
20 #include "lldb/Interpreter/OptionValueDictionary.h"
21 #include "lldb/Symbol/UnwindPlan.h"
22 
23 #include "Plugins/Process/Utility/ARMDefines.h"
24 #include "Plugins/Process/Utility/ARMUtils.h"
25 #include "Utility/ARM_DWARF_Registers.h"
26 
27 #include "llvm/ADT/STLExtras.h"
28 #include "llvm/Support/MathExtras.h" // for SignExtend32 template function
29                                      // and countTrailingZeros function
30 
31 using namespace lldb;
32 using namespace lldb_private;
33 
34 // Convenient macro definitions.
35 #define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS)
36 #define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS)
37 
38 #define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
39 
40 //----------------------------------------------------------------------
41 //
42 // ITSession implementation
43 //
44 //----------------------------------------------------------------------
45 
46 // A8.6.50
47 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
48 static uint32_t
49 CountITSize (uint32_t ITMask) {
50     // First count the trailing zeros of the IT mask.
51     uint32_t TZ = llvm::countTrailingZeros(ITMask);
52     if (TZ > 3)
53     {
54 #ifdef LLDB_CONFIGURATION_DEBUG
55         printf("Encoding error: IT Mask '0000'\n");
56 #endif
57         return 0;
58     }
59     return (4 - TZ);
60 }
61 
62 // Init ITState.  Note that at least one bit is always 1 in mask.
63 bool ITSession::InitIT(uint32_t bits7_0)
64 {
65     ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
66     if (ITCounter == 0)
67         return false;
68 
69     // A8.6.50 IT
70     unsigned short FirstCond = Bits32(bits7_0, 7, 4);
71     if (FirstCond == 0xF)
72     {
73 #ifdef LLDB_CONFIGURATION_DEBUG
74         printf("Encoding error: IT FirstCond '1111'\n");
75 #endif
76         return false;
77     }
78     if (FirstCond == 0xE && ITCounter != 1)
79     {
80 #ifdef LLDB_CONFIGURATION_DEBUG
81         printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
82 #endif
83         return false;
84     }
85 
86     ITState = bits7_0;
87     return true;
88 }
89 
90 // Update ITState if necessary.
91 void ITSession::ITAdvance()
92 {
93     //assert(ITCounter);
94     --ITCounter;
95     if (ITCounter == 0)
96         ITState = 0;
97     else
98     {
99         unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
100         SetBits32(ITState, 4, 0, NewITState4_0);
101     }
102 }
103 
104 // Return true if we're inside an IT Block.
105 bool ITSession::InITBlock()
106 {
107     return ITCounter != 0;
108 }
109 
110 // Return true if we're the last instruction inside an IT Block.
111 bool ITSession::LastInITBlock()
112 {
113     return ITCounter == 1;
114 }
115 
116 // Get condition bits for the current thumb instruction.
117 uint32_t ITSession::GetCond()
118 {
119     if (InITBlock())
120         return Bits32(ITState, 7, 4);
121     else
122         return COND_AL;
123 }
124 
125 // ARM constants used during decoding
126 #define REG_RD          0
127 #define LDM_REGLIST     1
128 #define SP_REG          13
129 #define LR_REG          14
130 #define PC_REG          15
131 #define PC_REGLIST_BIT  0x8000
132 
133 #define ARMv4     (1u << 0)
134 #define ARMv4T    (1u << 1)
135 #define ARMv5T    (1u << 2)
136 #define ARMv5TE   (1u << 3)
137 #define ARMv5TEJ  (1u << 4)
138 #define ARMv6     (1u << 5)
139 #define ARMv6K    (1u << 6)
140 #define ARMv6T2   (1u << 7)
141 #define ARMv7     (1u << 8)
142 #define ARMv7S    (1u << 9)
143 #define ARMv8     (1u << 10)
144 #define ARMvAll   (0xffffffffu)
145 
146 #define ARMV4T_ABOVE  (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
147 #define ARMV5_ABOVE   (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
148 #define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
149 #define ARMV5J_ABOVE  (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
150 #define ARMV6_ABOVE   (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
151 #define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv7S|ARMv8)
152 #define ARMV7_ABOVE   (ARMv7|ARMv7S|ARMv8)
153 
154 #define No_VFP  0
155 #define VFPv1   (1u << 1)
156 #define VFPv2   (1u << 2)
157 #define VFPv3   (1u << 3)
158 #define AdvancedSIMD (1u << 4)
159 
160 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
161 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
162 #define VFPv2v3     (VFPv2 | VFPv3)
163 
164 //----------------------------------------------------------------------
165 //
166 // EmulateInstructionARM implementation
167 //
168 //----------------------------------------------------------------------
169 
170 void
171 EmulateInstructionARM::Initialize ()
172 {
173     PluginManager::RegisterPlugin (GetPluginNameStatic (),
174                                    GetPluginDescriptionStatic (),
175                                    CreateInstance);
176 }
177 
178 void
179 EmulateInstructionARM::Terminate ()
180 {
181     PluginManager::UnregisterPlugin (CreateInstance);
182 }
183 
184 ConstString
185 EmulateInstructionARM::GetPluginNameStatic ()
186 {
187     static ConstString g_name("arm");
188     return g_name;
189 }
190 
191 const char *
192 EmulateInstructionARM::GetPluginDescriptionStatic ()
193 {
194     return "Emulate instructions for the ARM architecture.";
195 }
196 
197 EmulateInstruction *
198 EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type)
199 {
200     if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic(inst_type))
201     {
202         if (arch.GetTriple().getArch() == llvm::Triple::arm)
203         {
204             std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
205 
206             if (emulate_insn_ap.get())
207                 return emulate_insn_ap.release();
208         }
209         else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
210         {
211             std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
212 
213             if (emulate_insn_ap.get())
214                 return emulate_insn_ap.release();
215         }
216     }
217 
218     return NULL;
219 }
220 
221 bool
222 EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch)
223 {
224     if (arch.GetTriple().getArch () == llvm::Triple::arm)
225         return true;
226     else if (arch.GetTriple().getArch () == llvm::Triple::thumb)
227         return true;
228 
229     return false;
230 }
231 
232 // Write "bits (32) UNKNOWN" to memory address "address".  Helper function for many ARM instructions.
233 bool
234 EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address)
235 {
236     EmulateInstruction::Context context;
237     context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
238     context.SetNoArgs ();
239 
240     uint32_t random_data = rand ();
241     const uint32_t addr_byte_size = GetAddressByteSize();
242 
243     if (!MemAWrite (context, address, random_data, addr_byte_size))
244         return false;
245 
246     return true;
247 }
248 
249 // Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM instructions.
250 bool
251 EmulateInstructionARM::WriteBits32Unknown (int n)
252 {
253     EmulateInstruction::Context context;
254     context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
255     context.SetNoArgs ();
256 
257     bool success;
258     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
259 
260     if (!success)
261         return false;
262 
263     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
264         return false;
265 
266     return true;
267 }
268 
269 bool
270 EmulateInstructionARM::GetRegisterInfo (lldb::RegisterKind reg_kind, uint32_t reg_num, RegisterInfo &reg_info)
271 {
272     if (reg_kind == eRegisterKindGeneric)
273     {
274         switch (reg_num)
275         {
276             case LLDB_REGNUM_GENERIC_PC:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break;
277             case LLDB_REGNUM_GENERIC_SP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break;
278             case LLDB_REGNUM_GENERIC_FP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break;
279             case LLDB_REGNUM_GENERIC_RA:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break;
280             case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break;
281             default: return false;
282         }
283     }
284 
285     if (reg_kind == eRegisterKindDWARF)
286         return GetARMDWARFRegisterInfo(reg_num, reg_info);
287     return false;
288 }
289 
290 uint32_t
291 EmulateInstructionARM::GetFramePointerRegisterNumber () const
292 {
293     if (m_arch.GetTriple().isAndroid())
294         return LLDB_INVALID_REGNUM; // Don't use frame pointer on android
295     bool is_apple = false;
296     if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
297         is_apple = true;
298     switch (m_arch.GetTriple().getOS())
299     {
300             case llvm::Triple::Darwin:
301             case llvm::Triple::MacOSX:
302             case llvm::Triple::IOS:
303             case llvm::Triple::TvOS:
304             case llvm::Triple::WatchOS:
305                 is_apple = true;
306                 break;
307             default:
308                 break;
309     }
310 
311     /* On Apple iOS et al, the frame pointer register is always r7.
312      * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
313      */
314 
315     uint32_t fp_regnum = 11;
316 
317     if (is_apple)
318         fp_regnum = 7;
319 
320     if (m_opcode_mode == eModeThumb)
321         fp_regnum = 7;
322 
323     return fp_regnum;
324 }
325 
326 uint32_t
327 EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const
328 {
329     bool is_apple = false;
330     if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
331         is_apple = true;
332     switch (m_arch.GetTriple().getOS())
333     {
334             case llvm::Triple::Darwin:
335             case llvm::Triple::MacOSX:
336             case llvm::Triple::IOS:
337                 is_apple = true;
338                 break;
339             default:
340                 break;
341     }
342 
343     /* On Apple iOS et al, the frame pointer register is always r7.
344      * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
345      */
346 
347     uint32_t fp_regnum = dwarf_r11;
348 
349     if (is_apple)
350         fp_regnum = dwarf_r7;
351 
352     if (m_opcode_mode == eModeThumb)
353         fp_regnum = dwarf_r7;
354 
355     return fp_regnum;
356 }
357 
358 // Push Multiple Registers stores multiple registers to the stack, storing to
359 // consecutive memory locations ending just below the address in SP, and updates
360 // SP to point to the start of the stored data.
361 bool
362 EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding)
363 {
364 #if 0
365     // ARM pseudo code...
366     if (ConditionPassed())
367     {
368         EncodingSpecificOperations();
369         NullCheckIfThumbEE(13);
370         address = SP - 4*BitCount(registers);
371 
372         for (i = 0 to 14)
373         {
374             if (registers<i> == '1')
375             {
376                 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
377                     MemA[address,4] = bits(32) UNKNOWN;
378                 else
379                     MemA[address,4] = R[i];
380                 address = address + 4;
381             }
382         }
383 
384         if (registers<15> == '1') // Only possible for encoding A1 or A2
385             MemA[address,4] = PCStoreValue();
386 
387         SP = SP - 4*BitCount(registers);
388     }
389 #endif
390 
391     bool success = false;
392     if (ConditionPassed(opcode))
393     {
394         const uint32_t addr_byte_size = GetAddressByteSize();
395         const addr_t sp = ReadCoreReg (SP_REG, &success);
396         if (!success)
397             return false;
398         uint32_t registers = 0;
399         uint32_t Rt; // the source register
400         switch (encoding) {
401         case eEncodingT1:
402             registers = Bits32(opcode, 7, 0);
403             // The M bit represents LR.
404             if (Bit32(opcode, 8))
405                 registers |= (1u << 14);
406             // if BitCount(registers) < 1 then UNPREDICTABLE;
407             if (BitCount(registers) < 1)
408                 return false;
409             break;
410         case eEncodingT2:
411             // Ignore bits 15 & 13.
412             registers = Bits32(opcode, 15, 0) & ~0xa000;
413             // if BitCount(registers) < 2 then UNPREDICTABLE;
414             if (BitCount(registers) < 2)
415                 return false;
416             break;
417         case eEncodingT3:
418             Rt = Bits32(opcode, 15, 12);
419             // if BadReg(t) then UNPREDICTABLE;
420             if (BadReg(Rt))
421                 return false;
422             registers = (1u << Rt);
423             break;
424         case eEncodingA1:
425             registers = Bits32(opcode, 15, 0);
426             // Instead of return false, let's handle the following case as well,
427             // which amounts to pushing one reg onto the full descending stacks.
428             // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
429             break;
430         case eEncodingA2:
431             Rt = Bits32(opcode, 15, 12);
432             // if t == 13 then UNPREDICTABLE;
433             if (Rt == dwarf_sp)
434                 return false;
435             registers = (1u << Rt);
436             break;
437         default:
438             return false;
439         }
440         addr_t sp_offset = addr_byte_size * BitCount (registers);
441         addr_t addr = sp - sp_offset;
442         uint32_t i;
443 
444         EmulateInstruction::Context context;
445         context.type = EmulateInstruction::eContextPushRegisterOnStack;
446         RegisterInfo reg_info;
447         RegisterInfo sp_reg;
448         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
449         for (i=0; i<15; ++i)
450         {
451             if (BitIsSet (registers, i))
452             {
453                 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info);
454                 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
455                 uint32_t reg_value = ReadCoreReg(i, &success);
456                 if (!success)
457                     return false;
458                 if (!MemAWrite (context, addr, reg_value, addr_byte_size))
459                     return false;
460                 addr += addr_byte_size;
461             }
462         }
463 
464         if (BitIsSet (registers, 15))
465         {
466             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info);
467             context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
468             const uint32_t pc = ReadCoreReg(PC_REG, &success);
469             if (!success)
470                 return false;
471             if (!MemAWrite (context, addr, pc, addr_byte_size))
472                 return false;
473         }
474 
475         context.type = EmulateInstruction::eContextAdjustStackPointer;
476         context.SetImmediateSigned (-sp_offset);
477 
478         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
479             return false;
480     }
481     return true;
482 }
483 
484 // Pop Multiple Registers loads multiple registers from the stack, loading from
485 // consecutive memory locations staring at the address in SP, and updates
486 // SP to point just above the loaded data.
487 bool
488 EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding)
489 {
490 #if 0
491     // ARM pseudo code...
492     if (ConditionPassed())
493     {
494         EncodingSpecificOperations(); NullCheckIfThumbEE(13);
495         address = SP;
496         for i = 0 to 14
497             if registers<i> == '1' then
498                 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
499         if registers<15> == '1' then
500             if UnalignedAllowed then
501                 LoadWritePC(MemU[address,4]);
502             else
503                 LoadWritePC(MemA[address,4]);
504         if registers<13> == '0' then SP = SP + 4*BitCount(registers);
505         if registers<13> == '1' then SP = bits(32) UNKNOWN;
506     }
507 #endif
508 
509     bool success = false;
510 
511     if (ConditionPassed(opcode))
512     {
513         const uint32_t addr_byte_size = GetAddressByteSize();
514         const addr_t sp = ReadCoreReg (SP_REG, &success);
515         if (!success)
516             return false;
517         uint32_t registers = 0;
518         uint32_t Rt; // the destination register
519         switch (encoding) {
520         case eEncodingT1:
521             registers = Bits32(opcode, 7, 0);
522             // The P bit represents PC.
523             if (Bit32(opcode, 8))
524                 registers |= (1u << 15);
525             // if BitCount(registers) < 1 then UNPREDICTABLE;
526             if (BitCount(registers) < 1)
527                 return false;
528             break;
529         case eEncodingT2:
530             // Ignore bit 13.
531             registers = Bits32(opcode, 15, 0) & ~0x2000;
532             // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
533             if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
534                 return false;
535             // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
536             if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
537                 return false;
538             break;
539         case eEncodingT3:
540             Rt = Bits32(opcode, 15, 12);
541             // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
542             if (Rt == 13)
543                 return false;
544             if (Rt == 15 && InITBlock() && !LastInITBlock())
545                 return false;
546             registers = (1u << Rt);
547             break;
548         case eEncodingA1:
549             registers = Bits32(opcode, 15, 0);
550             // Instead of return false, let's handle the following case as well,
551             // which amounts to popping one reg from the full descending stacks.
552             // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
553 
554             // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
555             if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
556                 return false;
557             break;
558         case eEncodingA2:
559             Rt = Bits32(opcode, 15, 12);
560             // if t == 13 then UNPREDICTABLE;
561             if (Rt == dwarf_sp)
562                 return false;
563             registers = (1u << Rt);
564             break;
565         default:
566             return false;
567         }
568         addr_t sp_offset = addr_byte_size * BitCount (registers);
569         addr_t addr = sp;
570         uint32_t i, data;
571 
572         EmulateInstruction::Context context;
573         context.type = EmulateInstruction::eContextPopRegisterOffStack;
574 
575         RegisterInfo sp_reg;
576         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
577 
578         for (i=0; i<15; ++i)
579         {
580             if (BitIsSet (registers, i))
581             {
582                 context.SetAddress(addr);
583                 data = MemARead(context, addr, 4, 0, &success);
584                 if (!success)
585                     return false;
586                 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data))
587                     return false;
588                 addr += addr_byte_size;
589             }
590         }
591 
592         if (BitIsSet (registers, 15))
593         {
594             context.SetRegisterPlusOffset (sp_reg, addr - sp);
595             data = MemARead(context, addr, 4, 0, &success);
596             if (!success)
597                 return false;
598             // In ARMv5T and above, this is an interworking branch.
599             if (!LoadWritePC(context, data))
600                 return false;
601             //addr += addr_byte_size;
602         }
603 
604         context.type = EmulateInstruction::eContextAdjustStackPointer;
605         context.SetImmediateSigned (sp_offset);
606 
607         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
608             return false;
609     }
610     return true;
611 }
612 
613 // Set r7 or ip to point to saved value residing within the stack.
614 // ADD (SP plus immediate)
615 bool
616 EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding)
617 {
618 #if 0
619     // ARM pseudo code...
620     if (ConditionPassed())
621     {
622         EncodingSpecificOperations();
623         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
624         if d == 15 then
625            ALUWritePC(result); // setflags is always FALSE here
626         else
627             R[d] = result;
628             if setflags then
629                 APSR.N = result<31>;
630                 APSR.Z = IsZeroBit(result);
631                 APSR.C = carry;
632                 APSR.V = overflow;
633     }
634 #endif
635 
636     bool success = false;
637 
638     if (ConditionPassed(opcode))
639     {
640         const addr_t sp = ReadCoreReg (SP_REG, &success);
641         if (!success)
642             return false;
643         uint32_t Rd; // the destination register
644         uint32_t imm32;
645         switch (encoding) {
646         case eEncodingT1:
647             Rd = 7;
648             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
649             break;
650         case eEncodingA1:
651             Rd = Bits32(opcode, 15, 12);
652             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
653             break;
654         default:
655             return false;
656         }
657         addr_t sp_offset = imm32;
658         addr_t addr = sp + sp_offset; // a pointer to the stack area
659 
660         EmulateInstruction::Context context;
661         if (Rd == GetFramePointerRegisterNumber())
662             context.type = eContextSetFramePointer;
663         else
664             context.type = EmulateInstruction::eContextRegisterPlusOffset;
665         RegisterInfo sp_reg;
666         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
667         context.SetRegisterPlusOffset (sp_reg, sp_offset);
668 
669         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
670             return false;
671     }
672     return true;
673 }
674 
675 // Set r7 or ip to the current stack pointer.
676 // MOV (register)
677 bool
678 EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding)
679 {
680 #if 0
681     // ARM pseudo code...
682     if (ConditionPassed())
683     {
684         EncodingSpecificOperations();
685         result = R[m];
686         if d == 15 then
687             ALUWritePC(result); // setflags is always FALSE here
688         else
689             R[d] = result;
690             if setflags then
691                 APSR.N = result<31>;
692                 APSR.Z = IsZeroBit(result);
693                 // APSR.C unchanged
694                 // APSR.V unchanged
695     }
696 #endif
697 
698     bool success = false;
699 
700     if (ConditionPassed(opcode))
701     {
702         const addr_t sp = ReadCoreReg (SP_REG, &success);
703         if (!success)
704             return false;
705         uint32_t Rd; // the destination register
706         switch (encoding) {
707         case eEncodingT1:
708             Rd = 7;
709             break;
710         case eEncodingA1:
711             Rd = 12;
712             break;
713         default:
714             return false;
715         }
716 
717         EmulateInstruction::Context context;
718         if (Rd == GetFramePointerRegisterNumber())
719             context.type = EmulateInstruction::eContextSetFramePointer;
720         else
721             context.type = EmulateInstruction::eContextRegisterPlusOffset;
722         RegisterInfo sp_reg;
723         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
724         context.SetRegisterPlusOffset (sp_reg, 0);
725 
726         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
727             return false;
728     }
729     return true;
730 }
731 
732 // Move from high register (r8-r15) to low register (r0-r7).
733 // MOV (register)
734 bool
735 EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding)
736 {
737     return EmulateMOVRdRm (opcode, encoding);
738 }
739 
740 // Move from register to register.
741 // MOV (register)
742 bool
743 EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding)
744 {
745 #if 0
746     // ARM pseudo code...
747     if (ConditionPassed())
748     {
749         EncodingSpecificOperations();
750         result = R[m];
751         if d == 15 then
752             ALUWritePC(result); // setflags is always FALSE here
753         else
754             R[d] = result;
755             if setflags then
756                 APSR.N = result<31>;
757                 APSR.Z = IsZeroBit(result);
758                 // APSR.C unchanged
759                 // APSR.V unchanged
760     }
761 #endif
762 
763     bool success = false;
764 
765     if (ConditionPassed(opcode))
766     {
767         uint32_t Rm; // the source register
768         uint32_t Rd; // the destination register
769         bool setflags;
770         switch (encoding) {
771         case eEncodingT1:
772             Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
773             Rm = Bits32(opcode, 6, 3);
774             setflags = false;
775             if (Rd == 15 && InITBlock() && !LastInITBlock())
776                 return false;
777             break;
778         case eEncodingT2:
779             Rd = Bits32(opcode, 2, 0);
780             Rm = Bits32(opcode, 5, 3);
781             setflags = true;
782             if (InITBlock())
783                 return false;
784             break;
785         case eEncodingT3:
786             Rd = Bits32(opcode, 11, 8);
787             Rm = Bits32(opcode, 3, 0);
788             setflags = BitIsSet(opcode, 20);
789             // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
790             if (setflags && (BadReg(Rd) || BadReg(Rm)))
791                 return false;
792             // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE;
793             if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
794                 return false;
795             break;
796         case eEncodingA1:
797             Rd = Bits32(opcode, 15, 12);
798             Rm = Bits32(opcode, 3, 0);
799             setflags = BitIsSet(opcode, 20);
800 
801             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
802             if (Rd == 15 && setflags)
803                 return EmulateSUBSPcLrEtc (opcode, encoding);
804             break;
805         default:
806             return false;
807         }
808         uint32_t result = ReadCoreReg(Rm, &success);
809         if (!success)
810             return false;
811 
812         // The context specifies that Rm is to be moved into Rd.
813         EmulateInstruction::Context context;
814         if (Rd == 13)
815             context.type = EmulateInstruction::eContextAdjustStackPointer;
816         else
817             context.type = EmulateInstruction::eContextRegisterPlusOffset;
818         RegisterInfo dwarf_reg;
819         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
820         context.SetRegisterPlusOffset (dwarf_reg, 0);
821 
822         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
823             return false;
824     }
825     return true;
826 }
827 
828 // Move (immediate) writes an immediate value to the destination register.  It
829 // can optionally update the condition flags based on the value.
830 // MOV (immediate)
831 bool
832 EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding)
833 {
834 #if 0
835     // ARM pseudo code...
836     if (ConditionPassed())
837     {
838         EncodingSpecificOperations();
839         result = imm32;
840         if d == 15 then         // Can only occur for ARM encoding
841             ALUWritePC(result); // setflags is always FALSE here
842         else
843             R[d] = result;
844             if setflags then
845                 APSR.N = result<31>;
846                 APSR.Z = IsZeroBit(result);
847                 APSR.C = carry;
848                 // APSR.V unchanged
849     }
850 #endif
851 
852     if (ConditionPassed(opcode))
853     {
854         uint32_t Rd; // the destination register
855         uint32_t imm32; // the immediate value to be written to Rd
856         uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
857                             // for setflags == false, this value is a don't care
858                             // initialized to 0 to silence the static analyzer
859         bool setflags;
860         switch (encoding) {
861             case eEncodingT1:
862                 Rd = Bits32(opcode, 10, 8);
863                 setflags = !InITBlock();
864                 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
865                 carry = APSR_C;
866 
867                 break;
868 
869             case eEncodingT2:
870                 Rd = Bits32(opcode, 11, 8);
871                 setflags = BitIsSet(opcode, 20);
872                 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
873                 if (BadReg(Rd))
874                   return false;
875 
876                 break;
877 
878             case eEncodingT3:
879             {
880                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32);
881                 Rd = Bits32 (opcode, 11, 8);
882                 setflags = false;
883                 uint32_t imm4 = Bits32 (opcode, 19, 16);
884                 uint32_t imm3 = Bits32 (opcode, 14, 12);
885                 uint32_t i = Bit32 (opcode, 26);
886                 uint32_t imm8 = Bits32 (opcode, 7, 0);
887                 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
888 
889                 // if BadReg(d) then UNPREDICTABLE;
890                 if (BadReg (Rd))
891                     return false;
892             }
893                 break;
894 
895             case eEncodingA1:
896                 // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C);
897                 Rd = Bits32 (opcode, 15, 12);
898                 setflags = BitIsSet (opcode, 20);
899                 imm32 = ARMExpandImm_C (opcode, APSR_C, carry);
900 
901                 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
902                 if ((Rd == 15) && setflags)
903                     return EmulateSUBSPcLrEtc (opcode, encoding);
904 
905                 break;
906 
907             case eEncodingA2:
908             {
909                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
910                 Rd = Bits32 (opcode, 15, 12);
911                 setflags = false;
912                 uint32_t imm4 = Bits32 (opcode, 19, 16);
913                 uint32_t imm12 = Bits32 (opcode, 11, 0);
914                 imm32 = (imm4 << 12) | imm12;
915 
916                 // if d == 15 then UNPREDICTABLE;
917                 if (Rd == 15)
918                     return false;
919             }
920                 break;
921 
922             default:
923                 return false;
924         }
925         uint32_t result = imm32;
926 
927         // The context specifies that an immediate is to be moved into Rd.
928         EmulateInstruction::Context context;
929         context.type = EmulateInstruction::eContextImmediate;
930         context.SetNoArgs ();
931 
932         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
933             return false;
934     }
935     return true;
936 }
937 
938 // MUL multiplies two register values.  The least significant 32 bits of the result are written to the destination
939 // register.  These 32 bits do not depend on whether the source register values are considered to be signed values or
940 // unsigned values.
941 //
942 // Optionally, it can update the condition flags based on the result.  In the Thumb instruction set, this option is
943 // limited to only a few forms of the instruction.
944 bool
945 EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding)
946 {
947 #if 0
948     if ConditionPassed() then
949         EncodingSpecificOperations();
950         operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
951         operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
952         result = operand1 * operand2;
953         R[d] = result<31:0>;
954         if setflags then
955             APSR.N = result<31>;
956             APSR.Z = IsZeroBit(result);
957             if ArchVersion() == 4 then
958                 APSR.C = bit UNKNOWN;
959             // else APSR.C unchanged
960             // APSR.V always unchanged
961 #endif
962 
963     if (ConditionPassed(opcode))
964     {
965         uint32_t d;
966         uint32_t n;
967         uint32_t m;
968         bool setflags;
969 
970         // EncodingSpecificOperations();
971         switch (encoding)
972         {
973             case eEncodingT1:
974                 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
975                 d = Bits32 (opcode, 2, 0);
976                 n = Bits32 (opcode, 5, 3);
977                 m = Bits32 (opcode, 2, 0);
978                 setflags = !InITBlock();
979 
980                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
981                 if ((ArchVersion() < ARMv6) && (d == n))
982                     return false;
983 
984                 break;
985 
986             case eEncodingT2:
987                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
988                 d = Bits32 (opcode, 11, 8);
989                 n = Bits32 (opcode, 19, 16);
990                 m = Bits32 (opcode, 3, 0);
991                 setflags = false;
992 
993                 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
994                 if (BadReg (d) || BadReg (n) || BadReg (m))
995                     return false;
996 
997                 break;
998 
999             case eEncodingA1:
1000                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
1001                 d = Bits32 (opcode, 19, 16);
1002                 n = Bits32 (opcode, 3, 0);
1003                 m = Bits32 (opcode, 11, 8);
1004                 setflags = BitIsSet (opcode, 20);
1005 
1006                 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
1007                 if ((d == 15) ||  (n == 15) || (m == 15))
1008                     return false;
1009 
1010                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1011                 if ((ArchVersion() < ARMv6) && (d == n))
1012                     return false;
1013 
1014                 break;
1015 
1016             default:
1017                 return false;
1018         }
1019 
1020         bool success = false;
1021 
1022         // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
1023         uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
1024         if (!success)
1025             return false;
1026 
1027         // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
1028         uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
1029         if (!success)
1030             return false;
1031 
1032         // result = operand1 * operand2;
1033         uint64_t result = operand1 * operand2;
1034 
1035         // R[d] = result<31:0>;
1036         RegisterInfo op1_reg;
1037         RegisterInfo op2_reg;
1038         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
1039         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
1040 
1041         EmulateInstruction::Context context;
1042         context.type = eContextArithmetic;
1043         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
1044 
1045         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result)))
1046             return false;
1047 
1048         // if setflags then
1049         if (setflags)
1050         {
1051             // APSR.N = result<31>;
1052             // APSR.Z = IsZeroBit(result);
1053             m_new_inst_cpsr = m_opcode_cpsr;
1054             SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31));
1055             SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1056             if (m_new_inst_cpsr != m_opcode_cpsr)
1057             {
1058                 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1059                     return false;
1060             }
1061 
1062             // if ArchVersion() == 4 then
1063                 // APSR.C = bit UNKNOWN;
1064         }
1065     }
1066     return true;
1067 }
1068 
1069 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register.
1070 // It can optionally update the condition flags based on the value.
1071 bool
1072 EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding)
1073 {
1074 #if 0
1075     // ARM pseudo code...
1076     if (ConditionPassed())
1077     {
1078         EncodingSpecificOperations();
1079         result = NOT(imm32);
1080         if d == 15 then         // Can only occur for ARM encoding
1081             ALUWritePC(result); // setflags is always FALSE here
1082         else
1083             R[d] = result;
1084             if setflags then
1085                 APSR.N = result<31>;
1086                 APSR.Z = IsZeroBit(result);
1087                 APSR.C = carry;
1088                 // APSR.V unchanged
1089     }
1090 #endif
1091 
1092     if (ConditionPassed(opcode))
1093     {
1094         uint32_t Rd; // the destination register
1095         uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1096         uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1097         bool setflags;
1098         switch (encoding) {
1099         case eEncodingT1:
1100             Rd = Bits32(opcode, 11, 8);
1101             setflags = BitIsSet(opcode, 20);
1102             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1103             break;
1104         case eEncodingA1:
1105             Rd = Bits32(opcode, 15, 12);
1106             setflags = BitIsSet(opcode, 20);
1107             imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1108 
1109             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1110             if (Rd == 15 && setflags)
1111                 return EmulateSUBSPcLrEtc (opcode, encoding);
1112             break;
1113         default:
1114             return false;
1115         }
1116         uint32_t result = ~imm32;
1117 
1118         // The context specifies that an immediate is to be moved into Rd.
1119         EmulateInstruction::Context context;
1120         context.type = EmulateInstruction::eContextImmediate;
1121         context.SetNoArgs ();
1122 
1123         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1124             return false;
1125     }
1126     return true;
1127 }
1128 
1129 // Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register.
1130 // It can optionally update the condition flags based on the result.
1131 bool
1132 EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding)
1133 {
1134 #if 0
1135     // ARM pseudo code...
1136     if (ConditionPassed())
1137     {
1138         EncodingSpecificOperations();
1139         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1140         result = NOT(shifted);
1141         if d == 15 then         // Can only occur for ARM encoding
1142             ALUWritePC(result); // setflags is always FALSE here
1143         else
1144             R[d] = result;
1145             if setflags then
1146                 APSR.N = result<31>;
1147                 APSR.Z = IsZeroBit(result);
1148                 APSR.C = carry;
1149                 // APSR.V unchanged
1150     }
1151 #endif
1152 
1153     if (ConditionPassed(opcode))
1154     {
1155         uint32_t Rm; // the source register
1156         uint32_t Rd; // the destination register
1157         ARM_ShifterType shift_t;
1158         uint32_t shift_n; // the shift applied to the value read from Rm
1159         bool setflags;
1160         uint32_t carry; // the carry bit after the shift operation
1161         switch (encoding) {
1162         case eEncodingT1:
1163             Rd = Bits32(opcode, 2, 0);
1164             Rm = Bits32(opcode, 5, 3);
1165             setflags = !InITBlock();
1166             shift_t = SRType_LSL;
1167             shift_n = 0;
1168             if (InITBlock())
1169                 return false;
1170             break;
1171         case eEncodingT2:
1172             Rd = Bits32(opcode, 11, 8);
1173             Rm = Bits32(opcode, 3, 0);
1174             setflags = BitIsSet(opcode, 20);
1175             shift_n = DecodeImmShiftThumb(opcode, shift_t);
1176             // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1177             if (BadReg(Rd) || BadReg(Rm))
1178                 return false;
1179             break;
1180         case eEncodingA1:
1181             Rd = Bits32(opcode, 15, 12);
1182             Rm = Bits32(opcode, 3, 0);
1183             setflags = BitIsSet(opcode, 20);
1184             shift_n = DecodeImmShiftARM(opcode, shift_t);
1185             break;
1186         default:
1187             return false;
1188         }
1189         bool success = false;
1190         uint32_t value = ReadCoreReg(Rm, &success);
1191         if (!success)
1192             return false;
1193 
1194         uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1195         if (!success)
1196             return false;
1197         uint32_t result = ~shifted;
1198 
1199         // The context specifies that an immediate is to be moved into Rd.
1200         EmulateInstruction::Context context;
1201         context.type = EmulateInstruction::eContextImmediate;
1202         context.SetNoArgs ();
1203 
1204         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1205             return false;
1206     }
1207     return true;
1208 }
1209 
1210 // PC relative immediate load into register, possibly followed by ADD (SP plus register).
1211 // LDR (literal)
1212 bool
1213 EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding)
1214 {
1215 #if 0
1216     // ARM pseudo code...
1217     if (ConditionPassed())
1218     {
1219         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1220         base = Align(PC,4);
1221         address = if add then (base + imm32) else (base - imm32);
1222         data = MemU[address,4];
1223         if t == 15 then
1224             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1225         elsif UnalignedSupport() || address<1:0> = '00' then
1226             R[t] = data;
1227         else // Can only apply before ARMv7
1228             if CurrentInstrSet() == InstrSet_ARM then
1229                 R[t] = ROR(data, 8*UInt(address<1:0>));
1230             else
1231                 R[t] = bits(32) UNKNOWN;
1232     }
1233 #endif
1234 
1235     if (ConditionPassed(opcode))
1236     {
1237         bool success = false;
1238         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1239         if (!success)
1240             return false;
1241 
1242         // PC relative immediate load context
1243         EmulateInstruction::Context context;
1244         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1245         RegisterInfo pc_reg;
1246         GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
1247         context.SetRegisterPlusOffset (pc_reg, 0);
1248 
1249         uint32_t Rt;    // the destination register
1250         uint32_t imm32; // immediate offset from the PC
1251         bool add;       // +imm32 or -imm32?
1252         addr_t base;    // the base address
1253         addr_t address; // the PC relative address
1254         uint32_t data;  // the literal data value from the PC relative load
1255         switch (encoding) {
1256         case eEncodingT1:
1257             Rt = Bits32(opcode, 10, 8);
1258             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1259             add = true;
1260             break;
1261         case eEncodingT2:
1262             Rt = Bits32(opcode, 15, 12);
1263             imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1264             add = BitIsSet(opcode, 23);
1265             if (Rt == 15 && InITBlock() && !LastInITBlock())
1266                 return false;
1267             break;
1268         default:
1269             return false;
1270         }
1271 
1272         base = Align(pc, 4);
1273         if (add)
1274             address = base + imm32;
1275         else
1276             address = base - imm32;
1277 
1278         context.SetRegisterPlusOffset(pc_reg, address - base);
1279         data = MemURead(context, address, 4, 0, &success);
1280         if (!success)
1281             return false;
1282 
1283         if (Rt == 15)
1284         {
1285             if (Bits32(address, 1, 0) == 0)
1286             {
1287                 // In ARMv5T and above, this is an interworking branch.
1288                 if (!LoadWritePC(context, data))
1289                     return false;
1290             }
1291             else
1292                 return false;
1293         }
1294         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
1295         {
1296             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
1297                 return false;
1298         }
1299         else // We don't handle ARM for now.
1300             return false;
1301 
1302     }
1303     return true;
1304 }
1305 
1306 // An add operation to adjust the SP.
1307 // ADD (SP plus immediate)
1308 bool
1309 EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding)
1310 {
1311 #if 0
1312     // ARM pseudo code...
1313     if (ConditionPassed())
1314     {
1315         EncodingSpecificOperations();
1316         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1317         if d == 15 then // Can only occur for ARM encoding
1318             ALUWritePC(result); // setflags is always FALSE here
1319         else
1320             R[d] = result;
1321             if setflags then
1322                 APSR.N = result<31>;
1323                 APSR.Z = IsZeroBit(result);
1324                 APSR.C = carry;
1325                 APSR.V = overflow;
1326     }
1327 #endif
1328 
1329     bool success = false;
1330 
1331     if (ConditionPassed(opcode))
1332     {
1333         const addr_t sp = ReadCoreReg (SP_REG, &success);
1334         if (!success)
1335             return false;
1336         uint32_t imm32; // the immediate operand
1337         uint32_t d;
1338         bool setflags;
1339         switch (encoding)
1340         {
1341             case eEncodingT1:
1342                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1343                 d = Bits32 (opcode, 10, 8);
1344                 imm32 = (Bits32 (opcode, 7, 0) << 2);
1345                 setflags = false;
1346                 break;
1347 
1348             case eEncodingT2:
1349                 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1350                 d = 13;
1351                 imm32 = ThumbImm7Scaled (opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1352                 setflags = false;
1353                 break;
1354 
1355             case eEncodingT3:
1356                 // d = UInt(Rd); setflags = (S == "1"); imm32 = ThumbExpandImm(i:imm3:imm8);
1357                 d = Bits32 (opcode, 11, 8);
1358                 imm32 = ThumbExpandImm (opcode);
1359                 setflags = Bit32 (opcode, 20);
1360 
1361                 // if Rd == "1111" && S == "1" then SEE CMN (immediate);
1362                 if (d == 15 && setflags == 1)
1363                     return false; // CMN (immediate) not yet supported
1364 
1365                 // if d == 15 && S == "0" then UNPREDICTABLE;
1366                 if (d == 15 && setflags == 0)
1367                     return false;
1368                 break;
1369 
1370             case eEncodingT4:
1371                 {
1372                     // if Rn == '1111' then SEE ADR;
1373                     // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
1374                     d = Bits32 (opcode, 11, 8);
1375                     setflags = false;
1376                     uint32_t i = Bit32 (opcode, 26);
1377                     uint32_t imm3 = Bits32 (opcode, 14, 12);
1378                     uint32_t imm8 = Bits32 (opcode, 7, 0);
1379                     imm32 = (i << 11) | (imm3 << 8) | imm8;
1380 
1381                     // if d == 15 then UNPREDICTABLE;
1382                     if (d == 15)
1383                         return false;
1384                 }
1385                 break;
1386 
1387             default:
1388                 return false;
1389         }
1390         // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
1391         AddWithCarryResult res = AddWithCarry (sp, imm32, 0);
1392 
1393         EmulateInstruction::Context context;
1394         if (d == 13)
1395             context.type = EmulateInstruction::eContextAdjustStackPointer;
1396         else
1397             context.type = EmulateInstruction::eContextRegisterPlusOffset;
1398 
1399         RegisterInfo sp_reg;
1400         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1401         context.SetRegisterPlusOffset (sp_reg, res.result - sp);
1402 
1403         if (d == 15)
1404         {
1405             if (!ALUWritePC (context, res.result))
1406                 return false;
1407         }
1408         else
1409         {
1410             // R[d] = result;
1411             // if setflags then
1412             //     APSR.N = result<31>;
1413             //     APSR.Z = IsZeroBit(result);
1414             //     APSR.C = carry;
1415             //     APSR.V = overflow;
1416             if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
1417                 return false;
1418         }
1419     }
1420     return true;
1421 }
1422 
1423 // An add operation to adjust the SP.
1424 // ADD (SP plus register)
1425 bool
1426 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding)
1427 {
1428 #if 0
1429     // ARM pseudo code...
1430     if (ConditionPassed())
1431     {
1432         EncodingSpecificOperations();
1433         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1434         (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1435         if d == 15 then
1436             ALUWritePC(result); // setflags is always FALSE here
1437         else
1438             R[d] = result;
1439             if setflags then
1440                 APSR.N = result<31>;
1441                 APSR.Z = IsZeroBit(result);
1442                 APSR.C = carry;
1443                 APSR.V = overflow;
1444     }
1445 #endif
1446 
1447     bool success = false;
1448 
1449     if (ConditionPassed(opcode))
1450     {
1451         const addr_t sp = ReadCoreReg (SP_REG, &success);
1452         if (!success)
1453             return false;
1454         uint32_t Rm; // the second operand
1455         switch (encoding) {
1456         case eEncodingT2:
1457             Rm = Bits32(opcode, 6, 3);
1458             break;
1459         default:
1460             return false;
1461         }
1462         int32_t reg_value = ReadCoreReg(Rm, &success);
1463         if (!success)
1464             return false;
1465 
1466         addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1467 
1468         EmulateInstruction::Context context;
1469         context.type = eContextArithmetic;
1470         RegisterInfo sp_reg;
1471         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1472 
1473         RegisterInfo other_reg;
1474         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1475         context.SetRegisterRegisterOperands (sp_reg, other_reg);
1476 
1477         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
1478             return false;
1479     }
1480     return true;
1481 }
1482 
1483 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
1484 // at a PC-relative address, and changes instruction set from ARM to Thumb, or
1485 // from Thumb to ARM.
1486 // BLX (immediate)
1487 bool
1488 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding)
1489 {
1490 #if 0
1491     // ARM pseudo code...
1492     if (ConditionPassed())
1493     {
1494         EncodingSpecificOperations();
1495         if CurrentInstrSet() == InstrSet_ARM then
1496             LR = PC - 4;
1497         else
1498             LR = PC<31:1> : '1';
1499         if targetInstrSet == InstrSet_ARM then
1500             targetAddress = Align(PC,4) + imm32;
1501         else
1502             targetAddress = PC + imm32;
1503         SelectInstrSet(targetInstrSet);
1504         BranchWritePC(targetAddress);
1505     }
1506 #endif
1507 
1508     bool success = true;
1509 
1510     if (ConditionPassed(opcode))
1511     {
1512         EmulateInstruction::Context context;
1513         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1514         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1515         if (!success)
1516             return false;
1517         addr_t lr; // next instruction address
1518         addr_t target; // target address
1519         int32_t imm32; // PC-relative offset
1520         switch (encoding) {
1521         case eEncodingT1:
1522             {
1523             lr = pc | 1u; // return address
1524             uint32_t S = Bit32(opcode, 26);
1525             uint32_t imm10 = Bits32(opcode, 25, 16);
1526             uint32_t J1 = Bit32(opcode, 13);
1527             uint32_t J2 = Bit32(opcode, 11);
1528             uint32_t imm11 = Bits32(opcode, 10, 0);
1529             uint32_t I1 = !(J1 ^ S);
1530             uint32_t I2 = !(J2 ^ S);
1531             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1532             imm32 = llvm::SignExtend32<25>(imm25);
1533             target = pc + imm32;
1534             SelectInstrSet (eModeThumb);
1535             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
1536             if (InITBlock() && !LastInITBlock())
1537                 return false;
1538             break;
1539             }
1540         case eEncodingT2:
1541             {
1542             lr = pc | 1u; // return address
1543             uint32_t S = Bit32(opcode, 26);
1544             uint32_t imm10H = Bits32(opcode, 25, 16);
1545             uint32_t J1 = Bit32(opcode, 13);
1546             uint32_t J2 = Bit32(opcode, 11);
1547             uint32_t imm10L = Bits32(opcode, 10, 1);
1548             uint32_t I1 = !(J1 ^ S);
1549             uint32_t I2 = !(J2 ^ S);
1550             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
1551             imm32 = llvm::SignExtend32<25>(imm25);
1552             target = Align(pc, 4) + imm32;
1553             SelectInstrSet (eModeARM);
1554             context.SetISAAndImmediateSigned (eModeARM, 4 + imm32);
1555             if (InITBlock() && !LastInITBlock())
1556                 return false;
1557             break;
1558             }
1559         case eEncodingA1:
1560             lr = pc - 4; // return address
1561             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1562             target = Align(pc, 4) + imm32;
1563             SelectInstrSet (eModeARM);
1564             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
1565             break;
1566         case eEncodingA2:
1567             lr = pc - 4; // return address
1568             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
1569             target = pc + imm32;
1570             SelectInstrSet (eModeThumb);
1571             context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32);
1572             break;
1573         default:
1574             return false;
1575         }
1576         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1577             return false;
1578         if (!BranchWritePC(context, target))
1579             return false;
1580         if (m_opcode_cpsr != m_new_inst_cpsr)
1581             if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1582                 return false;
1583     }
1584     return true;
1585 }
1586 
1587 // Branch with Link and Exchange (register) calls a subroutine at an address and
1588 // instruction set specified by a register.
1589 // BLX (register)
1590 bool
1591 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding)
1592 {
1593 #if 0
1594     // ARM pseudo code...
1595     if (ConditionPassed())
1596     {
1597         EncodingSpecificOperations();
1598         target = R[m];
1599         if CurrentInstrSet() == InstrSet_ARM then
1600             next_instr_addr = PC - 4;
1601             LR = next_instr_addr;
1602         else
1603             next_instr_addr = PC - 2;
1604             LR = next_instr_addr<31:1> : '1';
1605         BXWritePC(target);
1606     }
1607 #endif
1608 
1609     bool success = false;
1610 
1611     if (ConditionPassed(opcode))
1612     {
1613         EmulateInstruction::Context context;
1614         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1615         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1616         addr_t lr; // next instruction address
1617         if (!success)
1618             return false;
1619         uint32_t Rm; // the register with the target address
1620         switch (encoding) {
1621         case eEncodingT1:
1622             lr = (pc - 2) | 1u; // return address
1623             Rm = Bits32(opcode, 6, 3);
1624             // if m == 15 then UNPREDICTABLE;
1625             if (Rm == 15)
1626                 return false;
1627             if (InITBlock() && !LastInITBlock())
1628                 return false;
1629             break;
1630         case eEncodingA1:
1631             lr = pc - 4; // return address
1632             Rm = Bits32(opcode, 3, 0);
1633             // if m == 15 then UNPREDICTABLE;
1634             if (Rm == 15)
1635                 return false;
1636             break;
1637         default:
1638             return false;
1639         }
1640         addr_t target = ReadCoreReg (Rm, &success);
1641         if (!success)
1642             return false;
1643         RegisterInfo dwarf_reg;
1644         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1645         context.SetRegister (dwarf_reg);
1646         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1647             return false;
1648         if (!BXWritePC(context, target))
1649             return false;
1650     }
1651     return true;
1652 }
1653 
1654 // Branch and Exchange causes a branch to an address and instruction set specified by a register.
1655 bool
1656 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding)
1657 {
1658 #if 0
1659     // ARM pseudo code...
1660     if (ConditionPassed())
1661     {
1662         EncodingSpecificOperations();
1663         BXWritePC(R[m]);
1664     }
1665 #endif
1666 
1667     if (ConditionPassed(opcode))
1668     {
1669         EmulateInstruction::Context context;
1670         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1671         uint32_t Rm; // the register with the target address
1672         switch (encoding) {
1673         case eEncodingT1:
1674             Rm = Bits32(opcode, 6, 3);
1675             if (InITBlock() && !LastInITBlock())
1676                 return false;
1677             break;
1678         case eEncodingA1:
1679             Rm = Bits32(opcode, 3, 0);
1680             break;
1681         default:
1682             return false;
1683         }
1684         bool success = false;
1685         addr_t target = ReadCoreReg (Rm, &success);
1686         if (!success)
1687             return false;
1688 
1689         RegisterInfo dwarf_reg;
1690         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1691         context.SetRegister (dwarf_reg);
1692         if (!BXWritePC(context, target))
1693             return false;
1694     }
1695     return true;
1696 }
1697 
1698 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an
1699 // address and instruction set specified by a register as though it were a BX instruction.
1700 //
1701 // TODO: Emulate Jazelle architecture?
1702 //       We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation.
1703 bool
1704 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding)
1705 {
1706 #if 0
1707     // ARM pseudo code...
1708     if (ConditionPassed())
1709     {
1710         EncodingSpecificOperations();
1711         if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
1712             BXWritePC(R[m]);
1713         else
1714             if JazelleAcceptsExecution() then
1715                 SwitchToJazelleExecution();
1716             else
1717                 SUBARCHITECTURE_DEFINED handler call;
1718     }
1719 #endif
1720 
1721     if (ConditionPassed(opcode))
1722     {
1723         EmulateInstruction::Context context;
1724         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1725         uint32_t Rm; // the register with the target address
1726         switch (encoding) {
1727         case eEncodingT1:
1728             Rm = Bits32(opcode, 19, 16);
1729             if (BadReg(Rm))
1730                 return false;
1731             if (InITBlock() && !LastInITBlock())
1732                 return false;
1733             break;
1734         case eEncodingA1:
1735             Rm = Bits32(opcode, 3, 0);
1736             if (Rm == 15)
1737                 return false;
1738             break;
1739         default:
1740             return false;
1741         }
1742         bool success = false;
1743         addr_t target = ReadCoreReg (Rm, &success);
1744         if (!success)
1745             return false;
1746 
1747         RegisterInfo dwarf_reg;
1748         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1749         context.SetRegister (dwarf_reg);
1750         if (!BXWritePC(context, target))
1751             return false;
1752     }
1753     return true;
1754 }
1755 
1756 // Set r7 to point to some ip offset.
1757 // SUB (immediate)
1758 bool
1759 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding)
1760 {
1761 #if 0
1762     // ARM pseudo code...
1763     if (ConditionPassed())
1764     {
1765         EncodingSpecificOperations();
1766         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1767         if d == 15 then // Can only occur for ARM encoding
1768            ALUWritePC(result); // setflags is always FALSE here
1769         else
1770             R[d] = result;
1771             if setflags then
1772                 APSR.N = result<31>;
1773                 APSR.Z = IsZeroBit(result);
1774                 APSR.C = carry;
1775                 APSR.V = overflow;
1776     }
1777 #endif
1778 
1779     if (ConditionPassed(opcode))
1780     {
1781         bool success = false;
1782         const addr_t ip = ReadCoreReg (12, &success);
1783         if (!success)
1784             return false;
1785         uint32_t imm32;
1786         switch (encoding) {
1787         case eEncodingA1:
1788             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1789             break;
1790         default:
1791             return false;
1792         }
1793         addr_t ip_offset = imm32;
1794         addr_t addr = ip - ip_offset; // the adjusted ip value
1795 
1796         EmulateInstruction::Context context;
1797         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1798         RegisterInfo dwarf_reg;
1799         GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg);
1800         context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
1801 
1802         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
1803             return false;
1804     }
1805     return true;
1806 }
1807 
1808 // Set ip to point to some stack offset.
1809 // SUB (SP minus immediate)
1810 bool
1811 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding)
1812 {
1813 #if 0
1814     // ARM pseudo code...
1815     if (ConditionPassed())
1816     {
1817         EncodingSpecificOperations();
1818         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1819         if d == 15 then // Can only occur for ARM encoding
1820            ALUWritePC(result); // setflags is always FALSE here
1821         else
1822             R[d] = result;
1823             if setflags then
1824                 APSR.N = result<31>;
1825                 APSR.Z = IsZeroBit(result);
1826                 APSR.C = carry;
1827                 APSR.V = overflow;
1828     }
1829 #endif
1830 
1831     if (ConditionPassed(opcode))
1832     {
1833         bool success = false;
1834         const addr_t sp = ReadCoreReg (SP_REG, &success);
1835         if (!success)
1836             return false;
1837         uint32_t imm32;
1838         switch (encoding) {
1839         case eEncodingA1:
1840             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1841             break;
1842         default:
1843             return false;
1844         }
1845         addr_t sp_offset = imm32;
1846         addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1847 
1848         EmulateInstruction::Context context;
1849         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1850         RegisterInfo dwarf_reg;
1851         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
1852         context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
1853 
1854         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
1855             return false;
1856     }
1857     return true;
1858 }
1859 
1860 // This instruction subtracts an immediate value from the SP value, and writes
1861 // the result to the destination register.
1862 //
1863 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage.
1864 bool
1865 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding)
1866 {
1867 #if 0
1868     // ARM pseudo code...
1869     if (ConditionPassed())
1870     {
1871         EncodingSpecificOperations();
1872         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1873         if d == 15 then        // Can only occur for ARM encoding
1874            ALUWritePC(result); // setflags is always FALSE here
1875         else
1876             R[d] = result;
1877             if setflags then
1878                 APSR.N = result<31>;
1879                 APSR.Z = IsZeroBit(result);
1880                 APSR.C = carry;
1881                 APSR.V = overflow;
1882     }
1883 #endif
1884 
1885     bool success = false;
1886     if (ConditionPassed(opcode))
1887     {
1888         const addr_t sp = ReadCoreReg (SP_REG, &success);
1889         if (!success)
1890             return false;
1891 
1892         uint32_t Rd;
1893         bool setflags;
1894         uint32_t imm32;
1895         switch (encoding) {
1896         case eEncodingT1:
1897             Rd = 13;
1898             setflags = false;
1899             imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1900             break;
1901         case eEncodingT2:
1902             Rd = Bits32(opcode, 11, 8);
1903             setflags = BitIsSet(opcode, 20);
1904             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1905             if (Rd == 15 && setflags)
1906                 return EmulateCMPImm(opcode, eEncodingT2);
1907             if (Rd == 15 && !setflags)
1908                 return false;
1909             break;
1910         case eEncodingT3:
1911             Rd = Bits32(opcode, 11, 8);
1912             setflags = false;
1913             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
1914             if (Rd == 15)
1915                 return false;
1916             break;
1917         case eEncodingA1:
1918             Rd = Bits32(opcode, 15, 12);
1919             setflags = BitIsSet(opcode, 20);
1920             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1921 
1922             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1923             if (Rd == 15 && setflags)
1924                 return EmulateSUBSPcLrEtc (opcode, encoding);
1925             break;
1926         default:
1927             return false;
1928         }
1929         AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
1930 
1931         EmulateInstruction::Context context;
1932         if (Rd == 13)
1933         {
1934             uint64_t imm64 = imm32;  // Need to expand it to 64 bits before attempting to negate it, or the wrong
1935                                      // value gets passed down to context.SetImmediateSigned.
1936             context.type = EmulateInstruction::eContextAdjustStackPointer;
1937             context.SetImmediateSigned (-imm64); // the stack pointer offset
1938         }
1939         else
1940         {
1941             context.type = EmulateInstruction::eContextImmediate;
1942             context.SetNoArgs ();
1943         }
1944 
1945         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
1946             return false;
1947     }
1948     return true;
1949 }
1950 
1951 // A store operation to the stack that also updates the SP.
1952 bool
1953 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding)
1954 {
1955 #if 0
1956     // ARM pseudo code...
1957     if (ConditionPassed())
1958     {
1959         EncodingSpecificOperations();
1960         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1961         address = if index then offset_addr else R[n];
1962         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1963         if wback then R[n] = offset_addr;
1964     }
1965 #endif
1966 
1967     bool success = false;
1968     if (ConditionPassed(opcode))
1969     {
1970         const uint32_t addr_byte_size = GetAddressByteSize();
1971         const addr_t sp = ReadCoreReg (SP_REG, &success);
1972         if (!success)
1973             return false;
1974         uint32_t Rt; // the source register
1975         uint32_t imm12;
1976         uint32_t Rn;  // This function assumes Rn is the SP, but we should verify that.
1977 
1978         bool index;
1979         bool add;
1980         bool wback;
1981         switch (encoding) {
1982         case eEncodingA1:
1983             Rt = Bits32(opcode, 15, 12);
1984             imm12 = Bits32(opcode, 11, 0);
1985             Rn = Bits32 (opcode, 19, 16);
1986 
1987             if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
1988                 return false;
1989 
1990             index = BitIsSet (opcode, 24);
1991             add = BitIsSet (opcode, 23);
1992             wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
1993 
1994             if (wback && ((Rn == 15) || (Rn == Rt)))
1995                 return false;
1996             break;
1997         default:
1998             return false;
1999         }
2000         addr_t offset_addr;
2001         if (add)
2002             offset_addr = sp + imm12;
2003         else
2004             offset_addr = sp - imm12;
2005 
2006         addr_t addr;
2007         if (index)
2008             addr = offset_addr;
2009         else
2010             addr = sp;
2011 
2012         EmulateInstruction::Context context;
2013         context.type = EmulateInstruction::eContextPushRegisterOnStack;
2014         RegisterInfo sp_reg;
2015         RegisterInfo dwarf_reg;
2016 
2017         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2018         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
2019         context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
2020         if (Rt != 15)
2021         {
2022             uint32_t reg_value = ReadCoreReg(Rt, &success);
2023             if (!success)
2024                 return false;
2025             if (!MemUWrite (context, addr, reg_value, addr_byte_size))
2026                 return false;
2027         }
2028         else
2029         {
2030             const uint32_t pc = ReadCoreReg(PC_REG, &success);
2031             if (!success)
2032                 return false;
2033             if (!MemUWrite (context, addr, pc, addr_byte_size))
2034                 return false;
2035         }
2036 
2037 
2038         if (wback)
2039         {
2040             context.type = EmulateInstruction::eContextAdjustStackPointer;
2041             context.SetImmediateSigned (addr - sp);
2042             if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr))
2043                 return false;
2044         }
2045     }
2046     return true;
2047 }
2048 
2049 // Vector Push stores multiple extension registers to the stack.
2050 // It also updates SP to point to the start of the stored data.
2051 bool
2052 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding)
2053 {
2054 #if 0
2055     // ARM pseudo code...
2056     if (ConditionPassed())
2057     {
2058         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2059         address = SP - imm32;
2060         SP = SP - imm32;
2061         if single_regs then
2062             for r = 0 to regs-1
2063                 MemA[address,4] = S[d+r]; address = address+4;
2064         else
2065             for r = 0 to regs-1
2066                 // Store as two word-aligned words in the correct order for current endianness.
2067                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
2068                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
2069                 address = address+8;
2070     }
2071 #endif
2072 
2073     bool success = false;
2074     if (ConditionPassed(opcode))
2075     {
2076         const uint32_t addr_byte_size = GetAddressByteSize();
2077         const addr_t sp = ReadCoreReg (SP_REG, &success);
2078         if (!success)
2079             return false;
2080         bool single_regs;
2081         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2082         uint32_t imm32; // stack offset
2083         uint32_t regs;  // number of registers
2084         switch (encoding) {
2085         case eEncodingT1:
2086         case eEncodingA1:
2087             single_regs = false;
2088             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2089             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2090             // If UInt(imm8) is odd, see "FSTMX".
2091             regs = Bits32(opcode, 7, 0) / 2;
2092             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2093             if (regs == 0 || regs > 16 || (d + regs) > 32)
2094                 return false;
2095             break;
2096         case eEncodingT2:
2097         case eEncodingA2:
2098             single_regs = true;
2099             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2100             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2101             regs = Bits32(opcode, 7, 0);
2102             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2103             if (regs == 0 || regs > 16 || (d + regs) > 32)
2104                 return false;
2105             break;
2106         default:
2107             return false;
2108         }
2109         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2110         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2111         addr_t sp_offset = imm32;
2112         addr_t addr = sp - sp_offset;
2113         uint32_t i;
2114 
2115         EmulateInstruction::Context context;
2116         context.type = EmulateInstruction::eContextPushRegisterOnStack;
2117 
2118         RegisterInfo dwarf_reg;
2119         RegisterInfo sp_reg;
2120         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2121         for (i=0; i<regs; ++i)
2122         {
2123             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2124             context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
2125             // uint64_t to accommodate 64-bit registers.
2126             uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success);
2127             if (!success)
2128                 return false;
2129             if (!MemAWrite (context, addr, reg_value, reg_byte_size))
2130                 return false;
2131             addr += reg_byte_size;
2132         }
2133 
2134         context.type = EmulateInstruction::eContextAdjustStackPointer;
2135         context.SetImmediateSigned (-sp_offset);
2136 
2137         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2138             return false;
2139     }
2140     return true;
2141 }
2142 
2143 // Vector Pop loads multiple extension registers from the stack.
2144 // It also updates SP to point just above the loaded data.
2145 bool
2146 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding)
2147 {
2148 #if 0
2149     // ARM pseudo code...
2150     if (ConditionPassed())
2151     {
2152         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2153         address = SP;
2154         SP = SP + imm32;
2155         if single_regs then
2156             for r = 0 to regs-1
2157                 S[d+r] = MemA[address,4]; address = address+4;
2158         else
2159             for r = 0 to regs-1
2160                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2161                 // Combine the word-aligned words in the correct order for current endianness.
2162                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2163     }
2164 #endif
2165 
2166     bool success = false;
2167     if (ConditionPassed(opcode))
2168     {
2169         const uint32_t addr_byte_size = GetAddressByteSize();
2170         const addr_t sp = ReadCoreReg (SP_REG, &success);
2171         if (!success)
2172             return false;
2173         bool single_regs;
2174         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2175         uint32_t imm32; // stack offset
2176         uint32_t regs;  // number of registers
2177         switch (encoding) {
2178         case eEncodingT1:
2179         case eEncodingA1:
2180             single_regs = false;
2181             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2182             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2183             // If UInt(imm8) is odd, see "FLDMX".
2184             regs = Bits32(opcode, 7, 0) / 2;
2185             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2186             if (regs == 0 || regs > 16 || (d + regs) > 32)
2187                 return false;
2188             break;
2189         case eEncodingT2:
2190         case eEncodingA2:
2191             single_regs = true;
2192             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2193             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2194             regs = Bits32(opcode, 7, 0);
2195             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2196             if (regs == 0 || regs > 16 || (d + regs) > 32)
2197                 return false;
2198             break;
2199         default:
2200             return false;
2201         }
2202         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2203         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2204         addr_t sp_offset = imm32;
2205         addr_t addr = sp;
2206         uint32_t i;
2207         uint64_t data; // uint64_t to accommodate 64-bit registers.
2208 
2209         EmulateInstruction::Context context;
2210         context.type = EmulateInstruction::eContextPopRegisterOffStack;
2211 
2212         RegisterInfo dwarf_reg;
2213         RegisterInfo sp_reg;
2214         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2215         for (i=0; i<regs; ++i)
2216         {
2217             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2218             context.SetAddress(addr);
2219             data = MemARead(context, addr, reg_byte_size, 0, &success);
2220             if (!success)
2221                 return false;
2222             if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2223                 return false;
2224             addr += reg_byte_size;
2225         }
2226 
2227         context.type = EmulateInstruction::eContextAdjustStackPointer;
2228         context.SetImmediateSigned (sp_offset);
2229 
2230         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2231             return false;
2232     }
2233     return true;
2234 }
2235 
2236 // SVC (previously SWI)
2237 bool
2238 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding)
2239 {
2240 #if 0
2241     // ARM pseudo code...
2242     if (ConditionPassed())
2243     {
2244         EncodingSpecificOperations();
2245         CallSupervisor();
2246     }
2247 #endif
2248 
2249     bool success = false;
2250 
2251     if (ConditionPassed(opcode))
2252     {
2253         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2254         addr_t lr; // next instruction address
2255         if (!success)
2256             return false;
2257         uint32_t imm32; // the immediate constant
2258         uint32_t mode;  // ARM or Thumb mode
2259         switch (encoding) {
2260         case eEncodingT1:
2261             lr = (pc + 2) | 1u; // return address
2262             imm32 = Bits32(opcode, 7, 0);
2263             mode = eModeThumb;
2264             break;
2265         case eEncodingA1:
2266             lr = pc + 4; // return address
2267             imm32 = Bits32(opcode, 23, 0);
2268             mode = eModeARM;
2269             break;
2270         default:
2271             return false;
2272         }
2273 
2274         EmulateInstruction::Context context;
2275         context.type = EmulateInstruction::eContextSupervisorCall;
2276         context.SetISAAndImmediate (mode, imm32);
2277         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
2278             return false;
2279     }
2280     return true;
2281 }
2282 
2283 // If Then makes up to four following instructions (the IT block) conditional.
2284 bool
2285 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding)
2286 {
2287 #if 0
2288     // ARM pseudo code...
2289     EncodingSpecificOperations();
2290     ITSTATE.IT<7:0> = firstcond:mask;
2291 #endif
2292 
2293     m_it_session.InitIT(Bits32(opcode, 7, 0));
2294     return true;
2295 }
2296 
2297 bool
2298 EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding)
2299 {
2300     // NOP, nothing to do...
2301     return true;
2302 }
2303 
2304 // Branch causes a branch to a target address.
2305 bool
2306 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding)
2307 {
2308 #if 0
2309     // ARM pseudo code...
2310     if (ConditionPassed())
2311     {
2312         EncodingSpecificOperations();
2313         BranchWritePC(PC + imm32);
2314     }
2315 #endif
2316 
2317     bool success = false;
2318 
2319     if (ConditionPassed(opcode))
2320     {
2321         EmulateInstruction::Context context;
2322         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2323         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2324         if (!success)
2325             return false;
2326         addr_t target; // target address
2327         int32_t imm32; // PC-relative offset
2328         switch (encoding) {
2329         case eEncodingT1:
2330             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2331             imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2332             target = pc + imm32;
2333             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2334             break;
2335         case eEncodingT2:
2336             imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1);
2337             target = pc + imm32;
2338             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2339             break;
2340         case eEncodingT3:
2341             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2342             {
2343             if (Bits32(opcode, 25, 23) == 7)
2344                 return false; // See Branches and miscellaneous control on page A6-235.
2345 
2346             uint32_t S = Bit32(opcode, 26);
2347             uint32_t imm6 = Bits32(opcode, 21, 16);
2348             uint32_t J1 = Bit32(opcode, 13);
2349             uint32_t J2 = Bit32(opcode, 11);
2350             uint32_t imm11 = Bits32(opcode, 10, 0);
2351             uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2352             imm32 = llvm::SignExtend32<21>(imm21);
2353             target = pc + imm32;
2354             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2355             break;
2356             }
2357         case eEncodingT4:
2358             {
2359             uint32_t S = Bit32(opcode, 26);
2360             uint32_t imm10 = Bits32(opcode, 25, 16);
2361             uint32_t J1 = Bit32(opcode, 13);
2362             uint32_t J2 = Bit32(opcode, 11);
2363             uint32_t imm11 = Bits32(opcode, 10, 0);
2364             uint32_t I1 = !(J1 ^ S);
2365             uint32_t I2 = !(J2 ^ S);
2366             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2367             imm32 = llvm::SignExtend32<25>(imm25);
2368             target = pc + imm32;
2369             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2370             break;
2371             }
2372         case eEncodingA1:
2373             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2374             target = pc + imm32;
2375             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
2376             break;
2377         default:
2378             return false;
2379         }
2380         if (!BranchWritePC(context, target))
2381             return false;
2382     }
2383     return true;
2384 }
2385 
2386 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
2387 // zero and conditionally branch forward a constant value.  They do not affect the condition flags.
2388 // CBNZ, CBZ
2389 bool
2390 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding)
2391 {
2392 #if 0
2393     // ARM pseudo code...
2394     EncodingSpecificOperations();
2395     if nonzero ^ IsZero(R[n]) then
2396         BranchWritePC(PC + imm32);
2397 #endif
2398 
2399     bool success = false;
2400 
2401     // Read the register value from the operand register Rn.
2402     uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2403     if (!success)
2404         return false;
2405 
2406     EmulateInstruction::Context context;
2407     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2408     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2409     if (!success)
2410         return false;
2411 
2412     addr_t target;  // target address
2413     uint32_t imm32; // PC-relative offset to branch forward
2414     bool nonzero;
2415     switch (encoding) {
2416     case eEncodingT1:
2417         imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2418         nonzero = BitIsSet(opcode, 11);
2419         target = pc + imm32;
2420         context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2421         break;
2422     default:
2423         return false;
2424     }
2425     if (m_ignore_conditions || (nonzero ^ (reg_val == 0)))
2426         if (!BranchWritePC(context, target))
2427             return false;
2428 
2429     return true;
2430 }
2431 
2432 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
2433 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2434 // The branch length is twice the value of the byte returned from the table.
2435 //
2436 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
2437 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2438 // The branch length is twice the value of the halfword returned from the table.
2439 // TBB, TBH
2440 bool
2441 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding)
2442 {
2443 #if 0
2444     // ARM pseudo code...
2445     EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2446     if is_tbh then
2447         halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2448     else
2449         halfwords = UInt(MemU[R[n]+R[m], 1]);
2450     BranchWritePC(PC + 2*halfwords);
2451 #endif
2452 
2453     bool success = false;
2454 
2455     if (ConditionPassed(opcode))
2456     {
2457         uint32_t Rn;     // the base register which contains the address of the table of branch lengths
2458         uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
2459         bool is_tbh;     // true if table branch halfword
2460         switch (encoding) {
2461         case eEncodingT1:
2462             Rn = Bits32(opcode, 19, 16);
2463             Rm = Bits32(opcode, 3, 0);
2464             is_tbh = BitIsSet(opcode, 4);
2465             if (Rn == 13 || BadReg(Rm))
2466                 return false;
2467             if (InITBlock() && !LastInITBlock())
2468                 return false;
2469             break;
2470         default:
2471             return false;
2472         }
2473 
2474         // Read the address of the table from the operand register Rn.
2475         // The PC can be used, in which case the table immediately follows this instruction.
2476         uint32_t base = ReadCoreReg(Rn, &success);
2477         if (!success)
2478             return false;
2479 
2480         // the table index
2481         uint32_t index = ReadCoreReg(Rm, &success);
2482         if (!success)
2483             return false;
2484 
2485         // the offsetted table address
2486         addr_t addr = base + (is_tbh ? index*2 : index);
2487 
2488         // PC-relative offset to branch forward
2489         EmulateInstruction::Context context;
2490         context.type = EmulateInstruction::eContextTableBranchReadMemory;
2491         uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2492         if (!success)
2493             return false;
2494 
2495         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2496         if (!success)
2497             return false;
2498 
2499         // target address
2500         addr_t target = pc + offset;
2501         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2502         context.SetISAAndImmediateSigned (eModeThumb, 4 + offset);
2503 
2504         if (!BranchWritePC(context, target))
2505             return false;
2506     }
2507 
2508     return true;
2509 }
2510 
2511 // This instruction adds an immediate value to a register value, and writes the result to the destination register.
2512 // It can optionally update the condition flags based on the result.
2513 bool
2514 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding)
2515 {
2516 #if 0
2517     if ConditionPassed() then
2518         EncodingSpecificOperations();
2519         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2520         R[d] = result;
2521         if setflags then
2522             APSR.N = result<31>;
2523             APSR.Z = IsZeroBit(result);
2524             APSR.C = carry;
2525             APSR.V = overflow;
2526 #endif
2527 
2528     bool success = false;
2529 
2530     if (ConditionPassed(opcode))
2531     {
2532         uint32_t d;
2533         uint32_t n;
2534         bool setflags;
2535         uint32_t imm32;
2536         uint32_t carry_out;
2537 
2538         //EncodingSpecificOperations();
2539         switch (encoding)
2540         {
2541             case eEncodingT1:
2542                 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32);
2543                 d = Bits32 (opcode, 2, 0);
2544                 n = Bits32 (opcode, 5, 3);
2545                 setflags = !InITBlock();
2546                 imm32 = Bits32 (opcode, 8,6);
2547 
2548                 break;
2549 
2550             case eEncodingT2:
2551                 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32);
2552                 d = Bits32 (opcode, 10, 8);
2553                 n = Bits32 (opcode, 10, 8);
2554                 setflags = !InITBlock();
2555                 imm32 = Bits32 (opcode, 7, 0);
2556 
2557                 break;
2558 
2559             case eEncodingT3:
2560                 // if Rd == '1111' && S == '1' then SEE CMN (immediate);
2561                 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8);
2562                 d = Bits32 (opcode, 11, 8);
2563                 n = Bits32 (opcode, 19, 16);
2564                 setflags = BitIsSet (opcode, 20);
2565                 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out);
2566 
2567                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2568                 if (n == 13)
2569                     return EmulateADDSPImm(opcode, eEncodingT3);
2570 
2571                 // if BadReg(d) || n == 15 then UNPREDICTABLE;
2572                 if (BadReg (d) || (n == 15))
2573                     return false;
2574 
2575                 break;
2576 
2577             case eEncodingT4:
2578             {
2579                 // if Rn == '1111' then SEE ADR;
2580                 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
2581                 d = Bits32 (opcode, 11, 8);
2582                 n = Bits32 (opcode, 19, 16);
2583                 setflags = false;
2584                 uint32_t i = Bit32 (opcode, 26);
2585                 uint32_t imm3 = Bits32 (opcode, 14, 12);
2586                 uint32_t imm8 = Bits32 (opcode, 7, 0);
2587                 imm32 = (i << 11) | (imm3 << 8) | imm8;
2588 
2589                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2590                 if (n == 13)
2591                     return EmulateADDSPImm(opcode, eEncodingT4);
2592 
2593                 // if BadReg(d) then UNPREDICTABLE;
2594                 if (BadReg (d))
2595                     return false;
2596 
2597                 break;
2598             }
2599 
2600             default:
2601                 return false;
2602         }
2603 
2604         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2605         if (!success)
2606             return false;
2607 
2608         //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2609         AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
2610 
2611         RegisterInfo reg_n;
2612         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
2613 
2614         EmulateInstruction::Context context;
2615         context.type = eContextArithmetic;
2616         context.SetRegisterPlusOffset (reg_n, imm32);
2617 
2618         //R[d] = result;
2619         //if setflags then
2620             //APSR.N = result<31>;
2621             //APSR.Z = IsZeroBit(result);
2622             //APSR.C = carry;
2623             //APSR.V = overflow;
2624         if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
2625             return false;
2626 
2627     }
2628     return true;
2629 }
2630 
2631 // This instruction adds an immediate value to a register value, and writes the result to the destination
2632 // register.  It can optionally update the condition flags based on the result.
2633 bool
2634 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding)
2635 {
2636 #if 0
2637     // ARM pseudo code...
2638     if ConditionPassed() then
2639         EncodingSpecificOperations();
2640         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2641         if d == 15 then
2642             ALUWritePC(result); // setflags is always FALSE here
2643         else
2644             R[d] = result;
2645             if setflags then
2646                 APSR.N = result<31>;
2647                 APSR.Z = IsZeroBit(result);
2648                 APSR.C = carry;
2649                 APSR.V = overflow;
2650 #endif
2651 
2652     bool success = false;
2653 
2654     if (ConditionPassed(opcode))
2655     {
2656         uint32_t Rd, Rn;
2657         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
2658         bool setflags;
2659         switch (encoding)
2660         {
2661         case eEncodingA1:
2662             Rd = Bits32(opcode, 15, 12);
2663             Rn = Bits32(opcode, 19, 16);
2664             setflags = BitIsSet(opcode, 20);
2665             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2666             break;
2667         default:
2668             return false;
2669         }
2670 
2671         // Read the first operand.
2672         uint32_t val1 = ReadCoreReg(Rn, &success);
2673         if (!success)
2674             return false;
2675 
2676         AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
2677 
2678         EmulateInstruction::Context context;
2679         if (Rd == 13)
2680             context.type = EmulateInstruction::eContextAdjustStackPointer;
2681         else if (Rd == GetFramePointerRegisterNumber())
2682             context.type = EmulateInstruction::eContextSetFramePointer;
2683         else
2684             context.type = EmulateInstruction::eContextRegisterPlusOffset;
2685 
2686         RegisterInfo dwarf_reg;
2687         GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
2688         context.SetRegisterPlusOffset (dwarf_reg, imm32);
2689 
2690         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2691             return false;
2692     }
2693     return true;
2694 }
2695 
2696 // This instruction adds a register value and an optionally-shifted register value, and writes the result
2697 // to the destination register. It can optionally update the condition flags based on the result.
2698 bool
2699 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding)
2700 {
2701 #if 0
2702     // ARM pseudo code...
2703     if ConditionPassed() then
2704         EncodingSpecificOperations();
2705         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2706         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2707         if d == 15 then
2708             ALUWritePC(result); // setflags is always FALSE here
2709         else
2710             R[d] = result;
2711             if setflags then
2712                 APSR.N = result<31>;
2713                 APSR.Z = IsZeroBit(result);
2714                 APSR.C = carry;
2715                 APSR.V = overflow;
2716 #endif
2717 
2718     bool success = false;
2719 
2720     if (ConditionPassed(opcode))
2721     {
2722         uint32_t Rd, Rn, Rm;
2723         ARM_ShifterType shift_t;
2724         uint32_t shift_n; // the shift applied to the value read from Rm
2725         bool setflags;
2726         switch (encoding)
2727         {
2728         case eEncodingT1:
2729             Rd = Bits32(opcode, 2, 0);
2730             Rn = Bits32(opcode, 5, 3);
2731             Rm = Bits32(opcode, 8, 6);
2732             setflags = !InITBlock();
2733             shift_t = SRType_LSL;
2734             shift_n = 0;
2735             break;
2736         case eEncodingT2:
2737             Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2738             Rm = Bits32(opcode, 6, 3);
2739             setflags = false;
2740             shift_t = SRType_LSL;
2741             shift_n = 0;
2742             if (Rn == 15 && Rm == 15)
2743                 return false;
2744             if (Rd == 15 && InITBlock() && !LastInITBlock())
2745                 return false;
2746             break;
2747         case eEncodingA1:
2748             Rd = Bits32(opcode, 15, 12);
2749             Rn = Bits32(opcode, 19, 16);
2750             Rm = Bits32(opcode, 3, 0);
2751             setflags = BitIsSet(opcode, 20);
2752             shift_n = DecodeImmShiftARM(opcode, shift_t);
2753             break;
2754         default:
2755             return false;
2756         }
2757 
2758         // Read the first operand.
2759         uint32_t val1 = ReadCoreReg(Rn, &success);
2760         if (!success)
2761             return false;
2762 
2763         // Read the second operand.
2764         uint32_t val2 = ReadCoreReg(Rm, &success);
2765         if (!success)
2766             return false;
2767 
2768         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2769         if (!success)
2770             return false;
2771         AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2772 
2773         EmulateInstruction::Context context;
2774         context.type = eContextArithmetic;
2775         RegisterInfo op1_reg;
2776         RegisterInfo op2_reg;
2777         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
2778         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
2779         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
2780 
2781         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2782             return false;
2783     }
2784     return true;
2785 }
2786 
2787 // Compare Negative (immediate) adds a register value and an immediate value.
2788 // It updates the condition flags based on the result, and discards the result.
2789 bool
2790 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding)
2791 {
2792 #if 0
2793     // ARM pseudo code...
2794     if ConditionPassed() then
2795         EncodingSpecificOperations();
2796         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2797         APSR.N = result<31>;
2798         APSR.Z = IsZeroBit(result);
2799         APSR.C = carry;
2800         APSR.V = overflow;
2801 #endif
2802 
2803     bool success = false;
2804 
2805     uint32_t Rn; // the first operand
2806     uint32_t imm32; // the immediate value to be compared with
2807     switch (encoding) {
2808     case eEncodingT1:
2809         Rn = Bits32(opcode, 19, 16);
2810         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2811         if (Rn == 15)
2812             return false;
2813         break;
2814     case eEncodingA1:
2815         Rn = Bits32(opcode, 19, 16);
2816         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2817         break;
2818     default:
2819         return false;
2820     }
2821     // Read the register value from the operand register Rn.
2822     uint32_t reg_val = ReadCoreReg(Rn, &success);
2823     if (!success)
2824         return false;
2825 
2826     AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
2827 
2828     EmulateInstruction::Context context;
2829     context.type = EmulateInstruction::eContextImmediate;
2830     context.SetNoArgs ();
2831     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2832         return false;
2833 
2834     return true;
2835 }
2836 
2837 // Compare Negative (register) adds a register value and an optionally-shifted register value.
2838 // It updates the condition flags based on the result, and discards the result.
2839 bool
2840 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding)
2841 {
2842 #if 0
2843     // ARM pseudo code...
2844     if ConditionPassed() then
2845         EncodingSpecificOperations();
2846         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2847         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2848         APSR.N = result<31>;
2849         APSR.Z = IsZeroBit(result);
2850         APSR.C = carry;
2851         APSR.V = overflow;
2852 #endif
2853 
2854     bool success = false;
2855 
2856     uint32_t Rn; // the first operand
2857     uint32_t Rm; // the second operand
2858     ARM_ShifterType shift_t;
2859     uint32_t shift_n; // the shift applied to the value read from Rm
2860     switch (encoding) {
2861     case eEncodingT1:
2862         Rn = Bits32(opcode, 2, 0);
2863         Rm = Bits32(opcode, 5, 3);
2864         shift_t = SRType_LSL;
2865         shift_n = 0;
2866         break;
2867     case eEncodingT2:
2868         Rn = Bits32(opcode, 19, 16);
2869         Rm = Bits32(opcode, 3, 0);
2870         shift_n = DecodeImmShiftThumb(opcode, shift_t);
2871         // if n == 15 || BadReg(m) then UNPREDICTABLE;
2872         if (Rn == 15 || BadReg(Rm))
2873             return false;
2874         break;
2875     case eEncodingA1:
2876         Rn = Bits32(opcode, 19, 16);
2877         Rm = Bits32(opcode, 3, 0);
2878         shift_n = DecodeImmShiftARM(opcode, shift_t);
2879         break;
2880     default:
2881         return false;
2882     }
2883     // Read the register value from register Rn.
2884     uint32_t val1 = ReadCoreReg(Rn, &success);
2885     if (!success)
2886         return false;
2887 
2888     // Read the register value from register Rm.
2889     uint32_t val2 = ReadCoreReg(Rm, &success);
2890     if (!success)
2891         return false;
2892 
2893     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2894     if (!success)
2895         return false;
2896     AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2897 
2898     EmulateInstruction::Context context;
2899     context.type = EmulateInstruction::eContextImmediate;
2900     context.SetNoArgs();
2901     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2902         return false;
2903 
2904     return true;
2905 }
2906 
2907 // Compare (immediate) subtracts an immediate value from a register value.
2908 // It updates the condition flags based on the result, and discards the result.
2909 bool
2910 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding)
2911 {
2912 #if 0
2913     // ARM pseudo code...
2914     if ConditionPassed() then
2915         EncodingSpecificOperations();
2916         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2917         APSR.N = result<31>;
2918         APSR.Z = IsZeroBit(result);
2919         APSR.C = carry;
2920         APSR.V = overflow;
2921 #endif
2922 
2923     bool success = false;
2924 
2925     uint32_t Rn; // the first operand
2926     uint32_t imm32; // the immediate value to be compared with
2927     switch (encoding) {
2928     case eEncodingT1:
2929         Rn = Bits32(opcode, 10, 8);
2930         imm32 = Bits32(opcode, 7, 0);
2931         break;
2932     case eEncodingT2:
2933         Rn = Bits32(opcode, 19, 16);
2934         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2935         if (Rn == 15)
2936             return false;
2937         break;
2938     case eEncodingA1:
2939         Rn = Bits32(opcode, 19, 16);
2940         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2941         break;
2942     default:
2943         return false;
2944     }
2945     // Read the register value from the operand register Rn.
2946     uint32_t reg_val = ReadCoreReg(Rn, &success);
2947     if (!success)
2948         return false;
2949 
2950     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
2951 
2952     EmulateInstruction::Context context;
2953     context.type = EmulateInstruction::eContextImmediate;
2954     context.SetNoArgs ();
2955     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2956         return false;
2957 
2958     return true;
2959 }
2960 
2961 // Compare (register) subtracts an optionally-shifted register value from a register value.
2962 // It updates the condition flags based on the result, and discards the result.
2963 bool
2964 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding)
2965 {
2966 #if 0
2967     // ARM pseudo code...
2968     if ConditionPassed() then
2969         EncodingSpecificOperations();
2970         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2971         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2972         APSR.N = result<31>;
2973         APSR.Z = IsZeroBit(result);
2974         APSR.C = carry;
2975         APSR.V = overflow;
2976 #endif
2977 
2978     bool success = false;
2979 
2980     uint32_t Rn; // the first operand
2981     uint32_t Rm; // the second operand
2982     ARM_ShifterType shift_t;
2983     uint32_t shift_n; // the shift applied to the value read from Rm
2984     switch (encoding) {
2985     case eEncodingT1:
2986         Rn = Bits32(opcode, 2, 0);
2987         Rm = Bits32(opcode, 5, 3);
2988         shift_t = SRType_LSL;
2989         shift_n = 0;
2990         break;
2991     case eEncodingT2:
2992         Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2993         Rm = Bits32(opcode, 6, 3);
2994         shift_t = SRType_LSL;
2995         shift_n = 0;
2996         if (Rn < 8 && Rm < 8)
2997             return false;
2998         if (Rn == 15 || Rm == 15)
2999             return false;
3000         break;
3001     case eEncodingT3:
3002         Rn = Bits32(opcode, 19, 16);
3003         Rm = Bits32(opcode, 3, 0);
3004         shift_n = DecodeImmShiftThumb(opcode, shift_t);
3005         if (Rn == 15 || BadReg(Rm))
3006             return false;
3007         break;
3008     case eEncodingA1:
3009         Rn = Bits32(opcode, 19, 16);
3010         Rm = Bits32(opcode, 3, 0);
3011         shift_n = DecodeImmShiftARM(opcode, shift_t);
3012         break;
3013     default:
3014         return false;
3015     }
3016     // Read the register value from register Rn.
3017     uint32_t val1 = ReadCoreReg(Rn, &success);
3018     if (!success)
3019         return false;
3020 
3021     // Read the register value from register Rm.
3022     uint32_t val2 = ReadCoreReg(Rm, &success);
3023     if (!success)
3024         return false;
3025 
3026     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3027     if (!success)
3028         return false;
3029     AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
3030 
3031     EmulateInstruction::Context context;
3032     context.type = EmulateInstruction::eContextImmediate;
3033     context.SetNoArgs();
3034     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
3035         return false;
3036 
3037     return true;
3038 }
3039 
3040 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
3041 // shifting in copies of its sign bit, and writes the result to the destination register.  It can
3042 // optionally update the condition flags based on the result.
3043 bool
3044 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding)
3045 {
3046 #if 0
3047     // ARM pseudo code...
3048     if ConditionPassed() then
3049         EncodingSpecificOperations();
3050         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3051         if d == 15 then         // Can only occur for ARM encoding
3052             ALUWritePC(result); // setflags is always FALSE here
3053         else
3054             R[d] = result;
3055             if setflags then
3056                 APSR.N = result<31>;
3057                 APSR.Z = IsZeroBit(result);
3058                 APSR.C = carry;
3059                 // APSR.V unchanged
3060 #endif
3061 
3062     return EmulateShiftImm (opcode, encoding, SRType_ASR);
3063 }
3064 
3065 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
3066 // shifting in copies of its sign bit, and writes the result to the destination register.
3067 // The variable number of bits is read from the bottom byte of a register. It can optionally update
3068 // the condition flags based on the result.
3069 bool
3070 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding)
3071 {
3072 #if 0
3073     // ARM pseudo code...
3074     if ConditionPassed() then
3075         EncodingSpecificOperations();
3076         shift_n = UInt(R[m]<7:0>);
3077         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3078         R[d] = result;
3079         if setflags then
3080             APSR.N = result<31>;
3081             APSR.Z = IsZeroBit(result);
3082             APSR.C = carry;
3083             // APSR.V unchanged
3084 #endif
3085 
3086     return EmulateShiftReg (opcode, encoding, SRType_ASR);
3087 }
3088 
3089 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
3090 // shifting in zeros, and writes the result to the destination register.  It can optionally
3091 // update the condition flags based on the result.
3092 bool
3093 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding)
3094 {
3095 #if 0
3096     // ARM pseudo code...
3097     if ConditionPassed() then
3098         EncodingSpecificOperations();
3099         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3100         if d == 15 then         // Can only occur for ARM encoding
3101             ALUWritePC(result); // setflags is always FALSE here
3102         else
3103             R[d] = result;
3104             if setflags then
3105                 APSR.N = result<31>;
3106                 APSR.Z = IsZeroBit(result);
3107                 APSR.C = carry;
3108                 // APSR.V unchanged
3109 #endif
3110 
3111     return EmulateShiftImm (opcode, encoding, SRType_LSL);
3112 }
3113 
3114 // Logical Shift Left (register) shifts a register value left by a variable number of bits,
3115 // shifting in zeros, and writes the result to the destination register.  The variable number
3116 // of bits is read from the bottom byte of a register. It can optionally update the condition
3117 // flags based on the result.
3118 bool
3119 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding)
3120 {
3121 #if 0
3122     // ARM pseudo code...
3123     if ConditionPassed() then
3124         EncodingSpecificOperations();
3125         shift_n = UInt(R[m]<7:0>);
3126         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3127         R[d] = result;
3128         if setflags then
3129             APSR.N = result<31>;
3130             APSR.Z = IsZeroBit(result);
3131             APSR.C = carry;
3132             // APSR.V unchanged
3133 #endif
3134 
3135     return EmulateShiftReg (opcode, encoding, SRType_LSL);
3136 }
3137 
3138 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
3139 // shifting in zeros, and writes the result to the destination register.  It can optionally
3140 // update the condition flags based on the result.
3141 bool
3142 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding)
3143 {
3144 #if 0
3145     // ARM pseudo code...
3146     if ConditionPassed() then
3147         EncodingSpecificOperations();
3148         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3149         if d == 15 then         // Can only occur for ARM encoding
3150             ALUWritePC(result); // setflags is always FALSE here
3151         else
3152             R[d] = result;
3153             if setflags then
3154                 APSR.N = result<31>;
3155                 APSR.Z = IsZeroBit(result);
3156                 APSR.C = carry;
3157                 // APSR.V unchanged
3158 #endif
3159 
3160     return EmulateShiftImm (opcode, encoding, SRType_LSR);
3161 }
3162 
3163 // Logical Shift Right (register) shifts a register value right by a variable number of bits,
3164 // shifting in zeros, and writes the result to the destination register.  The variable number
3165 // of bits is read from the bottom byte of a register. It can optionally update the condition
3166 // flags based on the result.
3167 bool
3168 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding)
3169 {
3170 #if 0
3171     // ARM pseudo code...
3172     if ConditionPassed() then
3173         EncodingSpecificOperations();
3174         shift_n = UInt(R[m]<7:0>);
3175         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3176         R[d] = result;
3177         if setflags then
3178             APSR.N = result<31>;
3179             APSR.Z = IsZeroBit(result);
3180             APSR.C = carry;
3181             // APSR.V unchanged
3182 #endif
3183 
3184     return EmulateShiftReg (opcode, encoding, SRType_LSR);
3185 }
3186 
3187 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
3188 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3189 // It can optionally update the condition flags based on the result.
3190 bool
3191 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding)
3192 {
3193 #if 0
3194     // ARM pseudo code...
3195     if ConditionPassed() then
3196         EncodingSpecificOperations();
3197         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3198         if d == 15 then         // Can only occur for ARM encoding
3199             ALUWritePC(result); // setflags is always FALSE here
3200         else
3201             R[d] = result;
3202             if setflags then
3203                 APSR.N = result<31>;
3204                 APSR.Z = IsZeroBit(result);
3205                 APSR.C = carry;
3206                 // APSR.V unchanged
3207 #endif
3208 
3209     return EmulateShiftImm (opcode, encoding, SRType_ROR);
3210 }
3211 
3212 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
3213 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3214 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
3215 // flags based on the result.
3216 bool
3217 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding)
3218 {
3219 #if 0
3220     // ARM pseudo code...
3221     if ConditionPassed() then
3222         EncodingSpecificOperations();
3223         shift_n = UInt(R[m]<7:0>);
3224         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3225         R[d] = result;
3226         if setflags then
3227             APSR.N = result<31>;
3228             APSR.Z = IsZeroBit(result);
3229             APSR.C = carry;
3230             // APSR.V unchanged
3231 #endif
3232 
3233     return EmulateShiftReg (opcode, encoding, SRType_ROR);
3234 }
3235 
3236 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
3237 // with the carry flag shifted into bit [31].
3238 //
3239 // RRX can optionally update the condition flags based on the result.
3240 // In that case, bit [0] is shifted into the carry flag.
3241 bool
3242 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding)
3243 {
3244 #if 0
3245     // ARM pseudo code...
3246     if ConditionPassed() then
3247         EncodingSpecificOperations();
3248         (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3249         if d == 15 then         // Can only occur for ARM encoding
3250             ALUWritePC(result); // setflags is always FALSE here
3251         else
3252             R[d] = result;
3253             if setflags then
3254                 APSR.N = result<31>;
3255                 APSR.Z = IsZeroBit(result);
3256                 APSR.C = carry;
3257                 // APSR.V unchanged
3258 #endif
3259 
3260     return EmulateShiftImm (opcode, encoding, SRType_RRX);
3261 }
3262 
3263 bool
3264 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3265 {
3266 //    assert(shift_type == SRType_ASR
3267 //           || shift_type == SRType_LSL
3268 //           || shift_type == SRType_LSR
3269 //           || shift_type == SRType_ROR
3270 //           || shift_type == SRType_RRX);
3271 
3272     bool success = false;
3273 
3274     if (ConditionPassed(opcode))
3275     {
3276         uint32_t Rd;    // the destination register
3277         uint32_t Rm;    // the first operand register
3278         uint32_t imm5;  // encoding for the shift amount
3279         uint32_t carry; // the carry bit after the shift operation
3280         bool setflags;
3281 
3282         // Special case handling!
3283         // A8.6.139 ROR (immediate) -- Encoding T1
3284         ARMEncoding use_encoding = encoding;
3285         if (shift_type == SRType_ROR && use_encoding == eEncodingT1)
3286         {
3287             // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
3288             // have the same decoding of bit fields as the other Thumb2 shift operations.
3289             use_encoding = eEncodingT2;
3290         }
3291 
3292         switch (use_encoding) {
3293         case eEncodingT1:
3294             // Due to the above special case handling!
3295             if (shift_type == SRType_ROR)
3296                 return false;
3297 
3298             Rd = Bits32(opcode, 2, 0);
3299             Rm = Bits32(opcode, 5, 3);
3300             setflags = !InITBlock();
3301             imm5 = Bits32(opcode, 10, 6);
3302             break;
3303         case eEncodingT2:
3304             // A8.6.141 RRX
3305             // There's no imm form of RRX instructions.
3306             if (shift_type == SRType_RRX)
3307                 return false;
3308 
3309             Rd = Bits32(opcode, 11, 8);
3310             Rm = Bits32(opcode, 3, 0);
3311             setflags = BitIsSet(opcode, 20);
3312             imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3313             if (BadReg(Rd) || BadReg(Rm))
3314                 return false;
3315             break;
3316         case eEncodingA1:
3317             Rd = Bits32(opcode, 15, 12);
3318             Rm = Bits32(opcode, 3, 0);
3319             setflags = BitIsSet(opcode, 20);
3320             imm5 = Bits32(opcode, 11, 7);
3321             break;
3322         default:
3323             return false;
3324         }
3325 
3326         // A8.6.139 ROR (immediate)
3327         if (shift_type == SRType_ROR && imm5 == 0)
3328             shift_type = SRType_RRX;
3329 
3330         // Get the first operand.
3331         uint32_t value = ReadCoreReg (Rm, &success);
3332         if (!success)
3333             return false;
3334 
3335         // Decode the shift amount if not RRX.
3336         uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3337 
3338         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3339         if (!success)
3340             return false;
3341 
3342         // The context specifies that an immediate is to be moved into Rd.
3343         EmulateInstruction::Context context;
3344         context.type = EmulateInstruction::eContextImmediate;
3345         context.SetNoArgs ();
3346 
3347         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3348             return false;
3349     }
3350     return true;
3351 }
3352 
3353 bool
3354 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3355 {
3356     // assert(shift_type == SRType_ASR
3357     //        || shift_type == SRType_LSL
3358     //        || shift_type == SRType_LSR
3359     //        || shift_type == SRType_ROR);
3360 
3361     bool success = false;
3362 
3363     if (ConditionPassed(opcode))
3364     {
3365         uint32_t Rd;    // the destination register
3366         uint32_t Rn;    // the first operand register
3367         uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
3368         uint32_t carry; // the carry bit after the shift operation
3369         bool setflags;
3370         switch (encoding) {
3371         case eEncodingT1:
3372             Rd = Bits32(opcode, 2, 0);
3373             Rn = Rd;
3374             Rm = Bits32(opcode, 5, 3);
3375             setflags = !InITBlock();
3376             break;
3377         case eEncodingT2:
3378             Rd = Bits32(opcode, 11, 8);
3379             Rn = Bits32(opcode, 19, 16);
3380             Rm = Bits32(opcode, 3, 0);
3381             setflags = BitIsSet(opcode, 20);
3382             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3383                 return false;
3384             break;
3385         case eEncodingA1:
3386             Rd = Bits32(opcode, 15, 12);
3387             Rn = Bits32(opcode, 3, 0);
3388             Rm = Bits32(opcode, 11, 8);
3389             setflags = BitIsSet(opcode, 20);
3390             if (Rd == 15 || Rn == 15 || Rm == 15)
3391                 return false;
3392             break;
3393         default:
3394             return false;
3395         }
3396 
3397         // Get the first operand.
3398         uint32_t value = ReadCoreReg (Rn, &success);
3399         if (!success)
3400             return false;
3401         // Get the Rm register content.
3402         uint32_t val = ReadCoreReg (Rm, &success);
3403         if (!success)
3404             return false;
3405 
3406         // Get the shift amount.
3407         uint32_t amt = Bits32(val, 7, 0);
3408 
3409         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3410         if (!success)
3411             return false;
3412 
3413         // The context specifies that an immediate is to be moved into Rd.
3414         EmulateInstruction::Context context;
3415         context.type = EmulateInstruction::eContextImmediate;
3416         context.SetNoArgs ();
3417 
3418         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3419             return false;
3420     }
3421     return true;
3422 }
3423 
3424 // LDM loads multiple registers from consecutive memory locations, using an
3425 // address from a base register.  Optionally the address just above the highest of those locations
3426 // can be written back to the base register.
3427 bool
3428 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding)
3429 {
3430 #if 0
3431     // ARM pseudo code...
3432     if ConditionPassed()
3433         EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3434         address = R[n];
3435 
3436         for i = 0 to 14
3437             if registers<i> == '1' then
3438                 R[i] = MemA[address, 4]; address = address + 4;
3439         if registers<15> == '1' then
3440             LoadWritePC (MemA[address, 4]);
3441 
3442         if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3443         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3444 
3445 #endif
3446 
3447     bool success = false;
3448     if (ConditionPassed(opcode))
3449     {
3450         uint32_t n;
3451         uint32_t registers = 0;
3452         bool wback;
3453         const uint32_t addr_byte_size = GetAddressByteSize();
3454         switch (encoding)
3455         {
3456             case eEncodingT1:
3457                 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0');
3458                 n = Bits32 (opcode, 10, 8);
3459                 registers = Bits32 (opcode, 7, 0);
3460                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3461                 wback = BitIsClear (registers, n);
3462                 // if BitCount(registers) < 1 then UNPREDICTABLE;
3463                 if (BitCount(registers) < 1)
3464                     return false;
3465                 break;
3466             case eEncodingT2:
3467                 // if W == '1' && Rn == '1101' then SEE POP;
3468                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3469                 n = Bits32 (opcode, 19, 16);
3470                 registers = Bits32 (opcode, 15, 0);
3471                 registers = registers & 0xdfff; // Make sure bit 13 is zero.
3472                 wback = BitIsSet (opcode, 21);
3473 
3474                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3475                 if ((n == 15)
3476                     || (BitCount (registers) < 2)
3477                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3478                     return false;
3479 
3480                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3481                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3482                     return false;
3483 
3484                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3485                 if (wback
3486                     && BitIsSet (registers, n))
3487                     return false;
3488                 break;
3489 
3490             case eEncodingA1:
3491                 n = Bits32 (opcode, 19, 16);
3492                 registers = Bits32 (opcode, 15, 0);
3493                 wback = BitIsSet (opcode, 21);
3494                 if ((n == 15)
3495                     || (BitCount (registers) < 1))
3496                     return false;
3497                 break;
3498             default:
3499                 return false;
3500         }
3501 
3502         int32_t offset = 0;
3503         const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3504         if (!success)
3505             return false;
3506 
3507         EmulateInstruction::Context context;
3508         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3509         RegisterInfo dwarf_reg;
3510         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3511         context.SetRegisterPlusOffset (dwarf_reg, offset);
3512 
3513         for (int i = 0; i < 14; ++i)
3514         {
3515             if (BitIsSet (registers, i))
3516             {
3517                 context.type = EmulateInstruction::eContextRegisterPlusOffset;
3518                 context.SetRegisterPlusOffset (dwarf_reg, offset);
3519                 if (wback && (n == 13)) // Pop Instruction
3520                 {
3521                     context.type = EmulateInstruction::eContextPopRegisterOffStack;
3522                     context.SetAddress(base_address + offset);
3523                 }
3524 
3525                 // R[i] = MemA [address, 4]; address = address + 4;
3526                 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3527                 if (!success)
3528                     return false;
3529 
3530                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3531                     return false;
3532 
3533                 offset += addr_byte_size;
3534             }
3535         }
3536 
3537         if (BitIsSet (registers, 15))
3538         {
3539             //LoadWritePC (MemA [address, 4]);
3540             context.type = EmulateInstruction::eContextRegisterPlusOffset;
3541             context.SetRegisterPlusOffset (dwarf_reg, offset);
3542             uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3543             if (!success)
3544                 return false;
3545             // In ARMv5T and above, this is an interworking branch.
3546             if (!LoadWritePC(context, data))
3547                 return false;
3548         }
3549 
3550         if (wback && BitIsClear (registers, n))
3551         {
3552             // R[n] = R[n] + 4 * BitCount (registers)
3553             int32_t offset = addr_byte_size * BitCount (registers);
3554             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3555             context.SetRegisterPlusOffset (dwarf_reg, offset);
3556 
3557             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
3558                 return false;
3559         }
3560         if (wback && BitIsSet (registers, n))
3561             // R[n] bits(32) UNKNOWN;
3562             return WriteBits32Unknown (n);
3563     }
3564     return true;
3565 }
3566 
3567 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register.
3568 // The consecutive memory locations end at this address and the address just below the lowest of those locations
3569 // can optionally be written back to the base register.
3570 bool
3571 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding)
3572 {
3573 #if 0
3574     // ARM pseudo code...
3575     if ConditionPassed() then
3576         EncodingSpecificOperations();
3577         address = R[n] - 4*BitCount(registers) + 4;
3578 
3579         for i = 0 to 14
3580             if registers<i> == '1' then
3581                   R[i] = MemA[address,4]; address = address + 4;
3582 
3583         if registers<15> == '1' then
3584             LoadWritePC(MemA[address,4]);
3585 
3586         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3587         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3588 #endif
3589 
3590     bool success = false;
3591 
3592     if (ConditionPassed(opcode))
3593     {
3594         uint32_t n;
3595         uint32_t registers = 0;
3596         bool wback;
3597         const uint32_t addr_byte_size = GetAddressByteSize();
3598 
3599         // EncodingSpecificOperations();
3600         switch (encoding)
3601         {
3602             case eEncodingA1:
3603                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3604                 n = Bits32 (opcode, 19, 16);
3605                 registers = Bits32 (opcode, 15, 0);
3606                 wback = BitIsSet (opcode, 21);
3607 
3608                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3609                 if ((n == 15) || (BitCount (registers) < 1))
3610                     return false;
3611 
3612                 break;
3613 
3614             default:
3615                 return false;
3616         }
3617         // address = R[n] - 4*BitCount(registers) + 4;
3618 
3619         int32_t offset = 0;
3620         addr_t Rn = ReadCoreReg (n, &success);
3621 
3622         if (!success)
3623             return false;
3624 
3625         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size;
3626 
3627         EmulateInstruction::Context context;
3628         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3629         RegisterInfo dwarf_reg;
3630         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3631         context.SetRegisterPlusOffset (dwarf_reg, offset);
3632 
3633         // for i = 0 to 14
3634         for (int i = 0; i < 14; ++i)
3635         {
3636             // if registers<i> == '1' then
3637             if (BitIsSet (registers, i))
3638             {
3639                   // R[i] = MemA[address,4]; address = address + 4;
3640                   context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3641                   uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3642                   if (!success)
3643                       return false;
3644                   if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3645                       return false;
3646                   offset += addr_byte_size;
3647             }
3648         }
3649 
3650         // if registers<15> == '1' then
3651         //     LoadWritePC(MemA[address,4]);
3652         if (BitIsSet (registers, 15))
3653         {
3654             context.SetRegisterPlusOffset (dwarf_reg, offset);
3655             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3656             if (!success)
3657                 return false;
3658             // In ARMv5T and above, this is an interworking branch.
3659             if (!LoadWritePC(context, data))
3660                 return false;
3661         }
3662 
3663         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3664         if (wback && BitIsClear (registers, n))
3665         {
3666             if (!success)
3667                 return false;
3668 
3669             offset = (addr_byte_size * BitCount (registers)) * -1;
3670             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3671             context.SetImmediateSigned (offset);
3672             addr_t addr = Rn + offset;
3673             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3674                 return false;
3675         }
3676 
3677         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3678         if (wback && BitIsSet (registers, n))
3679             return WriteBits32Unknown (n);
3680     }
3681     return true;
3682 }
3683 
3684 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
3685 // consecutive memory locations end just below this address, and the address of the lowest of those locations can
3686 // be optionally written back to the base register.
3687 bool
3688 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding)
3689 {
3690 #if 0
3691     // ARM pseudo code...
3692     if ConditionPassed() then
3693         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3694         address = R[n] - 4*BitCount(registers);
3695 
3696         for i = 0 to 14
3697             if registers<i> == '1' then
3698                   R[i] = MemA[address,4]; address = address + 4;
3699         if registers<15> == '1' then
3700                   LoadWritePC(MemA[address,4]);
3701 
3702         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3703         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3704 #endif
3705 
3706     bool success = false;
3707 
3708     if (ConditionPassed(opcode))
3709     {
3710         uint32_t n;
3711         uint32_t registers = 0;
3712         bool wback;
3713         const uint32_t addr_byte_size = GetAddressByteSize();
3714         switch (encoding)
3715         {
3716             case eEncodingT1:
3717                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3718                 n = Bits32 (opcode, 19, 16);
3719                 registers = Bits32 (opcode, 15, 0);
3720                 registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
3721                 wback = BitIsSet (opcode, 21);
3722 
3723                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3724                 if ((n == 15)
3725                     || (BitCount (registers) < 2)
3726                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3727                     return false;
3728 
3729                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3730                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3731                     return false;
3732 
3733                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3734                 if (wback && BitIsSet (registers, n))
3735                     return false;
3736 
3737                 break;
3738 
3739             case eEncodingA1:
3740                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3741                 n = Bits32 (opcode, 19, 16);
3742                 registers = Bits32 (opcode, 15, 0);
3743                 wback = BitIsSet (opcode, 21);
3744 
3745                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3746                 if ((n == 15) || (BitCount (registers) < 1))
3747                     return false;
3748 
3749                 break;
3750 
3751             default:
3752                 return false;
3753         }
3754 
3755         // address = R[n] - 4*BitCount(registers);
3756 
3757         int32_t offset = 0;
3758         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3759 
3760         if (!success)
3761             return false;
3762 
3763         addr_t address = Rn - (addr_byte_size * BitCount (registers));
3764         EmulateInstruction::Context context;
3765         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3766         RegisterInfo dwarf_reg;
3767         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3768         context.SetRegisterPlusOffset (dwarf_reg, Rn - address);
3769 
3770         for (int i = 0; i < 14; ++i)
3771         {
3772             if (BitIsSet (registers, i))
3773             {
3774                 // R[i] = MemA[address,4]; address = address + 4;
3775                 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3776                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3777                 if (!success)
3778                     return false;
3779 
3780                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3781                     return false;
3782 
3783                 offset += addr_byte_size;
3784             }
3785         }
3786 
3787         // if registers<15> == '1' then
3788         //     LoadWritePC(MemA[address,4]);
3789         if (BitIsSet (registers, 15))
3790         {
3791             context.SetRegisterPlusOffset (dwarf_reg, offset);
3792             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3793             if (!success)
3794                 return false;
3795             // In ARMv5T and above, this is an interworking branch.
3796             if (!LoadWritePC(context, data))
3797                 return false;
3798         }
3799 
3800         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3801         if (wback && BitIsClear (registers, n))
3802         {
3803             if (!success)
3804                 return false;
3805 
3806             offset = (addr_byte_size * BitCount (registers)) * -1;
3807             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3808             context.SetImmediateSigned (offset);
3809             addr_t addr = Rn + offset;
3810             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3811                 return false;
3812         }
3813 
3814         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3815         if (wback && BitIsSet (registers, n))
3816             return WriteBits32Unknown (n);
3817     }
3818     return true;
3819 }
3820 
3821 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
3822 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can
3823 // optinoally be written back to the base register.
3824 bool
3825 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding)
3826 {
3827 #if 0
3828     if ConditionPassed() then
3829         EncodingSpecificOperations();
3830         address = R[n] + 4;
3831 
3832         for i = 0 to 14
3833             if registers<i> == '1' then
3834                   R[i] = MemA[address,4]; address = address + 4;
3835         if registers<15> == '1' then
3836             LoadWritePC(MemA[address,4]);
3837 
3838         if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3839         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3840 #endif
3841 
3842     bool success = false;
3843 
3844     if (ConditionPassed(opcode))
3845     {
3846         uint32_t n;
3847         uint32_t registers = 0;
3848         bool wback;
3849         const uint32_t addr_byte_size = GetAddressByteSize();
3850         switch (encoding)
3851         {
3852             case eEncodingA1:
3853                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3854                 n = Bits32 (opcode, 19, 16);
3855                 registers = Bits32 (opcode, 15, 0);
3856                 wback = BitIsSet (opcode, 21);
3857 
3858                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3859                 if ((n == 15) || (BitCount (registers) < 1))
3860                     return false;
3861 
3862                 break;
3863             default:
3864                 return false;
3865         }
3866         // address = R[n] + 4;
3867 
3868         int32_t offset = 0;
3869         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3870 
3871         if (!success)
3872             return false;
3873 
3874         addr_t address = Rn + addr_byte_size;
3875 
3876         EmulateInstruction::Context context;
3877         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3878         RegisterInfo dwarf_reg;
3879         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3880         context.SetRegisterPlusOffset (dwarf_reg, offset);
3881 
3882         for (int i = 0; i < 14; ++i)
3883         {
3884             if (BitIsSet (registers, i))
3885             {
3886                 // R[i] = MemA[address,4]; address = address + 4;
3887 
3888                 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size);
3889                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3890                 if (!success)
3891                     return false;
3892 
3893                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3894                     return false;
3895 
3896                 offset += addr_byte_size;
3897             }
3898         }
3899 
3900         // if registers<15> == '1' then
3901         //     LoadWritePC(MemA[address,4]);
3902         if (BitIsSet (registers, 15))
3903         {
3904             context.SetRegisterPlusOffset (dwarf_reg, offset);
3905             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3906             if (!success)
3907                 return false;
3908             // In ARMv5T and above, this is an interworking branch.
3909             if (!LoadWritePC(context, data))
3910                 return false;
3911         }
3912 
3913         // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3914         if (wback && BitIsClear (registers, n))
3915         {
3916             if (!success)
3917                 return false;
3918 
3919             offset = addr_byte_size * BitCount (registers);
3920             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3921             context.SetImmediateSigned (offset);
3922             addr_t addr = Rn + offset;
3923             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3924                 return false;
3925         }
3926 
3927         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3928         if (wback && BitIsSet (registers, n))
3929             return WriteBits32Unknown (n);
3930     }
3931     return true;
3932 }
3933 
3934 // Load Register (immediate) calculates an address from a base register value and
3935 // an immediate offset, loads a word from memory, and writes to a register.
3936 // LDR (immediate, Thumb)
3937 bool
3938 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding)
3939 {
3940 #if 0
3941     // ARM pseudo code...
3942     if (ConditionPassed())
3943     {
3944         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3945         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3946         address = if index then offset_addr else R[n];
3947         data = MemU[address,4];
3948         if wback then R[n] = offset_addr;
3949         if t == 15 then
3950             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3951         elsif UnalignedSupport() || address<1:0> = '00' then
3952             R[t] = data;
3953         else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3954     }
3955 #endif
3956 
3957     bool success = false;
3958 
3959     if (ConditionPassed(opcode))
3960     {
3961         uint32_t Rt; // the destination register
3962         uint32_t Rn; // the base register
3963         uint32_t imm32; // the immediate offset used to form the address
3964         addr_t offset_addr; // the offset address
3965         addr_t address; // the calculated address
3966         uint32_t data; // the literal data value from memory load
3967         bool add, index, wback;
3968         switch (encoding) {
3969             case eEncodingT1:
3970                 Rt = Bits32(opcode, 2, 0);
3971                 Rn = Bits32(opcode, 5, 3);
3972                 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3973                 // index = TRUE; add = TRUE; wback = FALSE
3974                 add = true;
3975                 index = true;
3976                 wback = false;
3977 
3978                 break;
3979 
3980             case eEncodingT2:
3981                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
3982                 Rt = Bits32 (opcode, 10, 8);
3983                 Rn = 13;
3984                 imm32 = Bits32 (opcode, 7, 0) << 2;
3985 
3986                 // index = TRUE; add = TRUE; wback = FALSE;
3987                 index = true;
3988                 add = true;
3989                 wback = false;
3990 
3991                 break;
3992 
3993             case eEncodingT3:
3994                 // if Rn == '1111' then SEE LDR (literal);
3995                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
3996                 Rt = Bits32 (opcode, 15, 12);
3997                 Rn = Bits32 (opcode, 19, 16);
3998                 imm32 = Bits32 (opcode, 11, 0);
3999 
4000                 // index = TRUE; add = TRUE; wback = FALSE;
4001                 index = true;
4002                 add = true;
4003                 wback = false;
4004 
4005                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
4006                 if ((Rt == 15) && InITBlock() && !LastInITBlock())
4007                     return false;
4008 
4009                 break;
4010 
4011             case eEncodingT4:
4012                 // if Rn == '1111' then SEE LDR (literal);
4013                 // if P == '1' && U == '1' && W == '0' then SEE LDRT;
4014                 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
4015                 // if P == '0' && W == '0' then UNDEFINED;
4016                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
4017                     return false;
4018 
4019                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4020                 Rt = Bits32 (opcode, 15, 12);
4021                 Rn = Bits32 (opcode, 19, 16);
4022                 imm32 = Bits32 (opcode, 7, 0);
4023 
4024                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4025                 index = BitIsSet (opcode, 10);
4026                 add = BitIsSet (opcode, 9);
4027                 wback = BitIsSet (opcode, 8);
4028 
4029                 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
4030                 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock()))
4031                     return false;
4032 
4033                 break;
4034 
4035             default:
4036                 return false;
4037         }
4038         uint32_t base = ReadCoreReg (Rn, &success);
4039         if (!success)
4040             return false;
4041         if (add)
4042             offset_addr = base + imm32;
4043         else
4044             offset_addr = base - imm32;
4045 
4046         address = (index ? offset_addr : base);
4047 
4048         RegisterInfo base_reg;
4049         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
4050         if (wback)
4051         {
4052             EmulateInstruction::Context ctx;
4053             if (Rn == 13)
4054             {
4055                 ctx.type = eContextAdjustStackPointer;
4056                 ctx.SetImmediateSigned((int32_t) (offset_addr - base));
4057             }
4058             else if (Rn == GetFramePointerRegisterNumber())
4059             {
4060                 ctx.type = eContextSetFramePointer;
4061                 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
4062             }
4063             else
4064             {
4065                 ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
4066                 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
4067             }
4068 
4069 
4070             if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
4071                 return false;
4072         }
4073 
4074         // Prepare to write to the Rt register.
4075         EmulateInstruction::Context context;
4076         context.type = EmulateInstruction::eContextRegisterLoad;
4077         context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
4078 
4079         // Read memory from the address.
4080         data = MemURead(context, address, 4, 0, &success);
4081         if (!success)
4082             return false;
4083 
4084         if (Rt == 15)
4085         {
4086             if (Bits32(address, 1, 0) == 0)
4087             {
4088                 if (!LoadWritePC(context, data))
4089                     return false;
4090             }
4091             else
4092                 return false;
4093         }
4094         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
4095         {
4096             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
4097                 return false;
4098         }
4099         else
4100             WriteBits32Unknown (Rt);
4101     }
4102     return true;
4103 }
4104 
4105 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
4106 // from a base register.  The consecutive memory locations start at this address, and the address just above the last
4107 // of those locations can optionally be written back to the base register.
4108 bool
4109 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding)
4110 {
4111 #if 0
4112     if ConditionPassed() then
4113         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4114         address = R[n];
4115 
4116         for i = 0 to 14
4117             if registers<i> == '1' then
4118                 if i == n && wback && i != LowestSetBit(registers) then
4119                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4120                 else
4121                     MemA[address,4] = R[i];
4122                 address = address + 4;
4123 
4124         if registers<15> == '1' then // Only possible for encoding A1
4125             MemA[address,4] = PCStoreValue();
4126         if wback then R[n] = R[n] + 4*BitCount(registers);
4127 #endif
4128 
4129     bool success = false;
4130 
4131     if (ConditionPassed(opcode))
4132     {
4133         uint32_t n;
4134         uint32_t registers = 0;
4135         bool wback;
4136         const uint32_t addr_byte_size = GetAddressByteSize();
4137 
4138         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4139         switch (encoding)
4140         {
4141             case eEncodingT1:
4142                 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4143                 n = Bits32 (opcode, 10, 8);
4144                 registers = Bits32 (opcode, 7, 0);
4145                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
4146                 wback = true;
4147 
4148                 // if BitCount(registers) < 1 then UNPREDICTABLE;
4149                 if (BitCount (registers) < 1)
4150                     return false;
4151 
4152                 break;
4153 
4154             case eEncodingT2:
4155                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4156                 n = Bits32 (opcode, 19, 16);
4157                 registers = Bits32 (opcode, 15, 0);
4158                 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4159                 wback = BitIsSet (opcode, 21);
4160 
4161                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4162                 if ((n == 15) || (BitCount (registers) < 2))
4163                     return false;
4164 
4165                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4166                 if (wback && BitIsSet (registers, n))
4167                     return false;
4168 
4169                 break;
4170 
4171             case eEncodingA1:
4172                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4173                 n = Bits32 (opcode, 19, 16);
4174                 registers = Bits32 (opcode, 15, 0);
4175                 wback = BitIsSet (opcode, 21);
4176 
4177                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4178                 if ((n == 15) || (BitCount (registers) < 1))
4179                     return false;
4180 
4181                 break;
4182 
4183             default:
4184                 return false;
4185         }
4186 
4187         // address = R[n];
4188         int32_t offset = 0;
4189         const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4190         if (!success)
4191             return false;
4192 
4193         EmulateInstruction::Context context;
4194         context.type = EmulateInstruction::eContextRegisterStore;
4195         RegisterInfo base_reg;
4196         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4197 
4198         // for i = 0 to 14
4199         uint32_t lowest_set_bit = 14;
4200         for (uint32_t i = 0; i < 14; ++i)
4201         {
4202             // if registers<i> == '1' then
4203             if (BitIsSet (registers, i))
4204             {
4205                   if (i < lowest_set_bit)
4206                       lowest_set_bit = i;
4207                   // if i == n && wback && i != LowestSetBit(registers) then
4208                   if ((i == n) && wback && (i != lowest_set_bit))
4209                       // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4210                       WriteBits32UnknownToMemory (address + offset);
4211                   else
4212                   {
4213                      // MemA[address,4] = R[i];
4214                       uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4215                       if (!success)
4216                           return false;
4217 
4218                       RegisterInfo data_reg;
4219                       GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4220                       context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4221                       if (!MemAWrite (context, address + offset, data, addr_byte_size))
4222                           return false;
4223                   }
4224 
4225                   // address = address + 4;
4226                   offset += addr_byte_size;
4227             }
4228         }
4229 
4230         // if registers<15> == '1' then // Only possible for encoding A1
4231         //     MemA[address,4] = PCStoreValue();
4232         if (BitIsSet (registers, 15))
4233         {
4234             RegisterInfo pc_reg;
4235             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4236             context.SetRegisterPlusOffset (pc_reg, 8);
4237             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4238             if (!success)
4239                 return false;
4240 
4241             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4242                 return false;
4243         }
4244 
4245         // if wback then R[n] = R[n] + 4*BitCount(registers);
4246         if (wback)
4247         {
4248             offset = addr_byte_size * BitCount (registers);
4249             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4250             context.SetImmediateSigned (offset);
4251             addr_t data = address + offset;
4252             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4253                 return false;
4254         }
4255     }
4256     return true;
4257 }
4258 
4259 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
4260 // from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
4261 // of those locations can optionally be written back to the base register.
4262 bool
4263 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding)
4264 {
4265 #if 0
4266     if ConditionPassed() then
4267         EncodingSpecificOperations();
4268         address = R[n] - 4*BitCount(registers) + 4;
4269 
4270         for i = 0 to 14
4271             if registers<i> == '1' then
4272                 if i == n && wback && i != LowestSetBit(registers) then
4273                     MemA[address,4] = bits(32) UNKNOWN;
4274                 else
4275                     MemA[address,4] = R[i];
4276                 address = address + 4;
4277 
4278         if registers<15> == '1' then
4279             MemA[address,4] = PCStoreValue();
4280 
4281         if wback then R[n] = R[n] - 4*BitCount(registers);
4282 #endif
4283 
4284     bool success = false;
4285 
4286     if (ConditionPassed(opcode))
4287     {
4288         uint32_t n;
4289         uint32_t registers = 0;
4290         bool wback;
4291         const uint32_t addr_byte_size = GetAddressByteSize();
4292 
4293         // EncodingSpecificOperations();
4294         switch (encoding)
4295         {
4296             case eEncodingA1:
4297                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4298                 n = Bits32 (opcode, 19, 16);
4299                 registers = Bits32 (opcode, 15, 0);
4300                 wback = BitIsSet (opcode, 21);
4301 
4302                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4303                 if ((n == 15) || (BitCount (registers) < 1))
4304                     return false;
4305                 break;
4306             default:
4307                 return false;
4308         }
4309 
4310         // address = R[n] - 4*BitCount(registers) + 4;
4311         int32_t offset = 0;
4312         addr_t Rn = ReadCoreReg (n, &success);
4313         if (!success)
4314             return false;
4315 
4316         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4;
4317 
4318         EmulateInstruction::Context context;
4319         context.type = EmulateInstruction::eContextRegisterStore;
4320         RegisterInfo base_reg;
4321         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4322 
4323         // for i = 0 to 14
4324         uint32_t lowest_bit_set = 14;
4325         for (uint32_t i = 0; i < 14; ++i)
4326         {
4327             // if registers<i> == '1' then
4328             if (BitIsSet (registers, i))
4329             {
4330                 if (i < lowest_bit_set)
4331                     lowest_bit_set = i;
4332                 //if i == n && wback && i != LowestSetBit(registers) then
4333                 if ((i == n) && wback && (i != lowest_bit_set))
4334                     // MemA[address,4] = bits(32) UNKNOWN;
4335                     WriteBits32UnknownToMemory (address + offset);
4336                 else
4337                 {
4338                     // MemA[address,4] = R[i];
4339                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4340                     if (!success)
4341                         return false;
4342 
4343                     RegisterInfo data_reg;
4344                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4345                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4346                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4347                         return false;
4348                 }
4349 
4350                 // address = address + 4;
4351                 offset += addr_byte_size;
4352             }
4353         }
4354 
4355         // if registers<15> == '1' then
4356         //    MemA[address,4] = PCStoreValue();
4357         if (BitIsSet (registers, 15))
4358         {
4359             RegisterInfo pc_reg;
4360             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4361             context.SetRegisterPlusOffset (pc_reg, 8);
4362             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4363             if (!success)
4364                 return false;
4365 
4366             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4367                 return false;
4368         }
4369 
4370         // if wback then R[n] = R[n] - 4*BitCount(registers);
4371         if (wback)
4372         {
4373             offset = (addr_byte_size * BitCount (registers)) * -1;
4374             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4375             context.SetImmediateSigned (offset);
4376             addr_t data = Rn + offset;
4377             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4378                 return false;
4379         }
4380     }
4381     return true;
4382 }
4383 
4384 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
4385 // from a base register.  The consecutive memory locations end just below this address, and the address of the first of
4386 // those locations can optionally be written back to the base register.
4387 bool
4388 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding)
4389 {
4390 #if 0
4391     if ConditionPassed() then
4392         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4393         address = R[n] - 4*BitCount(registers);
4394 
4395         for i = 0 to 14
4396             if registers<i> == '1' then
4397                 if i == n && wback && i != LowestSetBit(registers) then
4398                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4399                 else
4400                     MemA[address,4] = R[i];
4401                 address = address + 4;
4402 
4403         if registers<15> == '1' then // Only possible for encoding A1
4404             MemA[address,4] = PCStoreValue();
4405 
4406         if wback then R[n] = R[n] - 4*BitCount(registers);
4407 #endif
4408 
4409 
4410     bool success = false;
4411 
4412     if (ConditionPassed(opcode))
4413     {
4414         uint32_t n;
4415         uint32_t registers = 0;
4416         bool wback;
4417         const uint32_t addr_byte_size = GetAddressByteSize();
4418 
4419         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4420         switch (encoding)
4421         {
4422             case eEncodingT1:
4423                 // if W == '1' && Rn == '1101' then SEE PUSH;
4424                 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
4425                 {
4426                     // See PUSH
4427                 }
4428                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4429                 n = Bits32 (opcode, 19, 16);
4430                 registers = Bits32 (opcode, 15, 0);
4431                 registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
4432                 wback = BitIsSet (opcode, 21);
4433                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4434                 if ((n == 15) || BitCount (registers) < 2)
4435                     return false;
4436                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4437                 if (wback && BitIsSet (registers, n))
4438                     return false;
4439                 break;
4440 
4441             case eEncodingA1:
4442                 // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE PUSH;
4443                 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
4444                 {
4445                     // See Push
4446                 }
4447                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4448                 n = Bits32 (opcode, 19, 16);
4449                 registers = Bits32 (opcode, 15, 0);
4450                 wback = BitIsSet (opcode, 21);
4451                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4452                 if ((n == 15) || BitCount (registers) < 1)
4453                     return false;
4454                 break;
4455 
4456             default:
4457                 return false;
4458         }
4459 
4460         // address = R[n] - 4*BitCount(registers);
4461 
4462         int32_t offset = 0;
4463         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4464         if (!success)
4465         return false;
4466 
4467         addr_t address = Rn - (addr_byte_size * BitCount (registers));
4468 
4469         EmulateInstruction::Context context;
4470         context.type = EmulateInstruction::eContextRegisterStore;
4471         RegisterInfo base_reg;
4472         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4473 
4474         // for i = 0 to 14
4475         uint32_t lowest_set_bit = 14;
4476         for (uint32_t i = 0; i < 14; ++i)
4477         {
4478             // if registers<i> == '1' then
4479             if (BitIsSet (registers, i))
4480             {
4481                 if (i < lowest_set_bit)
4482                     lowest_set_bit = i;
4483                 // if i == n && wback && i != LowestSetBit(registers) then
4484                 if ((i == n) && wback && (i != lowest_set_bit))
4485                     // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4486                     WriteBits32UnknownToMemory (address + offset);
4487                 else
4488                 {
4489                     // MemA[address,4] = R[i];
4490                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4491                     if (!success)
4492                         return false;
4493 
4494                     RegisterInfo data_reg;
4495                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4496                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4497                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4498                         return false;
4499                 }
4500 
4501                 // address = address + 4;
4502                 offset += addr_byte_size;
4503             }
4504         }
4505 
4506         // if registers<15> == '1' then // Only possible for encoding A1
4507         //     MemA[address,4] = PCStoreValue();
4508         if (BitIsSet (registers, 15))
4509         {
4510             RegisterInfo pc_reg;
4511             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4512             context.SetRegisterPlusOffset (pc_reg, 8);
4513             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4514             if (!success)
4515                 return false;
4516 
4517             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4518                 return false;
4519         }
4520 
4521         // if wback then R[n] = R[n] - 4*BitCount(registers);
4522         if (wback)
4523         {
4524             offset = (addr_byte_size * BitCount (registers)) * -1;
4525             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4526             context.SetImmediateSigned (offset);
4527             addr_t data = Rn + offset;
4528             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4529                 return false;
4530         }
4531     }
4532     return true;
4533 }
4534 
4535 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
4536 // from a base register.  The consecutive memory locations start just above this address, and the address of the last
4537 // of those locations can optionally be written back to the base register.
4538 bool
4539 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding)
4540 {
4541 #if 0
4542     if ConditionPassed() then
4543         EncodingSpecificOperations();
4544         address = R[n] + 4;
4545 
4546         for i = 0 to 14
4547             if registers<i> == '1' then
4548                 if i == n && wback && i != LowestSetBit(registers) then
4549                     MemA[address,4] = bits(32) UNKNOWN;
4550                 else
4551                     MemA[address,4] = R[i];
4552                 address = address + 4;
4553 
4554         if registers<15> == '1' then
4555             MemA[address,4] = PCStoreValue();
4556 
4557         if wback then R[n] = R[n] + 4*BitCount(registers);
4558 #endif
4559 
4560     bool success = false;
4561 
4562     if (ConditionPassed(opcode))
4563     {
4564         uint32_t n;
4565         uint32_t registers = 0;
4566         bool wback;
4567         const uint32_t addr_byte_size = GetAddressByteSize();
4568 
4569         // EncodingSpecificOperations();
4570         switch (encoding)
4571         {
4572             case eEncodingA1:
4573                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4574                 n = Bits32 (opcode, 19, 16);
4575                 registers = Bits32 (opcode, 15, 0);
4576                 wback = BitIsSet (opcode, 21);
4577 
4578                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4579                 if ((n == 15) && (BitCount (registers) < 1))
4580                     return false;
4581                 break;
4582             default:
4583                 return false;
4584         }
4585         // address = R[n] + 4;
4586 
4587         int32_t offset = 0;
4588         addr_t Rn = ReadCoreReg (n, &success);
4589         if (!success)
4590             return false;
4591 
4592         addr_t address = Rn + addr_byte_size;
4593 
4594         EmulateInstruction::Context context;
4595         context.type = EmulateInstruction::eContextRegisterStore;
4596         RegisterInfo base_reg;
4597         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4598 
4599         uint32_t lowest_set_bit = 14;
4600         // for i = 0 to 14
4601         for (uint32_t i = 0; i < 14; ++i)
4602         {
4603             // if registers<i> == '1' then
4604             if (BitIsSet (registers, i))
4605             {
4606                 if (i < lowest_set_bit)
4607                     lowest_set_bit = i;
4608                 // if i == n && wback && i != LowestSetBit(registers) then
4609                 if ((i == n) && wback && (i != lowest_set_bit))
4610                     // MemA[address,4] = bits(32) UNKNOWN;
4611                     WriteBits32UnknownToMemory (address + offset);
4612                 // else
4613                 else
4614                 {
4615                     // MemA[address,4] = R[i];
4616                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4617                     if (!success)
4618                         return false;
4619 
4620                     RegisterInfo data_reg;
4621                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4622                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size);
4623                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4624                         return false;
4625                 }
4626 
4627                 // address = address + 4;
4628                 offset += addr_byte_size;
4629             }
4630         }
4631 
4632         // if registers<15> == '1' then
4633             // MemA[address,4] = PCStoreValue();
4634         if (BitIsSet (registers, 15))
4635         {
4636             RegisterInfo pc_reg;
4637             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4638             context.SetRegisterPlusOffset (pc_reg, 8);
4639             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4640             if (!success)
4641             return false;
4642 
4643             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4644                 return false;
4645         }
4646 
4647         // if wback then R[n] = R[n] + 4*BitCount(registers);
4648         if (wback)
4649         {
4650             offset = addr_byte_size * BitCount (registers);
4651             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4652             context.SetImmediateSigned (offset);
4653             addr_t data = Rn + offset;
4654             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4655                 return false;
4656         }
4657     }
4658     return true;
4659 }
4660 
4661 // STR (store immediate) calculates an address from a base register value and an immediate offset, and stores a word
4662 // from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
4663 bool
4664 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding)
4665 {
4666 #if 0
4667     if ConditionPassed() then
4668         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4669         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4670         address = if index then offset_addr else R[n];
4671         if UnalignedSupport() || address<1:0> == '00' then
4672             MemU[address,4] = R[t];
4673         else // Can only occur before ARMv7
4674             MemU[address,4] = bits(32) UNKNOWN;
4675         if wback then R[n] = offset_addr;
4676 #endif
4677 
4678     bool success = false;
4679 
4680     if (ConditionPassed(opcode))
4681     {
4682         const uint32_t addr_byte_size = GetAddressByteSize();
4683 
4684         uint32_t t;
4685         uint32_t n;
4686         uint32_t imm32;
4687         bool index;
4688         bool add;
4689         bool wback;
4690         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4691         switch (encoding)
4692         {
4693             case eEncodingT1:
4694                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
4695                 t = Bits32 (opcode, 2, 0);
4696                 n = Bits32 (opcode, 5, 3);
4697                 imm32 = Bits32 (opcode, 10, 6) << 2;
4698 
4699                 // index = TRUE; add = TRUE; wback = FALSE;
4700                 index = true;
4701                 add = false;
4702                 wback = false;
4703                 break;
4704 
4705             case eEncodingT2:
4706                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4707                 t = Bits32 (opcode, 10, 8);
4708                 n = 13;
4709                 imm32 = Bits32 (opcode, 7, 0) << 2;
4710 
4711                 // index = TRUE; add = TRUE; wback = FALSE;
4712                 index = true;
4713                 add = true;
4714                 wback = false;
4715                 break;
4716 
4717             case eEncodingT3:
4718                 // if Rn == '1111' then UNDEFINED;
4719                 if (Bits32 (opcode, 19, 16) == 15)
4720                     return false;
4721 
4722                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4723                 t = Bits32 (opcode, 15, 12);
4724                 n = Bits32 (opcode, 19, 16);
4725                 imm32 = Bits32 (opcode, 11, 0);
4726 
4727                 // index = TRUE; add = TRUE; wback = FALSE;
4728                 index = true;
4729                 add = true;
4730                 wback = false;
4731 
4732                 // if t == 15 then UNPREDICTABLE;
4733                 if (t == 15)
4734                     return false;
4735                 break;
4736 
4737             case eEncodingT4:
4738                 // if P == '1' && U == '1' && W == '0' then SEE STRT;
4739                 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH;
4740                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4741                 if ((Bits32 (opcode, 19, 16) == 15)
4742                       || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
4743                     return false;
4744 
4745                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4746                 t = Bits32 (opcode, 15, 12);
4747                 n = Bits32 (opcode, 19, 16);
4748                 imm32 = Bits32 (opcode, 7, 0);
4749 
4750                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4751                 index = BitIsSet (opcode, 10);
4752                 add = BitIsSet (opcode, 9);
4753                 wback = BitIsSet (opcode, 8);
4754 
4755                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
4756                 if ((t == 15) || (wback && (n == t)))
4757                     return false;
4758                 break;
4759 
4760             default:
4761                 return false;
4762         }
4763 
4764         addr_t offset_addr;
4765         addr_t address;
4766 
4767         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4768         uint32_t base_address = ReadCoreReg (n, &success);
4769         if (!success)
4770             return false;
4771 
4772         if (add)
4773             offset_addr = base_address + imm32;
4774         else
4775             offset_addr = base_address - imm32;
4776 
4777         // address = if index then offset_addr else R[n];
4778         if (index)
4779             address = offset_addr;
4780         else
4781             address = base_address;
4782 
4783         EmulateInstruction::Context context;
4784         if (n == 13)
4785             context.type = eContextPushRegisterOnStack;
4786         else
4787             context.type = eContextRegisterStore;
4788 
4789         RegisterInfo base_reg;
4790         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4791 
4792         // if UnalignedSupport() || address<1:0> == '00' then
4793         if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
4794         {
4795             // MemU[address,4] = R[t];
4796             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4797             if (!success)
4798                 return false;
4799 
4800             RegisterInfo data_reg;
4801             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4802             int32_t offset = address - base_address;
4803             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4804             if (!MemUWrite (context, address, data, addr_byte_size))
4805                 return false;
4806         }
4807         else
4808         {
4809             // MemU[address,4] = bits(32) UNKNOWN;
4810             WriteBits32UnknownToMemory (address);
4811         }
4812 
4813         // if wback then R[n] = offset_addr;
4814         if (wback)
4815         {
4816             if (n == 13)
4817                 context.type = eContextAdjustStackPointer;
4818             else
4819                 context.type = eContextAdjustBaseRegister;
4820             context.SetAddress (offset_addr);
4821 
4822             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4823                 return false;
4824         }
4825     }
4826     return true;
4827 }
4828 
4829 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a
4830 // word from a register to memory.   The offset register value can optionally be shifted.
4831 bool
4832 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding)
4833 {
4834 #if 0
4835     if ConditionPassed() then
4836         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4837         offset = Shift(R[m], shift_t, shift_n, APSR.C);
4838         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4839         address = if index then offset_addr else R[n];
4840         if t == 15 then // Only possible for encoding A1
4841             data = PCStoreValue();
4842         else
4843             data = R[t];
4844         if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4845             MemU[address,4] = data;
4846         else // Can only occur before ARMv7
4847             MemU[address,4] = bits(32) UNKNOWN;
4848         if wback then R[n] = offset_addr;
4849 #endif
4850 
4851     bool success = false;
4852 
4853     if (ConditionPassed(opcode))
4854     {
4855         const uint32_t addr_byte_size = GetAddressByteSize();
4856 
4857         uint32_t t;
4858         uint32_t n;
4859         uint32_t m;
4860         ARM_ShifterType shift_t;
4861         uint32_t shift_n;
4862         bool index;
4863         bool add;
4864         bool wback;
4865 
4866         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4867         switch (encoding)
4868         {
4869             case eEncodingT1:
4870                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4871                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4872                 t = Bits32 (opcode, 2, 0);
4873                 n = Bits32 (opcode, 5, 3);
4874                 m = Bits32 (opcode, 8, 6);
4875 
4876                 // index = TRUE; add = TRUE; wback = FALSE;
4877                 index = true;
4878                 add = true;
4879                 wback = false;
4880 
4881                 // (shift_t, shift_n) = (SRType_LSL, 0);
4882                 shift_t = SRType_LSL;
4883                 shift_n = 0;
4884                 break;
4885 
4886             case eEncodingT2:
4887                 // if Rn == '1111' then UNDEFINED;
4888                 if (Bits32 (opcode, 19, 16) == 15)
4889                     return false;
4890 
4891                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4892                 t = Bits32 (opcode, 15, 12);
4893                 n = Bits32 (opcode, 19, 16);
4894                 m = Bits32 (opcode, 3, 0);
4895 
4896                 // index = TRUE; add = TRUE; wback = FALSE;
4897                 index = true;
4898                 add = true;
4899                 wback = false;
4900 
4901                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4902                 shift_t = SRType_LSL;
4903                 shift_n = Bits32 (opcode, 5, 4);
4904 
4905                 // if t == 15 || BadReg(m) then UNPREDICTABLE;
4906                 if ((t == 15) || (BadReg (m)))
4907                     return false;
4908                 break;
4909 
4910             case eEncodingA1:
4911             {
4912                 // if P == '0' && W == '1' then SEE STRT;
4913                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4914                 t = Bits32 (opcode, 15, 12);
4915                 n = Bits32 (opcode, 19, 16);
4916                 m = Bits32 (opcode, 3, 0);
4917 
4918                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
4919                 index = BitIsSet (opcode, 24);
4920                 add = BitIsSet (opcode, 23);
4921                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
4922 
4923                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
4924                 uint32_t typ = Bits32 (opcode, 6, 5);
4925                 uint32_t imm5 = Bits32 (opcode, 11, 7);
4926                 shift_n = DecodeImmShift(typ, imm5, shift_t);
4927 
4928                 // if m == 15 then UNPREDICTABLE;
4929                 if (m == 15)
4930                     return false;
4931 
4932                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
4933                 if (wback && ((n == 15) || (n == t)))
4934                     return false;
4935 
4936                 break;
4937             }
4938             default:
4939                 return false;
4940         }
4941 
4942         addr_t offset_addr;
4943         addr_t address;
4944         int32_t offset = 0;
4945 
4946         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4947         if (!success)
4948             return false;
4949 
4950         uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
4951         if (!success)
4952             return false;
4953 
4954         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4955         offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success);
4956         if (!success)
4957             return false;
4958 
4959         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4960         if (add)
4961             offset_addr = base_address + offset;
4962         else
4963             offset_addr = base_address - offset;
4964 
4965         // address = if index then offset_addr else R[n];
4966         if (index)
4967             address = offset_addr;
4968         else
4969             address = base_address;
4970 
4971         uint32_t data;
4972         // if t == 15 then // Only possible for encoding A1
4973         if (t == 15)
4974             // data = PCStoreValue();
4975             data = ReadCoreReg (PC_REG, &success);
4976         else
4977             // data = R[t];
4978             data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4979 
4980         if (!success)
4981             return false;
4982 
4983         EmulateInstruction::Context context;
4984         context.type = eContextRegisterStore;
4985 
4986         // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4987         if (UnalignedSupport ()
4988             || (BitIsClear (address, 1) && BitIsClear (address, 0))
4989             || CurrentInstrSet() == eModeARM)
4990         {
4991             // MemU[address,4] = data;
4992 
4993             RegisterInfo base_reg;
4994             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 +  n, base_reg);
4995 
4996             RegisterInfo data_reg;
4997             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4998 
4999             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
5000             if (!MemUWrite (context, address, data, addr_byte_size))
5001                 return false;
5002 
5003         }
5004         else
5005             // MemU[address,4] = bits(32) UNKNOWN;
5006             WriteBits32UnknownToMemory (address);
5007 
5008         // if wback then R[n] = offset_addr;
5009         if (wback)
5010         {
5011             context.type = eContextRegisterLoad;
5012             context.SetAddress (offset_addr);
5013             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5014                 return false;
5015         }
5016 
5017     }
5018     return true;
5019 }
5020 
5021 bool
5022 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding)
5023 {
5024 #if 0
5025     if ConditionPassed() then
5026         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5027         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5028         address = if index then offset_addr else R[n];
5029         MemU[address,1] = R[t]<7:0>;
5030         if wback then R[n] = offset_addr;
5031 #endif
5032 
5033 
5034     bool success = false;
5035 
5036     if (ConditionPassed(opcode))
5037     {
5038         uint32_t t;
5039         uint32_t n;
5040         uint32_t imm32;
5041         bool index;
5042         bool add;
5043         bool wback;
5044         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5045         switch (encoding)
5046         {
5047             case eEncodingT1:
5048                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
5049                 t = Bits32 (opcode, 2, 0);
5050                 n = Bits32 (opcode, 5, 3);
5051                 imm32 = Bits32 (opcode, 10, 6);
5052 
5053                 // index = TRUE; add = TRUE; wback = FALSE;
5054                 index = true;
5055                 add = true;
5056                 wback = false;
5057                 break;
5058 
5059             case eEncodingT2:
5060                 // if Rn == '1111' then UNDEFINED;
5061                 if (Bits32 (opcode, 19, 16) == 15)
5062                     return false;
5063 
5064                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5065                 t = Bits32 (opcode, 15, 12);
5066                 n = Bits32 (opcode, 19, 16);
5067                 imm32 = Bits32 (opcode, 11, 0);
5068 
5069                 // index = TRUE; add = TRUE; wback = FALSE;
5070                 index = true;
5071                 add = true;
5072                 wback = false;
5073 
5074                 // if BadReg(t) then UNPREDICTABLE;
5075                 if (BadReg (t))
5076                     return false;
5077                 break;
5078 
5079             case eEncodingT3:
5080                 // if P == '1' && U == '1' && W == '0' then SEE STRBT;
5081                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5082                 if (Bits32 (opcode, 19, 16) == 15)
5083                     return false;
5084 
5085                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5086                 t = Bits32 (opcode, 15, 12);
5087                 n = Bits32 (opcode, 19, 16);
5088                 imm32 = Bits32 (opcode, 7, 0);
5089 
5090                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5091                 index = BitIsSet (opcode, 10);
5092                 add = BitIsSet (opcode, 9);
5093                 wback = BitIsSet (opcode, 8);
5094 
5095                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
5096                 if ((BadReg (t)) || (wback && (n == t)))
5097                     return false;
5098                 break;
5099 
5100             default:
5101                 return false;
5102         }
5103 
5104         addr_t offset_addr;
5105         addr_t address;
5106         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5107         if (!success)
5108             return false;
5109 
5110         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5111         if (add)
5112             offset_addr = base_address + imm32;
5113         else
5114             offset_addr = base_address - imm32;
5115 
5116         // address = if index then offset_addr else R[n];
5117         if (index)
5118             address = offset_addr;
5119         else
5120             address = base_address;
5121 
5122         // MemU[address,1] = R[t]<7:0>
5123         RegisterInfo base_reg;
5124         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5125 
5126         RegisterInfo data_reg;
5127         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5128 
5129         EmulateInstruction::Context context;
5130         context.type = eContextRegisterStore;
5131         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
5132 
5133         uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5134         if (!success)
5135             return false;
5136 
5137         data = Bits32 (data, 7, 0);
5138 
5139         if (!MemUWrite (context, address, data, 1))
5140             return false;
5141 
5142         // if wback then R[n] = offset_addr;
5143         if (wback)
5144         {
5145             context.type = eContextRegisterLoad;
5146             context.SetAddress (offset_addr);
5147             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5148                 return false;
5149         }
5150 
5151     }
5152 
5153     return true;
5154 }
5155 
5156 // STRH (register) calculates an address from a base register value and an offset register value, and stores a
5157 // halfword from a register to memory.  The offset register value can be shifted left by 0, 1, 2, or 3 bits.
5158 bool
5159 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding)
5160 {
5161 #if 0
5162     if ConditionPassed() then
5163         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5164         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5165         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5166         address = if index then offset_addr else R[n];
5167         if UnalignedSupport() || address<0> == '0' then
5168             MemU[address,2] = R[t]<15:0>;
5169         else // Can only occur before ARMv7
5170             MemU[address,2] = bits(16) UNKNOWN;
5171         if wback then R[n] = offset_addr;
5172 #endif
5173 
5174     bool success = false;
5175 
5176     if (ConditionPassed(opcode))
5177     {
5178         uint32_t t;
5179         uint32_t n;
5180         uint32_t m;
5181         bool index;
5182         bool add;
5183         bool wback;
5184         ARM_ShifterType shift_t;
5185         uint32_t shift_n;
5186 
5187         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5188         switch (encoding)
5189         {
5190             case eEncodingT1:
5191                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5192                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5193                 t = Bits32 (opcode, 2, 0);
5194                 n = Bits32 (opcode, 5, 3);
5195                 m = Bits32 (opcode, 8, 6);
5196 
5197                 // index = TRUE; add = TRUE; wback = FALSE;
5198                 index = true;
5199                 add = true;
5200                 wback = false;
5201 
5202                 // (shift_t, shift_n) = (SRType_LSL, 0);
5203                 shift_t = SRType_LSL;
5204                 shift_n = 0;
5205 
5206                 break;
5207 
5208             case eEncodingT2:
5209                 // if Rn == '1111' then UNDEFINED;
5210                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5211                 t = Bits32 (opcode, 15, 12);
5212                 n = Bits32 (opcode, 19, 16);
5213                 m = Bits32 (opcode, 3, 0);
5214                 if (n == 15)
5215                     return false;
5216 
5217                 // index = TRUE; add = TRUE; wback = FALSE;
5218                 index = true;
5219                 add = true;
5220                 wback = false;
5221 
5222                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5223                 shift_t = SRType_LSL;
5224                 shift_n = Bits32 (opcode, 5, 4);
5225 
5226                 // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5227                 if (BadReg (t) || BadReg (m))
5228                     return false;
5229 
5230                 break;
5231 
5232             case eEncodingA1:
5233                 // if P == '0' && W == '1' then SEE STRHT;
5234                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5235                 t = Bits32 (opcode, 15, 12);
5236                 n = Bits32 (opcode, 19, 16);
5237                 m = Bits32 (opcode, 3, 0);
5238 
5239                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5240                 index = BitIsSet (opcode, 24);
5241                 add = BitIsSet (opcode, 23);
5242                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5243 
5244                 // (shift_t, shift_n) = (SRType_LSL, 0);
5245                 shift_t = SRType_LSL;
5246                 shift_n = 0;
5247 
5248                 // if t == 15 || m == 15 then UNPREDICTABLE;
5249                 if ((t == 15) || (m == 15))
5250                     return false;
5251 
5252                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5253                 if (wback && ((n == 15) || (n == t)))
5254                     return false;
5255 
5256                 break;
5257 
5258             default:
5259                 return false;
5260         }
5261 
5262         uint32_t Rm = ReadCoreReg (m, &success);
5263         if (!success)
5264             return false;
5265 
5266         uint32_t Rn = ReadCoreReg (n, &success);
5267         if (!success)
5268             return false;
5269 
5270         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5271         uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
5272         if (!success)
5273             return false;
5274 
5275         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5276         addr_t offset_addr;
5277         if (add)
5278             offset_addr = Rn + offset;
5279         else
5280             offset_addr = Rn - offset;
5281 
5282         // address = if index then offset_addr else R[n];
5283         addr_t address;
5284         if (index)
5285             address = offset_addr;
5286         else
5287             address = Rn;
5288 
5289         EmulateInstruction::Context context;
5290         context.type = eContextRegisterStore;
5291         RegisterInfo base_reg;
5292         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5293         RegisterInfo offset_reg;
5294         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5295 
5296         // if UnalignedSupport() || address<0> == '0' then
5297         if (UnalignedSupport() || BitIsClear (address, 0))
5298         {
5299             // MemU[address,2] = R[t]<15:0>;
5300             uint32_t Rt = ReadCoreReg (t, &success);
5301             if (!success)
5302                 return false;
5303 
5304             EmulateInstruction::Context context;
5305             context.type = eContextRegisterStore;
5306             RegisterInfo base_reg;
5307             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5308             RegisterInfo offset_reg;
5309             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5310             RegisterInfo data_reg;
5311             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5312             context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
5313 
5314             if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2))
5315                 return false;
5316         }
5317         else // Can only occur before ARMv7
5318         {
5319             // MemU[address,2] = bits(16) UNKNOWN;
5320         }
5321 
5322         // if wback then R[n] = offset_addr;
5323         if (wback)
5324         {
5325             context.type = eContextAdjustBaseRegister;
5326             context.SetAddress (offset_addr);
5327             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5328                 return false;
5329         }
5330     }
5331 
5332     return true;
5333 }
5334 
5335 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value,
5336 // and writes the result to the destination register.  It can optionally update the condition flags
5337 // based on the result.
5338 bool
5339 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding)
5340 {
5341 #if 0
5342     // ARM pseudo code...
5343     if ConditionPassed() then
5344         EncodingSpecificOperations();
5345         (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5346         if d == 15 then         // Can only occur for ARM encoding
5347             ALUWritePC(result); // setflags is always FALSE here
5348         else
5349             R[d] = result;
5350             if setflags then
5351                 APSR.N = result<31>;
5352                 APSR.Z = IsZeroBit(result);
5353                 APSR.C = carry;
5354                 APSR.V = overflow;
5355 #endif
5356 
5357     bool success = false;
5358 
5359     if (ConditionPassed(opcode))
5360     {
5361         uint32_t Rd, Rn;
5362         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
5363         bool setflags;
5364         switch (encoding)
5365         {
5366         case eEncodingT1:
5367             Rd = Bits32(opcode, 11, 8);
5368             Rn = Bits32(opcode, 19, 16);
5369             setflags = BitIsSet(opcode, 20);
5370             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5371             if (BadReg(Rd) || BadReg(Rn))
5372                 return false;
5373             break;
5374         case eEncodingA1:
5375             Rd = Bits32(opcode, 15, 12);
5376             Rn = Bits32(opcode, 19, 16);
5377             setflags = BitIsSet(opcode, 20);
5378             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5379 
5380             if (Rd == 15 && setflags)
5381                 return EmulateSUBSPcLrEtc (opcode, encoding);
5382             break;
5383         default:
5384             return false;
5385         }
5386 
5387         // Read the first operand.
5388         int32_t val1 = ReadCoreReg(Rn, &success);
5389         if (!success)
5390             return false;
5391 
5392         AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5393 
5394         EmulateInstruction::Context context;
5395         context.type = EmulateInstruction::eContextImmediate;
5396         context.SetNoArgs ();
5397 
5398         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5399             return false;
5400     }
5401     return true;
5402 }
5403 
5404 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted
5405 // register value, and writes the result to the destination register.  It can optionally update the
5406 // condition flags based on the result.
5407 bool
5408 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding)
5409 {
5410 #if 0
5411     // ARM pseudo code...
5412     if ConditionPassed() then
5413         EncodingSpecificOperations();
5414         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5415         (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5416         if d == 15 then         // Can only occur for ARM encoding
5417             ALUWritePC(result); // setflags is always FALSE here
5418         else
5419             R[d] = result;
5420             if setflags then
5421                 APSR.N = result<31>;
5422                 APSR.Z = IsZeroBit(result);
5423                 APSR.C = carry;
5424                 APSR.V = overflow;
5425 #endif
5426 
5427     bool success = false;
5428 
5429     if (ConditionPassed(opcode))
5430     {
5431         uint32_t Rd, Rn, Rm;
5432         ARM_ShifterType shift_t;
5433         uint32_t shift_n; // the shift applied to the value read from Rm
5434         bool setflags;
5435         switch (encoding)
5436         {
5437         case eEncodingT1:
5438             Rd = Rn = Bits32(opcode, 2, 0);
5439             Rm = Bits32(opcode, 5, 3);
5440             setflags = !InITBlock();
5441             shift_t = SRType_LSL;
5442             shift_n = 0;
5443             break;
5444         case eEncodingT2:
5445             Rd = Bits32(opcode, 11, 8);
5446             Rn = Bits32(opcode, 19, 16);
5447             Rm = Bits32(opcode, 3, 0);
5448             setflags = BitIsSet(opcode, 20);
5449             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5450             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5451                 return false;
5452             break;
5453         case eEncodingA1:
5454             Rd = Bits32(opcode, 15, 12);
5455             Rn = Bits32(opcode, 19, 16);
5456             Rm = Bits32(opcode, 3, 0);
5457             setflags = BitIsSet(opcode, 20);
5458             shift_n = DecodeImmShiftARM(opcode, shift_t);
5459 
5460             if (Rd == 15 && setflags)
5461                 return EmulateSUBSPcLrEtc (opcode, encoding);
5462             break;
5463         default:
5464             return false;
5465         }
5466 
5467         // Read the first operand.
5468         int32_t val1 = ReadCoreReg(Rn, &success);
5469         if (!success)
5470             return false;
5471 
5472         // Read the second operand.
5473         int32_t val2 = ReadCoreReg(Rm, &success);
5474         if (!success)
5475             return false;
5476 
5477         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5478         if (!success)
5479             return false;
5480         AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5481 
5482         EmulateInstruction::Context context;
5483         context.type = EmulateInstruction::eContextImmediate;
5484         context.SetNoArgs ();
5485 
5486         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5487             return false;
5488     }
5489     return true;
5490 }
5491 
5492 // This instruction adds an immediate value to the PC value to form a PC-relative address,
5493 // and writes the result to the destination register.
5494 bool
5495 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding)
5496 {
5497 #if 0
5498     // ARM pseudo code...
5499     if ConditionPassed() then
5500         EncodingSpecificOperations();
5501         result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5502         if d == 15 then         // Can only occur for ARM encodings
5503             ALUWritePC(result);
5504         else
5505             R[d] = result;
5506 #endif
5507 
5508     bool success = false;
5509 
5510     if (ConditionPassed(opcode))
5511     {
5512         uint32_t Rd;
5513         uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5514         bool add;
5515         switch (encoding)
5516         {
5517         case eEncodingT1:
5518             Rd = Bits32(opcode, 10, 8);
5519             imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5520             add = true;
5521             break;
5522         case eEncodingT2:
5523         case eEncodingT3:
5524             Rd = Bits32(opcode, 11, 8);
5525             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5526             add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5527             if (BadReg(Rd))
5528                 return false;
5529             break;
5530         case eEncodingA1:
5531         case eEncodingA2:
5532             Rd = Bits32(opcode, 15, 12);
5533             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5534             add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5535             break;
5536         default:
5537             return false;
5538         }
5539 
5540         // Read the PC value.
5541         uint32_t pc = ReadCoreReg(PC_REG, &success);
5542         if (!success)
5543             return false;
5544 
5545         uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5546 
5547         EmulateInstruction::Context context;
5548         context.type = EmulateInstruction::eContextImmediate;
5549         context.SetNoArgs ();
5550 
5551         if (!WriteCoreReg(context, result, Rd))
5552             return false;
5553     }
5554     return true;
5555 }
5556 
5557 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result
5558 // to the destination register.  It can optionally update the condition flags based on the result.
5559 bool
5560 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding)
5561 {
5562 #if 0
5563     // ARM pseudo code...
5564     if ConditionPassed() then
5565         EncodingSpecificOperations();
5566         result = R[n] AND imm32;
5567         if d == 15 then         // Can only occur for ARM encoding
5568             ALUWritePC(result); // setflags is always FALSE here
5569         else
5570             R[d] = result;
5571             if setflags then
5572                 APSR.N = result<31>;
5573                 APSR.Z = IsZeroBit(result);
5574                 APSR.C = carry;
5575                 // APSR.V unchanged
5576 #endif
5577 
5578     bool success = false;
5579 
5580     if (ConditionPassed(opcode))
5581     {
5582         uint32_t Rd, Rn;
5583         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
5584         bool setflags;
5585         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5586         switch (encoding)
5587         {
5588         case eEncodingT1:
5589             Rd = Bits32(opcode, 11, 8);
5590             Rn = Bits32(opcode, 19, 16);
5591             setflags = BitIsSet(opcode, 20);
5592             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5593             // if Rd == '1111' && S == '1' then SEE TST (immediate);
5594             if (Rd == 15 && setflags)
5595                 return EmulateTSTImm(opcode, eEncodingT1);
5596             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
5597                 return false;
5598             break;
5599         case eEncodingA1:
5600             Rd = Bits32(opcode, 15, 12);
5601             Rn = Bits32(opcode, 19, 16);
5602             setflags = BitIsSet(opcode, 20);
5603             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5604 
5605             if (Rd == 15 && setflags)
5606                 return EmulateSUBSPcLrEtc (opcode, encoding);
5607             break;
5608         default:
5609             return false;
5610         }
5611 
5612         // Read the first operand.
5613         uint32_t val1 = ReadCoreReg(Rn, &success);
5614         if (!success)
5615             return false;
5616 
5617         uint32_t result = val1 & imm32;
5618 
5619         EmulateInstruction::Context context;
5620         context.type = EmulateInstruction::eContextImmediate;
5621         context.SetNoArgs ();
5622 
5623         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5624             return false;
5625     }
5626     return true;
5627 }
5628 
5629 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value,
5630 // and writes the result to the destination register.  It can optionally update the condition flags
5631 // based on the result.
5632 bool
5633 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding)
5634 {
5635 #if 0
5636     // ARM pseudo code...
5637     if ConditionPassed() then
5638         EncodingSpecificOperations();
5639         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5640         result = R[n] AND shifted;
5641         if d == 15 then         // Can only occur for ARM encoding
5642             ALUWritePC(result); // setflags is always FALSE here
5643         else
5644             R[d] = result;
5645             if setflags then
5646                 APSR.N = result<31>;
5647                 APSR.Z = IsZeroBit(result);
5648                 APSR.C = carry;
5649                 // APSR.V unchanged
5650 #endif
5651 
5652     bool success = false;
5653 
5654     if (ConditionPassed(opcode))
5655     {
5656         uint32_t Rd, Rn, Rm;
5657         ARM_ShifterType shift_t;
5658         uint32_t shift_n; // the shift applied to the value read from Rm
5659         bool setflags;
5660         uint32_t carry;
5661         switch (encoding)
5662         {
5663         case eEncodingT1:
5664             Rd = Rn = Bits32(opcode, 2, 0);
5665             Rm = Bits32(opcode, 5, 3);
5666             setflags = !InITBlock();
5667             shift_t = SRType_LSL;
5668             shift_n = 0;
5669             break;
5670         case eEncodingT2:
5671             Rd = Bits32(opcode, 11, 8);
5672             Rn = Bits32(opcode, 19, 16);
5673             Rm = Bits32(opcode, 3, 0);
5674             setflags = BitIsSet(opcode, 20);
5675             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5676             // if Rd == '1111' && S == '1' then SEE TST (register);
5677             if (Rd == 15 && setflags)
5678                 return EmulateTSTReg(opcode, eEncodingT2);
5679             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
5680                 return false;
5681             break;
5682         case eEncodingA1:
5683             Rd = Bits32(opcode, 15, 12);
5684             Rn = Bits32(opcode, 19, 16);
5685             Rm = Bits32(opcode, 3, 0);
5686             setflags = BitIsSet(opcode, 20);
5687             shift_n = DecodeImmShiftARM(opcode, shift_t);
5688 
5689             if (Rd == 15 && setflags)
5690                 return EmulateSUBSPcLrEtc (opcode, encoding);
5691             break;
5692         default:
5693             return false;
5694         }
5695 
5696         // Read the first operand.
5697         uint32_t val1 = ReadCoreReg(Rn, &success);
5698         if (!success)
5699             return false;
5700 
5701         // Read the second operand.
5702         uint32_t val2 = ReadCoreReg(Rm, &success);
5703         if (!success)
5704             return false;
5705 
5706         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5707         if (!success)
5708             return false;
5709         uint32_t result = val1 & shifted;
5710 
5711         EmulateInstruction::Context context;
5712         context.type = EmulateInstruction::eContextImmediate;
5713         context.SetNoArgs ();
5714 
5715         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5716             return false;
5717     }
5718     return true;
5719 }
5720 
5721 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an
5722 // immediate value, and writes the result to the destination register.  It can optionally update the
5723 // condition flags based on the result.
5724 bool
5725 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding)
5726 {
5727 #if 0
5728     // ARM pseudo code...
5729     if ConditionPassed() then
5730         EncodingSpecificOperations();
5731         result = R[n] AND NOT(imm32);
5732         if d == 15 then         // Can only occur for ARM encoding
5733             ALUWritePC(result); // setflags is always FALSE here
5734         else
5735             R[d] = result;
5736             if setflags then
5737                 APSR.N = result<31>;
5738                 APSR.Z = IsZeroBit(result);
5739                 APSR.C = carry;
5740                 // APSR.V unchanged
5741 #endif
5742 
5743     bool success = false;
5744 
5745     if (ConditionPassed(opcode))
5746     {
5747         uint32_t Rd, Rn;
5748         uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn
5749         bool setflags;
5750         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5751         switch (encoding)
5752         {
5753         case eEncodingT1:
5754             Rd = Bits32(opcode, 11, 8);
5755             Rn = Bits32(opcode, 19, 16);
5756             setflags = BitIsSet(opcode, 20);
5757             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5758             if (BadReg(Rd) || BadReg(Rn))
5759                 return false;
5760             break;
5761         case eEncodingA1:
5762             Rd = Bits32(opcode, 15, 12);
5763             Rn = Bits32(opcode, 19, 16);
5764             setflags = BitIsSet(opcode, 20);
5765             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5766 
5767             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5768             if (Rd == 15 && setflags)
5769                 return EmulateSUBSPcLrEtc (opcode, encoding);
5770             break;
5771         default:
5772             return false;
5773         }
5774 
5775         // Read the first operand.
5776         uint32_t val1 = ReadCoreReg(Rn, &success);
5777         if (!success)
5778             return false;
5779 
5780         uint32_t result = val1 & ~imm32;
5781 
5782         EmulateInstruction::Context context;
5783         context.type = EmulateInstruction::eContextImmediate;
5784         context.SetNoArgs ();
5785 
5786         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5787             return false;
5788     }
5789     return true;
5790 }
5791 
5792 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an
5793 // optionally-shifted register value, and writes the result to the destination register.
5794 // It can optionally update the condition flags based on the result.
5795 bool
5796 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding)
5797 {
5798 #if 0
5799     // ARM pseudo code...
5800     if ConditionPassed() then
5801         EncodingSpecificOperations();
5802         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5803         result = R[n] AND NOT(shifted);
5804         if d == 15 then         // Can only occur for ARM encoding
5805             ALUWritePC(result); // setflags is always FALSE here
5806         else
5807             R[d] = result;
5808             if setflags then
5809                 APSR.N = result<31>;
5810                 APSR.Z = IsZeroBit(result);
5811                 APSR.C = carry;
5812                 // APSR.V unchanged
5813 #endif
5814 
5815     bool success = false;
5816 
5817     if (ConditionPassed(opcode))
5818     {
5819         uint32_t Rd, Rn, Rm;
5820         ARM_ShifterType shift_t;
5821         uint32_t shift_n; // the shift applied to the value read from Rm
5822         bool setflags;
5823         uint32_t carry;
5824         switch (encoding)
5825         {
5826         case eEncodingT1:
5827             Rd = Rn = Bits32(opcode, 2, 0);
5828             Rm = Bits32(opcode, 5, 3);
5829             setflags = !InITBlock();
5830             shift_t = SRType_LSL;
5831             shift_n = 0;
5832             break;
5833         case eEncodingT2:
5834             Rd = Bits32(opcode, 11, 8);
5835             Rn = Bits32(opcode, 19, 16);
5836             Rm = Bits32(opcode, 3, 0);
5837             setflags = BitIsSet(opcode, 20);
5838             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5839             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5840                 return false;
5841             break;
5842         case eEncodingA1:
5843             Rd = Bits32(opcode, 15, 12);
5844             Rn = Bits32(opcode, 19, 16);
5845             Rm = Bits32(opcode, 3, 0);
5846             setflags = BitIsSet(opcode, 20);
5847             shift_n = DecodeImmShiftARM(opcode, shift_t);
5848 
5849             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5850             if (Rd == 15 && setflags)
5851                 return EmulateSUBSPcLrEtc (opcode, encoding);
5852             break;
5853         default:
5854             return false;
5855         }
5856 
5857         // Read the first operand.
5858         uint32_t val1 = ReadCoreReg(Rn, &success);
5859         if (!success)
5860             return false;
5861 
5862         // Read the second operand.
5863         uint32_t val2 = ReadCoreReg(Rm, &success);
5864         if (!success)
5865             return false;
5866 
5867         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5868         if (!success)
5869             return false;
5870         uint32_t result = val1 & ~shifted;
5871 
5872         EmulateInstruction::Context context;
5873         context.type = EmulateInstruction::eContextImmediate;
5874         context.SetNoArgs ();
5875 
5876         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5877             return false;
5878     }
5879     return true;
5880 }
5881 
5882 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
5883 // from memory, and writes it to a register.  It can use offset, post-indexed, or pre-indexed addressing.
5884 bool
5885 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding)
5886 {
5887 #if 0
5888     if ConditionPassed() then
5889         EncodingSpecificOperations();
5890         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5891         address = if index then offset_addr else R[n];
5892         data = MemU[address,4];
5893         if wback then R[n] = offset_addr;
5894         if t == 15 then
5895             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5896         elsif UnalignedSupport() || address<1:0> = '00' then
5897             R[t] = data;
5898         else // Can only apply before ARMv7
5899             R[t] = ROR(data, 8*UInt(address<1:0>));
5900 #endif
5901 
5902     bool success = false;
5903 
5904     if (ConditionPassed(opcode))
5905     {
5906         const uint32_t addr_byte_size = GetAddressByteSize();
5907 
5908         uint32_t t;
5909         uint32_t n;
5910         uint32_t imm32;
5911         bool index;
5912         bool add;
5913         bool wback;
5914 
5915         switch (encoding)
5916         {
5917             case eEncodingA1:
5918                 // if Rn == '1111' then SEE LDR (literal);
5919                 // if P == '0' && W == '1' then SEE LDRT;
5920                 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP;
5921                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5922                 t = Bits32 (opcode, 15, 12);
5923                 n = Bits32 (opcode, 19, 16);
5924                 imm32 = Bits32 (opcode, 11, 0);
5925 
5926                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5927                 index = BitIsSet (opcode, 24);
5928                 add = BitIsSet (opcode, 23);
5929                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5930 
5931                 // if wback && n == t then UNPREDICTABLE;
5932                 if (wback && (n == t))
5933                     return false;
5934 
5935                 break;
5936 
5937             default:
5938                 return false;
5939         }
5940 
5941         addr_t address;
5942         addr_t offset_addr;
5943         addr_t base_address = ReadCoreReg (n, &success);
5944         if (!success)
5945             return false;
5946 
5947         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5948         if (add)
5949             offset_addr = base_address + imm32;
5950         else
5951             offset_addr = base_address - imm32;
5952 
5953         // address = if index then offset_addr else R[n];
5954         if (index)
5955             address = offset_addr;
5956         else
5957             address = base_address;
5958 
5959         // data = MemU[address,4];
5960 
5961         RegisterInfo base_reg;
5962         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5963 
5964         EmulateInstruction::Context context;
5965         context.type = eContextRegisterLoad;
5966         context.SetRegisterPlusOffset (base_reg, address - base_address);
5967 
5968         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5969         if (!success)
5970             return false;
5971 
5972         // if wback then R[n] = offset_addr;
5973         if (wback)
5974         {
5975             context.type = eContextAdjustBaseRegister;
5976             context.SetAddress (offset_addr);
5977             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5978                 return false;
5979         }
5980 
5981         // if t == 15 then
5982         if (t == 15)
5983         {
5984             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5985             if (BitIsClear (address, 1) && BitIsClear (address, 0))
5986             {
5987                 // LoadWritePC (data);
5988                 context.type = eContextRegisterLoad;
5989                 context.SetRegisterPlusOffset (base_reg, address - base_address);
5990                 LoadWritePC (context, data);
5991             }
5992             else
5993                   return false;
5994         }
5995         // elsif UnalignedSupport() || address<1:0> = '00' then
5996         else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5997         {
5998             // R[t] = data;
5999             context.type = eContextRegisterLoad;
6000             context.SetRegisterPlusOffset (base_reg, address - base_address);
6001             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6002                 return false;
6003         }
6004         // else // Can only apply before ARMv7
6005         else
6006         {
6007             // R[t] = ROR(data, 8*UInt(address<1:0>));
6008             data = ROR (data, Bits32 (address, 1, 0), &success);
6009             if (!success)
6010                 return false;
6011             context.type = eContextRegisterLoad;
6012             context.SetImmediate (data);
6013             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6014                 return false;
6015         }
6016 
6017     }
6018     return true;
6019 }
6020 
6021 // LDR (register) calculates an address from a base register value and an offset register value, loads a word
6022 // from memory, and writes it to a register.  The offset register value can optionally be shifted.
6023 bool
6024 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding)
6025 {
6026 #if 0
6027     if ConditionPassed() then
6028         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6029         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6030         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6031         address = if index then offset_addr else R[n];
6032         data = MemU[address,4];
6033         if wback then R[n] = offset_addr;
6034         if t == 15 then
6035             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6036         elsif UnalignedSupport() || address<1:0> = '00' then
6037             R[t] = data;
6038         else // Can only apply before ARMv7
6039             if CurrentInstrSet() == InstrSet_ARM then
6040                 R[t] = ROR(data, 8*UInt(address<1:0>));
6041             else
6042                 R[t] = bits(32) UNKNOWN;
6043 #endif
6044 
6045     bool success = false;
6046 
6047     if (ConditionPassed(opcode))
6048     {
6049         const uint32_t addr_byte_size = GetAddressByteSize();
6050 
6051         uint32_t t;
6052         uint32_t n;
6053         uint32_t m;
6054         bool index;
6055         bool add;
6056         bool wback;
6057         ARM_ShifterType shift_t;
6058         uint32_t shift_n;
6059 
6060         switch (encoding)
6061         {
6062             case eEncodingT1:
6063                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6064                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6065                 t = Bits32 (opcode, 2, 0);
6066                 n = Bits32 (opcode, 5, 3);
6067                 m = Bits32 (opcode, 8, 6);
6068 
6069                 // index = TRUE; add = TRUE; wback = FALSE;
6070                 index = true;
6071                 add = true;
6072                 wback = false;
6073 
6074                 // (shift_t, shift_n) = (SRType_LSL, 0);
6075                 shift_t = SRType_LSL;
6076                 shift_n = 0;
6077 
6078                 break;
6079 
6080             case eEncodingT2:
6081                 // if Rn == '1111' then SEE LDR (literal);
6082                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6083                 t = Bits32 (opcode, 15, 12);
6084                 n = Bits32 (opcode, 19, 16);
6085                 m = Bits32 (opcode, 3, 0);
6086 
6087                 // index = TRUE; add = TRUE; wback = FALSE;
6088                 index = true;
6089                 add = true;
6090                 wback = false;
6091 
6092                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6093                 shift_t = SRType_LSL;
6094                 shift_n = Bits32 (opcode, 5, 4);
6095 
6096                 // if BadReg(m) then UNPREDICTABLE;
6097                 if (BadReg (m))
6098                     return false;
6099 
6100                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
6101                 if ((t == 15) && InITBlock() && !LastInITBlock())
6102                     return false;
6103 
6104                 break;
6105 
6106             case eEncodingA1:
6107             {
6108                 // if P == '0' && W == '1' then SEE LDRT;
6109                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6110                 t = Bits32 (opcode, 15, 12);
6111                 n = Bits32 (opcode, 19, 16);
6112                 m = Bits32 (opcode, 3, 0);
6113 
6114                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6115                 index = BitIsSet (opcode, 24);
6116                 add = BitIsSet (opcode, 23);
6117                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6118 
6119                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6120                 uint32_t type = Bits32 (opcode, 6, 5);
6121                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6122                 shift_n = DecodeImmShift (type, imm5, shift_t);
6123 
6124                 // if m == 15 then UNPREDICTABLE;
6125                 if (m == 15)
6126                     return false;
6127 
6128                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6129                 if (wback && ((n == 15) || (n == t)))
6130                     return false;
6131             }
6132                 break;
6133 
6134 
6135             default:
6136                 return false;
6137         }
6138 
6139         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6140         if (!success)
6141             return false;
6142 
6143         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6144         if (!success)
6145             return false;
6146 
6147         addr_t offset_addr;
6148         addr_t address;
6149 
6150         // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an application level alias for the CPSR".
6151         addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success);
6152         if (!success)
6153             return false;
6154 
6155         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6156         if (add)
6157             offset_addr = Rn + offset;
6158         else
6159             offset_addr = Rn - offset;
6160 
6161         // address = if index then offset_addr else R[n];
6162             if (index)
6163                 address = offset_addr;
6164             else
6165                 address = Rn;
6166 
6167         // data = MemU[address,4];
6168         RegisterInfo base_reg;
6169         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6170 
6171         EmulateInstruction::Context context;
6172         context.type = eContextRegisterLoad;
6173         context.SetRegisterPlusOffset (base_reg, address - Rn);
6174 
6175         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
6176         if (!success)
6177             return false;
6178 
6179         // if wback then R[n] = offset_addr;
6180         if (wback)
6181         {
6182             context.type = eContextAdjustBaseRegister;
6183             context.SetAddress (offset_addr);
6184             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6185                 return false;
6186         }
6187 
6188         // if t == 15 then
6189         if (t == 15)
6190         {
6191             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6192             if (BitIsClear (address, 1) && BitIsClear (address, 0))
6193             {
6194                 context.type = eContextRegisterLoad;
6195                 context.SetRegisterPlusOffset (base_reg, address - Rn);
6196                 LoadWritePC (context, data);
6197             }
6198             else
6199                 return false;
6200         }
6201         // elsif UnalignedSupport() || address<1:0> = '00' then
6202         else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
6203         {
6204             // R[t] = data;
6205             context.type = eContextRegisterLoad;
6206             context.SetRegisterPlusOffset (base_reg, address - Rn);
6207             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6208                 return false;
6209         }
6210         else // Can only apply before ARMv7
6211         {
6212             // if CurrentInstrSet() == InstrSet_ARM then
6213             if (CurrentInstrSet () == eModeARM)
6214             {
6215                 // R[t] = ROR(data, 8*UInt(address<1:0>));
6216                 data = ROR (data, Bits32 (address, 1, 0), &success);
6217                 if (!success)
6218                     return false;
6219                 context.type = eContextRegisterLoad;
6220                 context.SetImmediate (data);
6221                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6222                     return false;
6223             }
6224             else
6225             {
6226                 // R[t] = bits(32) UNKNOWN;
6227                 WriteBits32Unknown (t);
6228             }
6229         }
6230     }
6231     return true;
6232 }
6233 
6234 // LDRB (immediate, Thumb)
6235 bool
6236 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6237 {
6238 #if 0
6239     if ConditionPassed() then
6240         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6241         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6242         address = if index then offset_addr else R[n];
6243         R[t] = ZeroExtend(MemU[address,1], 32);
6244         if wback then R[n] = offset_addr;
6245 #endif
6246 
6247     bool success = false;
6248 
6249     if (ConditionPassed(opcode))
6250     {
6251         uint32_t t;
6252         uint32_t n;
6253         uint32_t imm32;
6254         bool index;
6255         bool add;
6256         bool wback;
6257 
6258         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6259         switch (encoding)
6260         {
6261             case eEncodingT1:
6262                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6263                 t = Bits32 (opcode, 2, 0);
6264                 n = Bits32 (opcode, 5, 3);
6265                 imm32 = Bits32 (opcode, 10, 6);
6266 
6267                 // index = TRUE; add = TRUE; wback = FALSE;
6268                 index = true;
6269                 add = true;
6270                 wback= false;
6271 
6272                 break;
6273 
6274             case eEncodingT2:
6275                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6276                 t = Bits32 (opcode, 15, 12);
6277                 n = Bits32 (opcode, 19, 16);
6278                 imm32 = Bits32 (opcode, 11, 0);
6279 
6280                 // index = TRUE; add = TRUE; wback = FALSE;
6281                 index = true;
6282                 add = true;
6283                 wback = false;
6284 
6285                 // if Rt == '1111' then SEE PLD;
6286                 if (t == 15)
6287                     return false; // PLD is not implemented yet
6288 
6289                 // if Rn == '1111' then SEE LDRB (literal);
6290                 if (n == 15)
6291                     return EmulateLDRBLiteral(opcode, eEncodingT1);
6292 
6293                 // if t == 13 then UNPREDICTABLE;
6294                 if (t == 13)
6295                     return false;
6296 
6297                 break;
6298 
6299             case eEncodingT3:
6300                 // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6301                 // if P == '0' && W == '0' then UNDEFINED;
6302                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6303                     return false;
6304 
6305                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6306                 t = Bits32 (opcode, 15, 12);
6307                 n = Bits32 (opcode, 19, 16);
6308                 imm32 = Bits32 (opcode, 7, 0);
6309 
6310                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6311                 index = BitIsSet (opcode, 10);
6312                 add = BitIsSet (opcode, 9);
6313                 wback = BitIsSet (opcode, 8);
6314 
6315                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6316                 if (t == 15)
6317                     return false; // PLD is not implemented yet
6318 
6319                 // if Rn == '1111' then SEE LDRB (literal);
6320                 if (n == 15)
6321                     return EmulateLDRBLiteral(opcode, eEncodingT1);
6322 
6323                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6324                 if (BadReg (t) || (wback && (n == t)))
6325                     return false;
6326 
6327                 break;
6328 
6329             default:
6330                 return false;
6331         }
6332 
6333         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6334         if (!success)
6335             return false;
6336 
6337         addr_t address;
6338         addr_t offset_addr;
6339 
6340         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6341         if (add)
6342             offset_addr = Rn + imm32;
6343         else
6344             offset_addr = Rn - imm32;
6345 
6346         // address = if index then offset_addr else R[n];
6347         if (index)
6348             address = offset_addr;
6349         else
6350             address = Rn;
6351 
6352         // R[t] = ZeroExtend(MemU[address,1], 32);
6353         RegisterInfo base_reg;
6354         RegisterInfo data_reg;
6355         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6356         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6357 
6358         EmulateInstruction::Context context;
6359         context.type = eContextRegisterLoad;
6360         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
6361 
6362         uint64_t data = MemURead (context, address, 1, 0, &success);
6363         if (!success)
6364             return false;
6365 
6366         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6367             return false;
6368 
6369         // if wback then R[n] = offset_addr;
6370         if (wback)
6371         {
6372             context.type = eContextAdjustBaseRegister;
6373             context.SetAddress (offset_addr);
6374             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6375                 return false;
6376         }
6377     }
6378     return true;
6379 }
6380 
6381 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6382 // zero-extends it to form a 32-bit word and writes it to a register.
6383 bool
6384 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6385 {
6386 #if 0
6387     if ConditionPassed() then
6388         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6389         base = Align(PC,4);
6390         address = if add then (base + imm32) else (base - imm32);
6391         R[t] = ZeroExtend(MemU[address,1], 32);
6392 #endif
6393 
6394     bool success = false;
6395 
6396     if (ConditionPassed(opcode))
6397     {
6398         uint32_t t;
6399         uint32_t imm32;
6400         bool add;
6401         switch (encoding)
6402         {
6403             case eEncodingT1:
6404                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6405                 t = Bits32 (opcode, 15, 12);
6406                 imm32 = Bits32 (opcode, 11, 0);
6407                 add = BitIsSet (opcode, 23);
6408 
6409                 // if Rt == '1111' then SEE PLD;
6410                 if (t == 15)
6411                     return false; // PLD is not implemented yet
6412 
6413                 // if t == 13 then UNPREDICTABLE;
6414                 if (t == 13)
6415                     return false;
6416 
6417                 break;
6418 
6419             case eEncodingA1:
6420                 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6421                 t = Bits32 (opcode, 15, 12);
6422                 imm32 = Bits32 (opcode, 11, 0);
6423                 add = BitIsSet (opcode, 23);
6424 
6425                 // if t == 15 then UNPREDICTABLE;
6426                 if (t == 15)
6427                     return false;
6428                 break;
6429 
6430             default:
6431                 return false;
6432         }
6433 
6434         // base = Align(PC,4);
6435         uint32_t pc_val = ReadCoreReg (PC_REG, &success);
6436         if (!success)
6437             return false;
6438 
6439         uint32_t base = AlignPC (pc_val);
6440 
6441         addr_t address;
6442         // address = if add then (base + imm32) else (base - imm32);
6443         if (add)
6444             address = base + imm32;
6445         else
6446             address = base - imm32;
6447 
6448         // R[t] = ZeroExtend(MemU[address,1], 32);
6449         EmulateInstruction::Context context;
6450         context.type = eContextRelativeBranchImmediate;
6451         context.SetImmediate (address - base);
6452 
6453         uint64_t data = MemURead (context, address, 1, 0, &success);
6454         if (!success)
6455             return false;
6456 
6457         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6458             return false;
6459     }
6460     return true;
6461 }
6462 
6463 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from
6464 // memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6465 // optionally be shifted.
6466 bool
6467 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding)
6468 {
6469 #if 0
6470     if ConditionPassed() then
6471         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6472         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6473         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6474         address = if index then offset_addr else R[n];
6475         R[t] = ZeroExtend(MemU[address,1],32);
6476         if wback then R[n] = offset_addr;
6477 #endif
6478 
6479     bool success = false;
6480 
6481     if (ConditionPassed(opcode))
6482     {
6483         uint32_t t;
6484         uint32_t n;
6485         uint32_t m;
6486         bool index;
6487         bool add;
6488         bool wback;
6489         ARM_ShifterType shift_t;
6490         uint32_t shift_n;
6491 
6492         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6493         switch (encoding)
6494         {
6495             case eEncodingT1:
6496                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6497                 t = Bits32 (opcode, 2, 0);
6498                 n = Bits32 (opcode, 5, 3);
6499                 m = Bits32 (opcode, 8, 6);
6500 
6501                 // index = TRUE; add = TRUE; wback = FALSE;
6502                 index = true;
6503                 add = true;
6504                 wback = false;
6505 
6506                 // (shift_t, shift_n) = (SRType_LSL, 0);
6507                 shift_t = SRType_LSL;
6508                 shift_n = 0;
6509                 break;
6510 
6511             case eEncodingT2:
6512                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6513                 t = Bits32 (opcode, 15, 12);
6514                 n = Bits32 (opcode, 19, 16);
6515                 m = Bits32 (opcode, 3, 0);
6516 
6517                 // index = TRUE; add = TRUE; wback = FALSE;
6518                 index = true;
6519                 add = true;
6520                 wback = false;
6521 
6522                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6523                 shift_t = SRType_LSL;
6524                 shift_n = Bits32 (opcode, 5, 4);
6525 
6526                 // if Rt == '1111' then SEE PLD;
6527                 if (t == 15)
6528                     return false; // PLD is not implemented yet
6529 
6530                 // if Rn == '1111' then SEE LDRB (literal);
6531                 if (n == 15)
6532                     return EmulateLDRBLiteral(opcode, eEncodingT1);
6533 
6534                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6535                 if ((t == 13) || BadReg (m))
6536                     return false;
6537                 break;
6538 
6539             case eEncodingA1:
6540             {
6541                 // if P == '0' && W == '1' then SEE LDRBT;
6542                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6543                 t = Bits32 (opcode, 15, 12);
6544                 n = Bits32 (opcode, 19, 16);
6545                 m = Bits32 (opcode, 3, 0);
6546 
6547                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6548                 index = BitIsSet (opcode, 24);
6549                 add = BitIsSet (opcode, 23);
6550                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6551 
6552                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6553                 uint32_t type = Bits32 (opcode, 6, 5);
6554                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6555                 shift_n = DecodeImmShift (type, imm5, shift_t);
6556 
6557                 // if t == 15 || m == 15 then UNPREDICTABLE;
6558                 if ((t == 15) || (m == 15))
6559                     return false;
6560 
6561                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6562                 if (wback && ((n == 15) || (n == t)))
6563                     return false;
6564             }
6565                 break;
6566 
6567             default:
6568                 return false;
6569         }
6570 
6571         addr_t offset_addr;
6572         addr_t address;
6573 
6574         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6575         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6576         if (!success)
6577             return false;
6578 
6579         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6580         if (!success)
6581             return false;
6582 
6583         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6584         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6585         if (!success)
6586             return false;
6587 
6588         if (add)
6589             offset_addr = Rn + offset;
6590         else
6591             offset_addr = Rn - offset;
6592 
6593         // address = if index then offset_addr else R[n];
6594         if (index)
6595             address = offset_addr;
6596         else
6597             address = Rn;
6598 
6599         // R[t] = ZeroExtend(MemU[address,1],32);
6600         RegisterInfo base_reg;
6601         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6602 
6603         EmulateInstruction::Context context;
6604         context.type = eContextRegisterLoad;
6605         context.SetRegisterPlusOffset (base_reg, address - Rn);
6606 
6607         uint64_t data = MemURead (context, address, 1, 0, &success);
6608         if (!success)
6609             return false;
6610 
6611         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6612             return false;
6613 
6614         // if wback then R[n] = offset_addr;
6615         if (wback)
6616         {
6617             context.type = eContextAdjustBaseRegister;
6618             context.SetAddress (offset_addr);
6619             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6620                 return false;
6621         }
6622     }
6623     return true;
6624 }
6625 
6626 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a
6627 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register.  It can use offset,
6628 // post-indexed, or pre-indexed addressing.
6629 bool
6630 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding)
6631 {
6632 #if 0
6633     if ConditionPassed() then
6634         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6635         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6636         address = if index then offset_addr else R[n];
6637         data = MemU[address,2];
6638         if wback then R[n] = offset_addr;
6639         if UnalignedSupport() || address<0> = '0' then
6640             R[t] = ZeroExtend(data, 32);
6641         else // Can only apply before ARMv7
6642             R[t] = bits(32) UNKNOWN;
6643 #endif
6644 
6645 
6646     bool success = false;
6647 
6648     if (ConditionPassed(opcode))
6649     {
6650         uint32_t t;
6651         uint32_t n;
6652         uint32_t imm32;
6653         bool index;
6654         bool add;
6655         bool wback;
6656 
6657         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6658         switch (encoding)
6659         {
6660             case eEncodingT1:
6661                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
6662                 t = Bits32 (opcode, 2, 0);
6663                 n = Bits32 (opcode, 5, 3);
6664                 imm32 = Bits32 (opcode, 10, 6) << 1;
6665 
6666                 // index = TRUE; add = TRUE; wback = FALSE;
6667                 index = true;
6668                 add = true;
6669                 wback = false;
6670 
6671                 break;
6672 
6673             case eEncodingT2:
6674                 // if Rt == '1111' then SEE "Unallocated memory hints";
6675                 // if Rn == '1111' then SEE LDRH (literal);
6676                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6677                 t = Bits32 (opcode, 15, 12);
6678                 n = Bits32 (opcode, 19, 16);
6679                 imm32 = Bits32 (opcode, 11, 0);
6680 
6681                 // index = TRUE; add = TRUE; wback = FALSE;
6682                 index = true;
6683                 add = true;
6684                 wback = false;
6685 
6686                 // if t == 13 then UNPREDICTABLE;
6687                 if (t == 13)
6688                     return false;
6689                 break;
6690 
6691             case eEncodingT3:
6692                 // if Rn == '1111' then SEE LDRH (literal);
6693                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
6694                 // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
6695                 // if P == '0' && W == '0' then UNDEFINED;
6696                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6697                     return false;
6698 
6699                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6700                 t = Bits32 (opcode, 15, 12);
6701                 n = Bits32 (opcode, 19, 16);
6702                 imm32 = Bits32 (opcode, 7, 0);
6703 
6704                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6705                 index = BitIsSet (opcode, 10);
6706                 add = BitIsSet (opcode, 9);
6707                 wback = BitIsSet (opcode, 8);
6708 
6709                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6710                 if (BadReg (t) || (wback && (n == t)))
6711                     return false;
6712                 break;
6713 
6714             default:
6715                 return false;
6716         }
6717 
6718         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6719         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6720         if (!success)
6721             return false;
6722 
6723         addr_t offset_addr;
6724         addr_t address;
6725 
6726         if (add)
6727             offset_addr = Rn + imm32;
6728         else
6729             offset_addr = Rn - imm32;
6730 
6731         // address = if index then offset_addr else R[n];
6732         if (index)
6733             address = offset_addr;
6734         else
6735             address = Rn;
6736 
6737         // data = MemU[address,2];
6738         RegisterInfo base_reg;
6739         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6740 
6741         EmulateInstruction::Context context;
6742         context.type = eContextRegisterLoad;
6743         context.SetRegisterPlusOffset (base_reg, address - Rn);
6744 
6745         uint64_t data = MemURead (context, address, 2, 0, &success);
6746         if (!success)
6747             return false;
6748 
6749         // if wback then R[n] = offset_addr;
6750         if (wback)
6751         {
6752             context.type = eContextAdjustBaseRegister;
6753             context.SetAddress (offset_addr);
6754             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6755                 return false;
6756         }
6757 
6758         // if UnalignedSupport() || address<0> = '0' then
6759         if (UnalignedSupport () || BitIsClear (address, 0))
6760         {
6761             // R[t] = ZeroExtend(data, 32);
6762             context.type = eContextRegisterLoad;
6763             context.SetRegisterPlusOffset (base_reg, address - Rn);
6764             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6765                 return false;
6766         }
6767         else // Can only apply before ARMv7
6768         {
6769             // R[t] = bits(32) UNKNOWN;
6770             WriteBits32Unknown (t);
6771         }
6772     }
6773     return true;
6774 }
6775 
6776 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory,
6777 // zero-extends it to form a 32-bit word, and writes it to a register.
6778 bool
6779 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding)
6780 {
6781 #if 0
6782     if ConditionPassed() then
6783         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6784         base = Align(PC,4);
6785         address = if add then (base + imm32) else (base - imm32);
6786         data = MemU[address,2];
6787         if UnalignedSupport() || address<0> = '0' then
6788             R[t] = ZeroExtend(data, 32);
6789         else // Can only apply before ARMv7
6790             R[t] = bits(32) UNKNOWN;
6791 #endif
6792 
6793     bool success = false;
6794 
6795     if (ConditionPassed(opcode))
6796     {
6797         uint32_t t;
6798         uint32_t imm32;
6799         bool add;
6800 
6801         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6802         switch (encoding)
6803         {
6804             case eEncodingT1:
6805                 // if Rt == '1111' then SEE "Unallocated memory hints";
6806                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6807                 t = Bits32 (opcode, 15, 12);
6808                 imm32 = Bits32 (opcode, 11, 0);
6809                 add = BitIsSet (opcode, 23);
6810 
6811                 // if t == 13 then UNPREDICTABLE;
6812                 if (t == 13)
6813                     return false;
6814 
6815                 break;
6816 
6817             case eEncodingA1:
6818             {
6819                 uint32_t imm4H = Bits32 (opcode, 11, 8);
6820                 uint32_t imm4L = Bits32 (opcode, 3, 0);
6821 
6822                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6823                 t = Bits32 (opcode, 15, 12);
6824                 imm32 = (imm4H << 4) | imm4L;
6825                 add = BitIsSet (opcode, 23);
6826 
6827                 // if t == 15 then UNPREDICTABLE;
6828                 if (t == 15)
6829                     return false;
6830                 break;
6831             }
6832 
6833             default:
6834                 return false;
6835         }
6836 
6837         // base = Align(PC,4);
6838         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6839         if (!success)
6840             return false;
6841 
6842         addr_t base = AlignPC (pc_value);
6843         addr_t address;
6844 
6845         // address = if add then (base + imm32) else (base - imm32);
6846         if (add)
6847             address = base + imm32;
6848         else
6849             address = base - imm32;
6850 
6851         // data = MemU[address,2];
6852         RegisterInfo base_reg;
6853         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
6854 
6855         EmulateInstruction::Context context;
6856         context.type = eContextRegisterLoad;
6857         context.SetRegisterPlusOffset (base_reg, address - base);
6858 
6859         uint64_t data = MemURead (context, address, 2, 0, &success);
6860         if (!success)
6861             return false;
6862 
6863 
6864         // if UnalignedSupport() || address<0> = '0' then
6865         if (UnalignedSupport () || BitIsClear (address, 0))
6866         {
6867             // R[t] = ZeroExtend(data, 32);
6868             context.type = eContextRegisterLoad;
6869             context.SetRegisterPlusOffset (base_reg, address - base);
6870             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6871                 return false;
6872 
6873         }
6874         else // Can only apply before ARMv7
6875         {
6876             // R[t] = bits(32) UNKNOWN;
6877             WriteBits32Unknown (t);
6878         }
6879     }
6880     return true;
6881 }
6882 
6883 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword
6884 // from memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6885 // be shifted left by 0, 1, 2, or 3 bits.
6886 bool
6887 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding)
6888 {
6889 #if 0
6890     if ConditionPassed() then
6891         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6892         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6893         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6894         address = if index then offset_addr else R[n];
6895         data = MemU[address,2];
6896         if wback then R[n] = offset_addr;
6897         if UnalignedSupport() || address<0> = '0' then
6898             R[t] = ZeroExtend(data, 32);
6899         else // Can only apply before ARMv7
6900             R[t] = bits(32) UNKNOWN;
6901 #endif
6902 
6903     bool success = false;
6904 
6905     if (ConditionPassed(opcode))
6906     {
6907         uint32_t t;
6908         uint32_t n;
6909         uint32_t m;
6910         bool index;
6911         bool add;
6912         bool wback;
6913         ARM_ShifterType shift_t;
6914         uint32_t shift_n;
6915 
6916         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6917         switch (encoding)
6918         {
6919             case eEncodingT1:
6920                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6921                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6922                 t = Bits32 (opcode, 2, 0);
6923                 n = Bits32 (opcode, 5, 3);
6924                 m = Bits32 (opcode, 8, 6);
6925 
6926                 // index = TRUE; add = TRUE; wback = FALSE;
6927                 index = true;
6928                 add = true;
6929                 wback = false;
6930 
6931                 // (shift_t, shift_n) = (SRType_LSL, 0);
6932                 shift_t = SRType_LSL;
6933                 shift_n = 0;
6934 
6935                 break;
6936 
6937             case eEncodingT2:
6938                 // if Rn == '1111' then SEE LDRH (literal);
6939                 // if Rt == '1111' then SEE "Unallocated memory hints";
6940                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6941                 t = Bits32 (opcode, 15, 12);
6942                 n = Bits32 (opcode, 19, 16);
6943                 m = Bits32 (opcode, 3, 0);
6944 
6945                 // index = TRUE; add = TRUE; wback = FALSE;
6946                 index = true;
6947                 add = true;
6948                 wback = false;
6949 
6950                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6951                 shift_t = SRType_LSL;
6952                 shift_n = Bits32 (opcode, 5, 4);
6953 
6954                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6955                 if ((t == 13) || BadReg (m))
6956                     return false;
6957                 break;
6958 
6959             case eEncodingA1:
6960                 // if P == '0' && W == '1' then SEE LDRHT;
6961                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6962                 t = Bits32 (opcode, 15, 12);
6963                 n = Bits32 (opcode, 19, 16);
6964                 m = Bits32 (opcode, 3, 0);
6965 
6966                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6967                 index = BitIsSet (opcode, 24);
6968                 add = BitIsSet (opcode, 23);
6969                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6970 
6971                 // (shift_t, shift_n) = (SRType_LSL, 0);
6972                 shift_t = SRType_LSL;
6973                 shift_n = 0;
6974 
6975                 // if t == 15 || m == 15 then UNPREDICTABLE;
6976                 if ((t == 15) || (m == 15))
6977                     return false;
6978 
6979                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6980                 if (wback && ((n == 15) || (n == t)))
6981                     return false;
6982 
6983                 break;
6984 
6985             default:
6986                 return false;
6987         }
6988 
6989         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6990 
6991         uint64_t Rm  = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6992         if (!success)
6993             return false;
6994 
6995         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6996         if (!success)
6997             return false;
6998 
6999         addr_t offset_addr;
7000         addr_t address;
7001 
7002         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7003         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7004         if (!success)
7005             return false;
7006 
7007         if (add)
7008             offset_addr = Rn + offset;
7009         else
7010             offset_addr = Rn - offset;
7011 
7012         // address = if index then offset_addr else R[n];
7013         if (index)
7014             address = offset_addr;
7015         else
7016             address = Rn;
7017 
7018         // data = MemU[address,2];
7019         RegisterInfo base_reg;
7020         RegisterInfo offset_reg;
7021         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7022         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7023 
7024         EmulateInstruction::Context context;
7025         context.type = eContextRegisterLoad;
7026         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7027         uint64_t data = MemURead (context, address, 2, 0, &success);
7028         if (!success)
7029             return false;
7030 
7031         // if wback then R[n] = offset_addr;
7032         if (wback)
7033         {
7034             context.type = eContextAdjustBaseRegister;
7035             context.SetAddress (offset_addr);
7036             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7037                 return false;
7038         }
7039 
7040         // if UnalignedSupport() || address<0> = '0' then
7041         if (UnalignedSupport() || BitIsClear (address, 0))
7042         {
7043             // R[t] = ZeroExtend(data, 32);
7044             context.type = eContextRegisterLoad;
7045             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7046             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
7047                 return false;
7048         }
7049         else // Can only apply before ARMv7
7050         {
7051             // R[t] = bits(32) UNKNOWN;
7052             WriteBits32Unknown (t);
7053         }
7054     }
7055     return true;
7056 }
7057 
7058 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from
7059 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed,
7060 // or pre-indexed addressing.
7061 bool
7062 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding)
7063 {
7064 #if 0
7065     if ConditionPassed() then
7066         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7067         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7068         address = if index then offset_addr else R[n];
7069         R[t] = SignExtend(MemU[address,1], 32);
7070         if wback then R[n] = offset_addr;
7071 #endif
7072 
7073     bool success = false;
7074 
7075     if (ConditionPassed(opcode))
7076     {
7077         uint32_t t;
7078         uint32_t n;
7079         uint32_t imm32;
7080         bool index;
7081         bool add;
7082         bool wback;
7083 
7084         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7085         switch (encoding)
7086         {
7087             case eEncodingT1:
7088                 // if Rt == '1111' then SEE PLI;
7089                 // if Rn == '1111' then SEE LDRSB (literal);
7090                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7091                 t = Bits32 (opcode, 15, 12);
7092                 n = Bits32 (opcode, 19, 16);
7093                 imm32 = Bits32 (opcode, 11, 0);
7094 
7095                 // index = TRUE; add = TRUE; wback = FALSE;
7096                 index = true;
7097                 add = true;
7098                 wback = false;
7099 
7100                 // if t == 13 then UNPREDICTABLE;
7101                 if (t == 13)
7102                     return false;
7103 
7104                 break;
7105 
7106             case eEncodingT2:
7107                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
7108                 // if Rn == '1111' then SEE LDRSB (literal);
7109                 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
7110                 // if P == '0' && W == '0' then UNDEFINED;
7111                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7112                     return false;
7113 
7114                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7115                 t = Bits32 (opcode, 15, 12);
7116                 n = Bits32 (opcode, 19, 16);
7117                 imm32 = Bits32 (opcode, 7, 0);
7118 
7119                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7120                 index = BitIsSet (opcode, 10);
7121                 add = BitIsSet (opcode, 9);
7122                 wback = BitIsSet (opcode, 8);
7123 
7124                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7125                   if (((t == 13) || ((t == 15)
7126                                      && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8))))
7127                       || (wback && (n == t)))
7128                     return false;
7129 
7130                 break;
7131 
7132             case eEncodingA1:
7133             {
7134                 // if Rn == '1111' then SEE LDRSB (literal);
7135                 // if P == '0' && W == '1' then SEE LDRSBT;
7136                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7137                 t = Bits32 (opcode, 15, 12);
7138                 n = Bits32 (opcode, 19, 16);
7139 
7140                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7141                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7142                 imm32 = (imm4H << 4) | imm4L;
7143 
7144                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7145                 index = BitIsSet (opcode, 24);
7146                 add = BitIsSet (opcode, 23);
7147                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
7148 
7149                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7150                 if ((t == 15) || (wback && (n == t)))
7151                     return false;
7152 
7153                 break;
7154             }
7155 
7156             default:
7157                 return false;
7158         }
7159 
7160         uint64_t Rn = ReadCoreReg (n, &success);
7161         if (!success)
7162             return false;
7163 
7164         addr_t offset_addr;
7165         addr_t address;
7166 
7167         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7168         if (add)
7169             offset_addr = Rn + imm32;
7170         else
7171             offset_addr = Rn - imm32;
7172 
7173         // address = if index then offset_addr else R[n];
7174         if (index)
7175             address = offset_addr;
7176         else
7177             address = Rn;
7178 
7179         // R[t] = SignExtend(MemU[address,1], 32);
7180         RegisterInfo base_reg;
7181         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7182 
7183         EmulateInstruction::Context context;
7184         context.type = eContextRegisterLoad;
7185         context.SetRegisterPlusOffset (base_reg, address - Rn);
7186 
7187         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7188         if (!success)
7189             return false;
7190 
7191         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7192         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7193             return false;
7194 
7195         // if wback then R[n] = offset_addr;
7196         if (wback)
7197         {
7198             context.type = eContextAdjustBaseRegister;
7199             context.SetAddress (offset_addr);
7200             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7201                 return false;
7202         }
7203     }
7204 
7205     return true;
7206 }
7207 
7208 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
7209 // sign-extends it to form a 32-bit word, and writes tit to a register.
7210 bool
7211 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding)
7212 {
7213 #if 0
7214     if ConditionPassed() then
7215         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7216         base = Align(PC,4);
7217         address = if add then (base + imm32) else (base - imm32);
7218         R[t] = SignExtend(MemU[address,1], 32);
7219 #endif
7220 
7221     bool success = false;
7222 
7223     if (ConditionPassed(opcode))
7224     {
7225         uint32_t t;
7226         uint32_t imm32;
7227         bool add;
7228 
7229         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7230         switch (encoding)
7231         {
7232             case eEncodingT1:
7233                 // if Rt == '1111' then SEE PLI;
7234                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7235                 t = Bits32 (opcode, 15, 12);
7236                 imm32 = Bits32 (opcode, 11, 0);
7237                 add = BitIsSet (opcode, 23);
7238 
7239                 // if t == 13 then UNPREDICTABLE;
7240                 if (t == 13)
7241                     return false;
7242 
7243                 break;
7244 
7245             case eEncodingA1:
7246             {
7247                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7248                 t = Bits32 (opcode, 15, 12);
7249                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7250                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7251                 imm32 = (imm4H << 4) | imm4L;
7252                 add = BitIsSet (opcode, 23);
7253 
7254                 // if t == 15 then UNPREDICTABLE;
7255                 if (t == 15)
7256                     return false;
7257 
7258                 break;
7259             }
7260 
7261             default:
7262                 return false;
7263         }
7264 
7265         // base = Align(PC,4);
7266         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7267         if (!success)
7268             return false;
7269         uint64_t base = AlignPC (pc_value);
7270 
7271         // address = if add then (base + imm32) else (base - imm32);
7272         addr_t address;
7273         if (add)
7274             address = base + imm32;
7275         else
7276             address = base - imm32;
7277 
7278         // R[t] = SignExtend(MemU[address,1], 32);
7279         RegisterInfo base_reg;
7280         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7281 
7282         EmulateInstruction::Context context;
7283         context.type = eContextRegisterLoad;
7284         context.SetRegisterPlusOffset (base_reg, address - base);
7285 
7286         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7287         if (!success)
7288             return false;
7289 
7290         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7291         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7292             return false;
7293     }
7294     return true;
7295 }
7296 
7297 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from
7298 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7299 // shifted left by 0, 1, 2, or 3 bits.
7300 bool
7301 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding)
7302 {
7303 #if 0
7304     if ConditionPassed() then
7305         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7306         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7307         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7308         address = if index then offset_addr else R[n];
7309         R[t] = SignExtend(MemU[address,1], 32);
7310         if wback then R[n] = offset_addr;
7311 #endif
7312 
7313     bool success = false;
7314 
7315     if (ConditionPassed(opcode))
7316     {
7317         uint32_t t;
7318         uint32_t n;
7319         uint32_t m;
7320         bool index;
7321         bool add;
7322         bool wback;
7323         ARM_ShifterType shift_t;
7324         uint32_t shift_n;
7325 
7326         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7327         switch (encoding)
7328         {
7329             case eEncodingT1:
7330                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7331                 t = Bits32 (opcode, 2, 0);
7332                 n = Bits32 (opcode, 5, 3);
7333                 m = Bits32 (opcode, 8, 6);
7334 
7335                 // index = TRUE; add = TRUE; wback = FALSE;
7336                 index = true;
7337                 add = true;
7338                 wback = false;
7339 
7340                 // (shift_t, shift_n) = (SRType_LSL, 0);
7341                 shift_t = SRType_LSL;
7342                 shift_n = 0;
7343 
7344                 break;
7345 
7346             case eEncodingT2:
7347                 // if Rt == '1111' then SEE PLI;
7348                 // if Rn == '1111' then SEE LDRSB (literal);
7349                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7350                 t = Bits32 (opcode, 15, 12);
7351                 n = Bits32 (opcode, 19, 16);
7352                 m = Bits32 (opcode, 3, 0);
7353 
7354                 // index = TRUE; add = TRUE; wback = FALSE;
7355                 index = true;
7356                 add = true;
7357                 wback = false;
7358 
7359                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7360                 shift_t = SRType_LSL;
7361                 shift_n = Bits32 (opcode, 5, 4);
7362 
7363                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7364                 if ((t == 13) || BadReg (m))
7365                     return false;
7366                 break;
7367 
7368             case eEncodingA1:
7369                 // if P == '0' && W == '1' then SEE LDRSBT;
7370                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7371                 t = Bits32 (opcode, 15, 12);
7372                 n = Bits32 (opcode, 19, 16);
7373                 m = Bits32 (opcode, 3, 0);
7374 
7375                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7376                 index = BitIsSet (opcode, 24);
7377                 add = BitIsSet (opcode, 23);
7378                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7379 
7380                 // (shift_t, shift_n) = (SRType_LSL, 0);
7381                 shift_t = SRType_LSL;
7382                 shift_n = 0;
7383 
7384                 // if t == 15 || m == 15 then UNPREDICTABLE;
7385                 if ((t == 15) || (m == 15))
7386                     return false;
7387 
7388                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7389                 if (wback && ((n == 15) || (n == t)))
7390                     return false;
7391                 break;
7392 
7393             default:
7394                 return false;
7395         }
7396 
7397         uint64_t Rm =  ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7398         if (!success)
7399             return false;
7400 
7401         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7402         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7403         if (!success)
7404             return false;
7405 
7406         addr_t offset_addr;
7407         addr_t address;
7408 
7409         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7410         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7411         if (!success)
7412             return false;
7413 
7414         if (add)
7415             offset_addr = Rn + offset;
7416         else
7417             offset_addr = Rn - offset;
7418 
7419         // address = if index then offset_addr else R[n];
7420         if (index)
7421             address = offset_addr;
7422         else
7423             address = Rn;
7424 
7425         // R[t] = SignExtend(MemU[address,1], 32);
7426         RegisterInfo base_reg;
7427         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7428         RegisterInfo offset_reg;
7429         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7430 
7431         EmulateInstruction::Context context;
7432         context.type = eContextRegisterLoad;
7433         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7434 
7435         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7436         if (!success)
7437             return false;
7438 
7439         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7440         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7441             return false;
7442 
7443         // if wback then R[n] = offset_addr;
7444         if (wback)
7445         {
7446             context.type = eContextAdjustBaseRegister;
7447             context.SetAddress (offset_addr);
7448             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7449                 return false;
7450         }
7451     }
7452     return true;
7453 }
7454 
7455 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from
7456 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed, or
7457 // pre-indexed addressing.
7458 bool
7459 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding)
7460 {
7461 #if 0
7462     if ConditionPassed() then
7463         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7464         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7465         address = if index then offset_addr else R[n];
7466         data = MemU[address,2];
7467         if wback then R[n] = offset_addr;
7468         if UnalignedSupport() || address<0> = '0' then
7469             R[t] = SignExtend(data, 32);
7470         else // Can only apply before ARMv7
7471             R[t] = bits(32) UNKNOWN;
7472 #endif
7473 
7474     bool success = false;
7475 
7476     if (ConditionPassed(opcode))
7477     {
7478         uint32_t t;
7479         uint32_t n;
7480         uint32_t imm32;
7481         bool index;
7482         bool add;
7483         bool wback;
7484 
7485         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7486         switch (encoding)
7487         {
7488             case eEncodingT1:
7489                 // if Rn == '1111' then SEE LDRSH (literal);
7490                 // if Rt == '1111' then SEE "Unallocated memory hints";
7491                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7492                 t = Bits32 (opcode, 15, 12);
7493                 n = Bits32 (opcode, 19, 16);
7494                 imm32 = Bits32 (opcode, 11, 0);
7495 
7496                 // index = TRUE; add = TRUE; wback = FALSE;
7497                 index = true;
7498                 add = true;
7499                 wback = false;
7500 
7501                 // if t == 13 then UNPREDICTABLE;
7502                 if (t == 13)
7503                     return false;
7504 
7505                 break;
7506 
7507             case eEncodingT2:
7508                 // if Rn == '1111' then SEE LDRSH (literal);
7509                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
7510                 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7511                 // if P == '0' && W == '0' then UNDEFINED;
7512                   if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7513                   return false;
7514 
7515                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7516                 t = Bits32 (opcode, 15, 12);
7517                 n = Bits32 (opcode, 19, 16);
7518                 imm32 = Bits32 (opcode, 7, 0);
7519 
7520                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7521                 index = BitIsSet (opcode, 10);
7522                 add = BitIsSet (opcode, 9);
7523                 wback = BitIsSet (opcode, 8);
7524 
7525                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7526                 if (BadReg (t) || (wback && (n == t)))
7527                     return false;
7528 
7529                 break;
7530 
7531             case eEncodingA1:
7532             {
7533                 // if Rn == '1111' then SEE LDRSH (literal);
7534                 // if P == '0' && W == '1' then SEE LDRSHT;
7535                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7536                 t = Bits32 (opcode, 15, 12);
7537                 n = Bits32 (opcode, 19, 16);
7538                 uint32_t imm4H = Bits32 (opcode, 11,8);
7539                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7540                 imm32 = (imm4H << 4) | imm4L;
7541 
7542                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7543                 index = BitIsSet (opcode, 24);
7544                 add = BitIsSet (opcode, 23);
7545                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7546 
7547                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7548                 if ((t == 15) || (wback && (n == t)))
7549                     return false;
7550 
7551                 break;
7552             }
7553 
7554             default:
7555                 return false;
7556         }
7557 
7558         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7559         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7560         if (!success)
7561             return false;
7562 
7563         addr_t offset_addr;
7564         if (add)
7565             offset_addr = Rn + imm32;
7566         else
7567             offset_addr = Rn - imm32;
7568 
7569         // address = if index then offset_addr else R[n];
7570         addr_t address;
7571         if (index)
7572             address = offset_addr;
7573         else
7574             address = Rn;
7575 
7576         // data = MemU[address,2];
7577         RegisterInfo base_reg;
7578         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7579 
7580         EmulateInstruction::Context context;
7581         context.type = eContextRegisterLoad;
7582         context.SetRegisterPlusOffset (base_reg, address - Rn);
7583 
7584         uint64_t data = MemURead (context, address, 2, 0, &success);
7585         if (!success)
7586             return false;
7587 
7588         // if wback then R[n] = offset_addr;
7589         if (wback)
7590         {
7591             context.type = eContextAdjustBaseRegister;
7592             context.SetAddress (offset_addr);
7593             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7594                 return false;
7595         }
7596 
7597         // if UnalignedSupport() || address<0> = '0' then
7598         if (UnalignedSupport() || BitIsClear (address, 0))
7599         {
7600             // R[t] = SignExtend(data, 32);
7601             int64_t signed_data = llvm::SignExtend64<16>(data);
7602             context.type = eContextRegisterLoad;
7603             context.SetRegisterPlusOffset (base_reg, address - Rn);
7604             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7605                 return false;
7606         }
7607         else // Can only apply before ARMv7
7608         {
7609             // R[t] = bits(32) UNKNOWN;
7610             WriteBits32Unknown (t);
7611         }
7612     }
7613     return true;
7614 }
7615 
7616 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory,
7617 // sign-extends it to from a 32-bit word, and writes it to a register.
7618 bool
7619 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding)
7620 {
7621 #if 0
7622     if ConditionPassed() then
7623         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7624         base = Align(PC,4);
7625         address = if add then (base + imm32) else (base - imm32);
7626         data = MemU[address,2];
7627         if UnalignedSupport() || address<0> = '0' then
7628             R[t] = SignExtend(data, 32);
7629         else // Can only apply before ARMv7
7630             R[t] = bits(32) UNKNOWN;
7631 #endif
7632 
7633     bool success = false;
7634 
7635     if (ConditionPassed(opcode))
7636     {
7637         uint32_t t;
7638         uint32_t imm32;
7639         bool add;
7640 
7641         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7642         switch (encoding)
7643         {
7644             case eEncodingT1:
7645                 // if Rt == '1111' then SEE "Unallocated memory hints";
7646                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7647                 t = Bits32  (opcode, 15, 12);
7648                 imm32 = Bits32 (opcode, 11, 0);
7649                 add = BitIsSet (opcode, 23);
7650 
7651                 // if t == 13 then UNPREDICTABLE;
7652                 if (t == 13)
7653                     return false;
7654 
7655                 break;
7656 
7657             case eEncodingA1:
7658             {
7659                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7660                 t = Bits32 (opcode, 15, 12);
7661                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7662                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7663                 imm32 = (imm4H << 4) | imm4L;
7664                 add = BitIsSet (opcode, 23);
7665 
7666                 // if t == 15 then UNPREDICTABLE;
7667                 if (t == 15)
7668                     return false;
7669 
7670                 break;
7671             }
7672             default:
7673                 return false;
7674         }
7675 
7676         // base = Align(PC,4);
7677         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7678         if (!success)
7679             return false;
7680 
7681         uint64_t base = AlignPC (pc_value);
7682 
7683         addr_t address;
7684         // address = if add then (base + imm32) else (base - imm32);
7685         if (add)
7686             address = base + imm32;
7687         else
7688             address = base - imm32;
7689 
7690         // data = MemU[address,2];
7691         RegisterInfo base_reg;
7692         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7693 
7694         EmulateInstruction::Context context;
7695         context.type = eContextRegisterLoad;
7696         context.SetRegisterPlusOffset (base_reg, imm32);
7697 
7698         uint64_t data = MemURead (context, address, 2, 0, &success);
7699         if (!success)
7700             return false;
7701 
7702         // if UnalignedSupport() || address<0> = '0' then
7703         if (UnalignedSupport() || BitIsClear (address, 0))
7704         {
7705             // R[t] = SignExtend(data, 32);
7706             int64_t signed_data = llvm::SignExtend64<16>(data);
7707             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7708                 return false;
7709         }
7710         else // Can only apply before ARMv7
7711         {
7712             // R[t] = bits(32) UNKNOWN;
7713             WriteBits32Unknown (t);
7714         }
7715     }
7716     return true;
7717 }
7718 
7719 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword
7720 // from memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7721 // shifted left by 0, 1, 2, or 3 bits.
7722 bool
7723 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding)
7724 {
7725 #if 0
7726     if ConditionPassed() then
7727         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7728         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7729         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7730         address = if index then offset_addr else R[n];
7731         data = MemU[address,2];
7732         if wback then R[n] = offset_addr;
7733         if UnalignedSupport() || address<0> = '0' then
7734             R[t] = SignExtend(data, 32);
7735         else // Can only apply before ARMv7
7736             R[t] = bits(32) UNKNOWN;
7737 #endif
7738 
7739     bool success = false;
7740 
7741     if (ConditionPassed(opcode))
7742     {
7743         uint32_t t;
7744         uint32_t n;
7745         uint32_t m;
7746         bool index;
7747         bool add;
7748         bool wback;
7749         ARM_ShifterType shift_t;
7750         uint32_t shift_n;
7751 
7752         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7753         switch (encoding)
7754         {
7755             case eEncodingT1:
7756                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
7757                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7758                 t = Bits32 (opcode, 2, 0);
7759                 n = Bits32 (opcode, 5, 3);
7760                 m = Bits32 (opcode, 8, 6);
7761 
7762                 // index = TRUE; add = TRUE; wback = FALSE;
7763                 index = true;
7764                 add = true;
7765                 wback = false;
7766 
7767                 // (shift_t, shift_n) = (SRType_LSL, 0);
7768                 shift_t = SRType_LSL;
7769                 shift_n = 0;
7770 
7771                 break;
7772 
7773             case eEncodingT2:
7774                 // if Rn == '1111' then SEE LDRSH (literal);
7775                 // if Rt == '1111' then SEE "Unallocated memory hints";
7776                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7777                 t = Bits32 (opcode, 15, 12);
7778                 n = Bits32 (opcode, 19, 16);
7779                 m = Bits32 (opcode, 3, 0);
7780 
7781                 // index = TRUE; add = TRUE; wback = FALSE;
7782                 index = true;
7783                 add = true;
7784                 wback = false;
7785 
7786                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7787                 shift_t = SRType_LSL;
7788                 shift_n = Bits32 (opcode, 5, 4);
7789 
7790                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7791                 if ((t == 13) || BadReg (m))
7792                     return false;
7793 
7794                 break;
7795 
7796             case eEncodingA1:
7797                 // if P == '0' && W == '1' then SEE LDRSHT;
7798                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7799                 t = Bits32 (opcode, 15, 12);
7800                 n = Bits32 (opcode, 19, 16);
7801                 m = Bits32 (opcode, 3, 0);
7802 
7803                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7804                 index = BitIsSet (opcode, 24);
7805                 add = BitIsSet (opcode, 23);
7806                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7807 
7808                 // (shift_t, shift_n) = (SRType_LSL, 0);
7809                 shift_t = SRType_LSL;
7810                 shift_n = 0;
7811 
7812                 // if t == 15 || m == 15 then UNPREDICTABLE;
7813                 if ((t == 15) || (m == 15))
7814                     return false;
7815 
7816                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7817                 if (wback && ((n == 15) || (n == t)))
7818                     return false;
7819 
7820                 break;
7821 
7822             default:
7823                 return false;
7824         }
7825 
7826         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7827         if (!success)
7828             return false;
7829 
7830         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7831         if (!success)
7832             return false;
7833 
7834         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7835         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7836         if (!success)
7837             return false;
7838 
7839         addr_t offset_addr;
7840         addr_t address;
7841 
7842         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7843         if (add)
7844             offset_addr = Rn + offset;
7845         else
7846             offset_addr = Rn - offset;
7847 
7848         // address = if index then offset_addr else R[n];
7849         if (index)
7850             address = offset_addr;
7851         else
7852             address = Rn;
7853 
7854         // data = MemU[address,2];
7855         RegisterInfo base_reg;
7856         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7857 
7858         RegisterInfo offset_reg;
7859         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7860 
7861         EmulateInstruction::Context context;
7862         context.type = eContextRegisterLoad;
7863         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7864 
7865         uint64_t data = MemURead (context, address, 2, 0, &success);
7866         if (!success)
7867             return false;
7868 
7869         // if wback then R[n] = offset_addr;
7870         if (wback)
7871         {
7872             context.type = eContextAdjustBaseRegister;
7873             context.SetAddress (offset_addr);
7874             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7875                 return false;
7876         }
7877 
7878         // if UnalignedSupport() || address<0> = '0' then
7879         if (UnalignedSupport() || BitIsClear (address, 0))
7880         {
7881             // R[t] = SignExtend(data, 32);
7882             context.type = eContextRegisterLoad;
7883             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7884 
7885             int64_t signed_data = llvm::SignExtend64<16>(data);
7886             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7887                 return false;
7888         }
7889         else // Can only apply before ARMv7
7890         {
7891             // R[t] = bits(32) UNKNOWN;
7892             WriteBits32Unknown (t);
7893         }
7894     }
7895     return true;
7896 }
7897 
7898 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7899 // register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7900 bool
7901 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding)
7902 {
7903 #if 0
7904     if ConditionPassed() then
7905         EncodingSpecificOperations();
7906         rotated = ROR(R[m], rotation);
7907         R[d] = SignExtend(rotated<7:0>, 32);
7908 #endif
7909 
7910     bool success = false;
7911 
7912     if (ConditionPassed(opcode))
7913     {
7914         uint32_t d;
7915         uint32_t m;
7916         uint32_t rotation;
7917 
7918         // EncodingSpecificOperations();
7919         switch (encoding)
7920         {
7921             case eEncodingT1:
7922                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7923                 d = Bits32 (opcode, 2, 0);
7924                 m = Bits32 (opcode, 5, 3);
7925                 rotation = 0;
7926 
7927                 break;
7928 
7929             case eEncodingT2:
7930                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7931                 d = Bits32 (opcode, 11, 8);
7932                 m = Bits32 (opcode, 3, 0);
7933                 rotation = Bits32 (opcode, 5, 4) << 3;
7934 
7935                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7936                 if (BadReg (d) || BadReg (m))
7937                     return false;
7938 
7939                 break;
7940 
7941             case eEncodingA1:
7942                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7943                 d = Bits32 (opcode, 15, 12);
7944                 m = Bits32 (opcode, 3, 0);
7945                 rotation = Bits32 (opcode, 11, 10) << 3;
7946 
7947                 // if d == 15 || m == 15 then UNPREDICTABLE;
7948                 if ((d == 15) || (m == 15))
7949                     return false;
7950 
7951                 break;
7952 
7953             default:
7954                 return false;
7955         }
7956 
7957         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7958         if (!success)
7959             return false;
7960 
7961         // rotated = ROR(R[m], rotation);
7962         uint64_t rotated = ROR (Rm, rotation, &success);
7963         if (!success)
7964             return false;
7965 
7966         // R[d] = SignExtend(rotated<7:0>, 32);
7967         int64_t data = llvm::SignExtend64<8>(rotated);
7968 
7969         RegisterInfo source_reg;
7970         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7971 
7972         EmulateInstruction::Context context;
7973         context.type = eContextRegisterLoad;
7974         context.SetRegister (source_reg);
7975 
7976         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7977             return false;
7978     }
7979     return true;
7980 }
7981 
7982 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7983 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7984 bool
7985 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding)
7986 {
7987 #if 0
7988     if ConditionPassed() then
7989         EncodingSpecificOperations();
7990         rotated = ROR(R[m], rotation);
7991         R[d] = SignExtend(rotated<15:0>, 32);
7992 #endif
7993 
7994     bool success = false;
7995 
7996     if (ConditionPassed(opcode))
7997     {
7998         uint32_t d;
7999         uint32_t m;
8000         uint32_t rotation;
8001 
8002         // EncodingSpecificOperations();
8003         switch (encoding)
8004         {
8005             case eEncodingT1:
8006                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8007                 d = Bits32 (opcode, 2, 0);
8008                 m = Bits32 (opcode, 5, 3);
8009                 rotation = 0;
8010 
8011                 break;
8012 
8013             case eEncodingT2:
8014                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8015                 d = Bits32 (opcode, 11, 8);
8016                 m = Bits32 (opcode, 3, 0);
8017                 rotation = Bits32 (opcode, 5, 4) << 3;
8018 
8019                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8020                 if (BadReg (d) || BadReg (m))
8021                     return false;
8022 
8023                 break;
8024 
8025             case eEncodingA1:
8026                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8027                 d = Bits32 (opcode, 15, 12);
8028                 m = Bits32 (opcode, 3, 0);
8029                 rotation = Bits32 (opcode, 11, 10) << 3;
8030 
8031                 // if d == 15 || m == 15 then UNPREDICTABLE;
8032                 if ((d == 15) || (m == 15))
8033                     return false;
8034 
8035                 break;
8036 
8037             default:
8038                 return false;
8039         }
8040 
8041         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8042         if (!success)
8043             return false;
8044 
8045         // rotated = ROR(R[m], rotation);
8046         uint64_t rotated = ROR (Rm, rotation, &success);
8047         if (!success)
8048             return false;
8049 
8050         // R[d] = SignExtend(rotated<15:0>, 32);
8051         RegisterInfo source_reg;
8052         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8053 
8054         EmulateInstruction::Context context;
8055         context.type = eContextRegisterLoad;
8056         context.SetRegister (source_reg);
8057 
8058         int64_t data = llvm::SignExtend64<16> (rotated);
8059         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
8060             return false;
8061     }
8062 
8063     return true;
8064 }
8065 
8066 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination
8067 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
8068 bool
8069 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding)
8070 {
8071 #if 0
8072     if ConditionPassed() then
8073         EncodingSpecificOperations();
8074         rotated = ROR(R[m], rotation);
8075         R[d] = ZeroExtend(rotated<7:0>, 32);
8076 #endif
8077 
8078     bool success = false;
8079 
8080     if (ConditionPassed(opcode))
8081     {
8082         uint32_t d;
8083         uint32_t m;
8084         uint32_t rotation;
8085 
8086         // EncodingSpecificOperations();
8087         switch (encoding)
8088         {
8089             case eEncodingT1:
8090                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8091                 d = Bits32 (opcode, 2, 0);
8092                 m = Bits32 (opcode, 5, 3);
8093                 rotation = 0;
8094 
8095                 break;
8096 
8097             case eEncodingT2:
8098                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8099                 d = Bits32 (opcode, 11, 8);
8100                 m = Bits32 (opcode, 3, 0);
8101                   rotation = Bits32 (opcode, 5, 4) << 3;
8102 
8103                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8104                 if (BadReg (d) || BadReg (m))
8105                   return false;
8106 
8107                 break;
8108 
8109             case eEncodingA1:
8110                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8111                 d = Bits32 (opcode, 15, 12);
8112                 m = Bits32 (opcode, 3, 0);
8113                 rotation = Bits32 (opcode, 11, 10) << 3;
8114 
8115                 // if d == 15 || m == 15 then UNPREDICTABLE;
8116                 if ((d == 15) || (m == 15))
8117                     return false;
8118 
8119                 break;
8120 
8121             default:
8122                 return false;
8123         }
8124 
8125         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8126         if (!success)
8127             return false;
8128 
8129         // rotated = ROR(R[m], rotation);
8130         uint64_t rotated = ROR (Rm, rotation, &success);
8131         if (!success)
8132             return false;
8133 
8134         // R[d] = ZeroExtend(rotated<7:0>, 32);
8135         RegisterInfo source_reg;
8136         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8137 
8138         EmulateInstruction::Context context;
8139         context.type = eContextRegisterLoad;
8140         context.SetRegister (source_reg);
8141 
8142         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0)))
8143             return false;
8144     }
8145     return true;
8146 }
8147 
8148 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination
8149 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
8150 bool
8151 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding)
8152 {
8153 #if 0
8154     if ConditionPassed() then
8155         EncodingSpecificOperations();
8156         rotated = ROR(R[m], rotation);
8157         R[d] = ZeroExtend(rotated<15:0>, 32);
8158 #endif
8159 
8160     bool success = false;
8161 
8162     if (ConditionPassed(opcode))
8163     {
8164         uint32_t d;
8165         uint32_t m;
8166         uint32_t rotation;
8167 
8168         switch (encoding)
8169         {
8170             case eEncodingT1:
8171                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8172                 d = Bits32 (opcode, 2, 0);
8173                 m = Bits32 (opcode, 5, 3);
8174                 rotation = 0;
8175 
8176                 break;
8177 
8178             case eEncodingT2:
8179                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8180                 d = Bits32 (opcode, 11, 8);
8181                 m = Bits32 (opcode, 3, 0);
8182                 rotation = Bits32 (opcode, 5, 4) << 3;
8183 
8184                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8185                 if (BadReg (d) || BadReg (m))
8186                   return false;
8187 
8188                 break;
8189 
8190             case eEncodingA1:
8191                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8192                 d = Bits32 (opcode, 15, 12);
8193                 m = Bits32 (opcode, 3, 0);
8194                 rotation = Bits32 (opcode, 11, 10) << 3;
8195 
8196                 // if d == 15 || m == 15 then UNPREDICTABLE;
8197                 if ((d == 15) || (m == 15))
8198                     return false;
8199 
8200                 break;
8201 
8202             default:
8203                 return false;
8204         }
8205 
8206         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8207         if (!success)
8208             return false;
8209 
8210         // rotated = ROR(R[m], rotation);
8211         uint64_t rotated = ROR (Rm, rotation, &success);
8212         if (!success)
8213             return false;
8214 
8215         // R[d] = ZeroExtend(rotated<15:0>, 32);
8216         RegisterInfo source_reg;
8217         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8218 
8219         EmulateInstruction::Context context;
8220         context.type = eContextRegisterLoad;
8221         context.SetRegister (source_reg);
8222 
8223         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0)))
8224             return false;
8225     }
8226     return true;
8227 }
8228 
8229 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following
8230 // word respectively.
8231 bool
8232 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding)
8233 {
8234 #if 0
8235     if ConditionPassed() then
8236         EncodingSpecificOperations();
8237         if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8238             UNPREDICTABLE;
8239         else
8240             address = if increment then R[n] else R[n]-8;
8241             if wordhigher then address = address+4;
8242             CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8243             BranchWritePC(MemA[address,4]);
8244             if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8245 #endif
8246 
8247     bool success = false;
8248 
8249     if (ConditionPassed(opcode))
8250     {
8251         uint32_t n;
8252         bool wback;
8253         bool increment;
8254         bool wordhigher;
8255 
8256         // EncodingSpecificOperations();
8257         switch (encoding)
8258         {
8259             case eEncodingT1:
8260                 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE;
8261                 n = Bits32 (opcode, 19, 16);
8262                 wback = BitIsSet (opcode, 21);
8263                 increment = false;
8264                 wordhigher = false;
8265 
8266                 // if n == 15 then UNPREDICTABLE;
8267                 if (n == 15)
8268                     return false;
8269 
8270                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8271                 if (InITBlock() && !LastInITBlock())
8272                     return false;
8273 
8274                 break;
8275 
8276             case eEncodingT2:
8277                 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8278                 n = Bits32 (opcode, 19, 16);
8279                 wback = BitIsSet (opcode, 21);
8280                 increment = true;
8281                 wordhigher = false;
8282 
8283                 // if n == 15 then UNPREDICTABLE;
8284                 if (n == 15)
8285                     return false;
8286 
8287                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8288                 if (InITBlock() && !LastInITBlock())
8289                     return false;
8290 
8291                 break;
8292 
8293             case eEncodingA1:
8294                 // n = UInt(Rn);
8295                 n = Bits32 (opcode, 19, 16);
8296 
8297                 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8298                 wback = BitIsSet (opcode, 21);
8299                 increment = BitIsSet (opcode, 23);
8300                 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23));
8301 
8302                 // if n == 15 then UNPREDICTABLE;
8303                 if (n == 15)
8304                     return false;
8305 
8306                 break;
8307 
8308             default:
8309                 return false;
8310         }
8311 
8312         // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8313         if (!CurrentModeIsPrivileged ())
8314             // UNPREDICTABLE;
8315             return false;
8316         else
8317         {
8318             uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8319             if (!success)
8320                 return false;
8321 
8322             addr_t address;
8323             // address = if increment then R[n] else R[n]-8;
8324             if (increment)
8325                 address = Rn;
8326             else
8327                 address = Rn - 8;
8328 
8329             // if wordhigher then address = address+4;
8330             if (wordhigher)
8331                 address = address + 4;
8332 
8333             // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8334             RegisterInfo base_reg;
8335             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8336 
8337             EmulateInstruction::Context context;
8338             context.type = eContextReturnFromException;
8339             context.SetRegisterPlusOffset (base_reg, address - Rn);
8340 
8341             uint64_t data = MemARead (context, address + 4, 4, 0, &success);
8342             if (!success)
8343                 return false;
8344 
8345             CPSRWriteByInstr (data, 15, true);
8346 
8347             // BranchWritePC(MemA[address,4]);
8348             uint64_t data2 = MemARead (context, address, 4, 0, &success);
8349             if (!success)
8350                 return false;
8351 
8352             BranchWritePC (context, data2);
8353 
8354             // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8355             if (wback)
8356             {
8357                 context.type = eContextAdjustBaseRegister;
8358                 if (increment)
8359                 {
8360                     context.SetOffset (8);
8361                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8))
8362                         return false;
8363                 }
8364                 else
8365                 {
8366                     context.SetOffset (-8);
8367                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8))
8368                         return false;
8369                 }
8370             } // if wback
8371         }
8372     } // if ConditionPassed()
8373     return true;
8374 }
8375 
8376 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
8377 // and writes the result to the destination register.  It can optionally update the condition flags based on
8378 // the result.
8379 bool
8380 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding)
8381 {
8382 #if 0
8383     // ARM pseudo code...
8384     if ConditionPassed() then
8385         EncodingSpecificOperations();
8386         result = R[n] EOR imm32;
8387         if d == 15 then         // Can only occur for ARM encoding
8388             ALUWritePC(result); // setflags is always FALSE here
8389         else
8390             R[d] = result;
8391             if setflags then
8392                 APSR.N = result<31>;
8393                 APSR.Z = IsZeroBit(result);
8394                 APSR.C = carry;
8395                 // APSR.V unchanged
8396 #endif
8397 
8398     bool success = false;
8399 
8400     if (ConditionPassed(opcode))
8401     {
8402         uint32_t Rd, Rn;
8403         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8404         bool setflags;
8405         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8406         switch (encoding)
8407         {
8408         case eEncodingT1:
8409             Rd = Bits32(opcode, 11, 8);
8410             Rn = Bits32(opcode, 19, 16);
8411             setflags = BitIsSet(opcode, 20);
8412             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8413             // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8414             if (Rd == 15 && setflags)
8415                 return EmulateTEQImm (opcode, eEncodingT1);
8416             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8417                 return false;
8418             break;
8419         case eEncodingA1:
8420             Rd = Bits32(opcode, 15, 12);
8421             Rn = Bits32(opcode, 19, 16);
8422             setflags = BitIsSet(opcode, 20);
8423             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8424 
8425             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8426             if (Rd == 15 && setflags)
8427                 return EmulateSUBSPcLrEtc (opcode, encoding);
8428             break;
8429         default:
8430             return false;
8431         }
8432 
8433         // Read the first operand.
8434         uint32_t val1 = ReadCoreReg(Rn, &success);
8435         if (!success)
8436             return false;
8437 
8438         uint32_t result = val1 ^ imm32;
8439 
8440         EmulateInstruction::Context context;
8441         context.type = EmulateInstruction::eContextImmediate;
8442         context.SetNoArgs ();
8443 
8444         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8445             return false;
8446     }
8447     return true;
8448 }
8449 
8450 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an
8451 // optionally-shifted register value, and writes the result to the destination register.
8452 // It can optionally update the condition flags based on the result.
8453 bool
8454 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding)
8455 {
8456 #if 0
8457     // ARM pseudo code...
8458     if ConditionPassed() then
8459         EncodingSpecificOperations();
8460         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8461         result = R[n] EOR shifted;
8462         if d == 15 then         // Can only occur for ARM encoding
8463             ALUWritePC(result); // setflags is always FALSE here
8464         else
8465             R[d] = result;
8466             if setflags then
8467                 APSR.N = result<31>;
8468                 APSR.Z = IsZeroBit(result);
8469                 APSR.C = carry;
8470                 // APSR.V unchanged
8471 #endif
8472 
8473     bool success = false;
8474 
8475     if (ConditionPassed(opcode))
8476     {
8477         uint32_t Rd, Rn, Rm;
8478         ARM_ShifterType shift_t;
8479         uint32_t shift_n; // the shift applied to the value read from Rm
8480         bool setflags;
8481         uint32_t carry;
8482         switch (encoding)
8483         {
8484         case eEncodingT1:
8485             Rd = Rn = Bits32(opcode, 2, 0);
8486             Rm = Bits32(opcode, 5, 3);
8487             setflags = !InITBlock();
8488             shift_t = SRType_LSL;
8489             shift_n = 0;
8490             break;
8491         case eEncodingT2:
8492             Rd = Bits32(opcode, 11, 8);
8493             Rn = Bits32(opcode, 19, 16);
8494             Rm = Bits32(opcode, 3, 0);
8495             setflags = BitIsSet(opcode, 20);
8496             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8497             // if Rd == '1111' && S == '1' then SEE TEQ (register);
8498             if (Rd == 15 && setflags)
8499                 return EmulateTEQReg (opcode, eEncodingT1);
8500             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8501                 return false;
8502             break;
8503         case eEncodingA1:
8504             Rd = Bits32(opcode, 15, 12);
8505             Rn = Bits32(opcode, 19, 16);
8506             Rm = Bits32(opcode, 3, 0);
8507             setflags = BitIsSet(opcode, 20);
8508             shift_n = DecodeImmShiftARM(opcode, shift_t);
8509 
8510             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8511             if (Rd == 15 && setflags)
8512                 return EmulateSUBSPcLrEtc (opcode, encoding);
8513             break;
8514         default:
8515             return false;
8516         }
8517 
8518         // Read the first operand.
8519         uint32_t val1 = ReadCoreReg(Rn, &success);
8520         if (!success)
8521             return false;
8522 
8523         // Read the second operand.
8524         uint32_t val2 = ReadCoreReg(Rm, &success);
8525         if (!success)
8526             return false;
8527 
8528         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8529         if (!success)
8530             return false;
8531         uint32_t result = val1 ^ shifted;
8532 
8533         EmulateInstruction::Context context;
8534         context.type = EmulateInstruction::eContextImmediate;
8535         context.SetNoArgs ();
8536 
8537         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8538             return false;
8539     }
8540     return true;
8541 }
8542 
8543 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and
8544 // writes the result to the destination register.  It can optionally update the condition flags based
8545 // on the result.
8546 bool
8547 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding)
8548 {
8549 #if 0
8550     // ARM pseudo code...
8551     if ConditionPassed() then
8552         EncodingSpecificOperations();
8553         result = R[n] OR imm32;
8554         if d == 15 then         // Can only occur for ARM encoding
8555             ALUWritePC(result); // setflags is always FALSE here
8556         else
8557             R[d] = result;
8558             if setflags then
8559                 APSR.N = result<31>;
8560                 APSR.Z = IsZeroBit(result);
8561                 APSR.C = carry;
8562                 // APSR.V unchanged
8563 #endif
8564 
8565     bool success = false;
8566 
8567     if (ConditionPassed(opcode))
8568     {
8569         uint32_t Rd, Rn;
8570         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8571         bool setflags;
8572         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8573         switch (encoding)
8574         {
8575         case eEncodingT1:
8576             Rd = Bits32(opcode, 11, 8);
8577             Rn = Bits32(opcode, 19, 16);
8578             setflags = BitIsSet(opcode, 20);
8579             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8580             // if Rn == '1111' then SEE MOV (immediate);
8581             if (Rn == 15)
8582                 return EmulateMOVRdImm (opcode, eEncodingT2);
8583             if (BadReg(Rd) || Rn == 13)
8584                 return false;
8585             break;
8586         case eEncodingA1:
8587             Rd = Bits32(opcode, 15, 12);
8588             Rn = Bits32(opcode, 19, 16);
8589             setflags = BitIsSet(opcode, 20);
8590             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8591 
8592             if (Rd == 15 && setflags)
8593                 return EmulateSUBSPcLrEtc (opcode, encoding);
8594             break;
8595         default:
8596             return false;
8597         }
8598 
8599         // Read the first operand.
8600         uint32_t val1 = ReadCoreReg(Rn, &success);
8601         if (!success)
8602             return false;
8603 
8604         uint32_t result = val1 | imm32;
8605 
8606         EmulateInstruction::Context context;
8607         context.type = EmulateInstruction::eContextImmediate;
8608         context.SetNoArgs ();
8609 
8610         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8611             return false;
8612     }
8613     return true;
8614 }
8615 
8616 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register
8617 // value, and writes the result to the destination register.  It can optionally update the condition flags based
8618 // on the result.
8619 bool
8620 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding)
8621 {
8622 #if 0
8623     // ARM pseudo code...
8624     if ConditionPassed() then
8625         EncodingSpecificOperations();
8626         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8627         result = R[n] OR shifted;
8628         if d == 15 then         // Can only occur for ARM encoding
8629             ALUWritePC(result); // setflags is always FALSE here
8630         else
8631             R[d] = result;
8632             if setflags then
8633                 APSR.N = result<31>;
8634                 APSR.Z = IsZeroBit(result);
8635                 APSR.C = carry;
8636                 // APSR.V unchanged
8637 #endif
8638 
8639     bool success = false;
8640 
8641     if (ConditionPassed(opcode))
8642     {
8643         uint32_t Rd, Rn, Rm;
8644         ARM_ShifterType shift_t;
8645         uint32_t shift_n; // the shift applied to the value read from Rm
8646         bool setflags;
8647         uint32_t carry;
8648         switch (encoding)
8649         {
8650         case eEncodingT1:
8651             Rd = Rn = Bits32(opcode, 2, 0);
8652             Rm = Bits32(opcode, 5, 3);
8653             setflags = !InITBlock();
8654             shift_t = SRType_LSL;
8655             shift_n = 0;
8656             break;
8657         case eEncodingT2:
8658             Rd = Bits32(opcode, 11, 8);
8659             Rn = Bits32(opcode, 19, 16);
8660             Rm = Bits32(opcode, 3, 0);
8661             setflags = BitIsSet(opcode, 20);
8662             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8663             // if Rn == '1111' then SEE MOV (register);
8664             if (Rn == 15)
8665                 return EmulateMOVRdRm (opcode, eEncodingT3);
8666             if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
8667                 return false;
8668             break;
8669         case eEncodingA1:
8670             Rd = Bits32(opcode, 15, 12);
8671             Rn = Bits32(opcode, 19, 16);
8672             Rm = Bits32(opcode, 3, 0);
8673             setflags = BitIsSet(opcode, 20);
8674             shift_n = DecodeImmShiftARM(opcode, shift_t);
8675 
8676             if (Rd == 15 && setflags)
8677                 return EmulateSUBSPcLrEtc (opcode, encoding);
8678             break;
8679         default:
8680             return false;
8681         }
8682 
8683         // Read the first operand.
8684         uint32_t val1 = ReadCoreReg(Rn, &success);
8685         if (!success)
8686             return false;
8687 
8688         // Read the second operand.
8689         uint32_t val2 = ReadCoreReg(Rm, &success);
8690         if (!success)
8691             return false;
8692 
8693         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8694         if (!success)
8695             return false;
8696         uint32_t result = val1 | shifted;
8697 
8698         EmulateInstruction::Context context;
8699         context.type = EmulateInstruction::eContextImmediate;
8700         context.SetNoArgs ();
8701 
8702         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8703             return false;
8704     }
8705     return true;
8706 }
8707 
8708 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to
8709 // the destination register. It can optionally update the condition flags based on the result.
8710 bool
8711 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding)
8712 {
8713 #if 0
8714     // ARM pseudo code...
8715     if ConditionPassed() then
8716         EncodingSpecificOperations();
8717         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
8718         if d == 15 then         // Can only occur for ARM encoding
8719             ALUWritePC(result); // setflags is always FALSE here
8720         else
8721             R[d] = result;
8722             if setflags then
8723                 APSR.N = result<31>;
8724                 APSR.Z = IsZeroBit(result);
8725                 APSR.C = carry;
8726                 APSR.V = overflow;
8727 #endif
8728 
8729     bool success = false;
8730 
8731     uint32_t Rd; // the destination register
8732     uint32_t Rn; // the first operand
8733     bool setflags;
8734     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8735     switch (encoding) {
8736     case eEncodingT1:
8737         Rd = Bits32(opcode, 2, 0);
8738         Rn = Bits32(opcode, 5, 3);
8739         setflags = !InITBlock();
8740         imm32 = 0;
8741         break;
8742     case eEncodingT2:
8743         Rd = Bits32(opcode, 11, 8);
8744         Rn = Bits32(opcode, 19, 16);
8745         setflags = BitIsSet(opcode, 20);
8746         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8747         if (BadReg(Rd) || BadReg(Rn))
8748             return false;
8749         break;
8750     case eEncodingA1:
8751         Rd = Bits32(opcode, 15, 12);
8752         Rn = Bits32(opcode, 19, 16);
8753         setflags = BitIsSet(opcode, 20);
8754         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8755 
8756         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8757         if (Rd == 15 && setflags)
8758             return EmulateSUBSPcLrEtc (opcode, encoding);
8759         break;
8760     default:
8761         return false;
8762     }
8763     // Read the register value from the operand register Rn.
8764     uint32_t reg_val = ReadCoreReg(Rn, &success);
8765     if (!success)
8766         return false;
8767 
8768     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
8769 
8770     EmulateInstruction::Context context;
8771     context.type = EmulateInstruction::eContextImmediate;
8772     context.SetNoArgs ();
8773 
8774     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8775         return false;
8776 
8777     return true;
8778 }
8779 
8780 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the
8781 // result to the destination register. It can optionally update the condition flags based on the result.
8782 bool
8783 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding)
8784 {
8785 #if 0
8786     // ARM pseudo code...
8787     if ConditionPassed() then
8788         EncodingSpecificOperations();
8789         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8790         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
8791         if d == 15 then         // Can only occur for ARM encoding
8792             ALUWritePC(result); // setflags is always FALSE here
8793         else
8794             R[d] = result;
8795             if setflags then
8796                 APSR.N = result<31>;
8797                 APSR.Z = IsZeroBit(result);
8798                 APSR.C = carry;
8799                 APSR.V = overflow;
8800 #endif
8801 
8802     bool success = false;
8803 
8804     uint32_t Rd; // the destination register
8805     uint32_t Rn; // the first operand
8806     uint32_t Rm; // the second operand
8807     bool setflags;
8808     ARM_ShifterType shift_t;
8809     uint32_t shift_n; // the shift applied to the value read from Rm
8810     switch (encoding) {
8811     case eEncodingT1:
8812         Rd = Bits32(opcode, 11, 8);
8813         Rn = Bits32(opcode, 19, 16);
8814         Rm = Bits32(opcode, 3, 0);
8815         setflags = BitIsSet(opcode, 20);
8816         shift_n = DecodeImmShiftThumb(opcode, shift_t);
8817         // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
8818         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8819             return false;
8820         break;
8821     case eEncodingA1:
8822         Rd = Bits32(opcode, 15, 12);
8823         Rn = Bits32(opcode, 19, 16);
8824         Rm = Bits32(opcode, 3, 0);
8825         setflags = BitIsSet(opcode, 20);
8826         shift_n = DecodeImmShiftARM(opcode, shift_t);
8827 
8828         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8829         if (Rd == 15 && setflags)
8830             return EmulateSUBSPcLrEtc (opcode, encoding);
8831         break;
8832     default:
8833         return false;
8834     }
8835     // Read the register value from register Rn.
8836     uint32_t val1 = ReadCoreReg(Rn, &success);
8837     if (!success)
8838         return false;
8839 
8840     // Read the register value from register Rm.
8841     uint32_t val2 = ReadCoreReg(Rm, &success);
8842     if (!success)
8843         return false;
8844 
8845     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8846     if (!success)
8847         return false;
8848     AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
8849 
8850     EmulateInstruction::Context context;
8851     context.type = EmulateInstruction::eContextImmediate;
8852     context.SetNoArgs();
8853     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8854         return false;
8855 
8856     return true;
8857 }
8858 
8859 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from
8860 // an immediate value, and writes the result to the destination register. It can optionally update the condition
8861 // flags based on the result.
8862 bool
8863 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding)
8864 {
8865 #if 0
8866     // ARM pseudo code...
8867     if ConditionPassed() then
8868         EncodingSpecificOperations();
8869         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
8870         if d == 15 then
8871             ALUWritePC(result); // setflags is always FALSE here
8872         else
8873             R[d] = result;
8874             if setflags then
8875                 APSR.N = result<31>;
8876                 APSR.Z = IsZeroBit(result);
8877                 APSR.C = carry;
8878                 APSR.V = overflow;
8879 #endif
8880 
8881     bool success = false;
8882 
8883     uint32_t Rd; // the destination register
8884     uint32_t Rn; // the first operand
8885     bool setflags;
8886     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8887     switch (encoding) {
8888     case eEncodingA1:
8889         Rd = Bits32(opcode, 15, 12);
8890         Rn = Bits32(opcode, 19, 16);
8891         setflags = BitIsSet(opcode, 20);
8892         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8893 
8894         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8895         if (Rd == 15 && setflags)
8896             return EmulateSUBSPcLrEtc  (opcode, encoding);
8897         break;
8898     default:
8899         return false;
8900     }
8901     // Read the register value from the operand register Rn.
8902     uint32_t reg_val = ReadCoreReg(Rn, &success);
8903     if (!success)
8904         return false;
8905 
8906     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
8907 
8908     EmulateInstruction::Context context;
8909     context.type = EmulateInstruction::eContextImmediate;
8910     context.SetNoArgs ();
8911 
8912     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8913         return false;
8914 
8915     return true;
8916 }
8917 
8918 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an
8919 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the
8920 // condition flags based on the result.
8921 bool
8922 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding)
8923 {
8924 #if 0
8925     // ARM pseudo code...
8926     if ConditionPassed() then
8927         EncodingSpecificOperations();
8928         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8929         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
8930         if d == 15 then
8931             ALUWritePC(result); // setflags is always FALSE here
8932         else
8933             R[d] = result;
8934             if setflags then
8935                 APSR.N = result<31>;
8936                 APSR.Z = IsZeroBit(result);
8937                 APSR.C = carry;
8938                 APSR.V = overflow;
8939 #endif
8940 
8941     bool success = false;
8942 
8943     uint32_t Rd; // the destination register
8944     uint32_t Rn; // the first operand
8945     uint32_t Rm; // the second operand
8946     bool setflags;
8947     ARM_ShifterType shift_t;
8948     uint32_t shift_n; // the shift applied to the value read from Rm
8949     switch (encoding) {
8950     case eEncodingA1:
8951         Rd = Bits32(opcode, 15, 12);
8952         Rn = Bits32(opcode, 19, 16);
8953         Rm = Bits32(opcode, 3, 0);
8954         setflags = BitIsSet(opcode, 20);
8955         shift_n = DecodeImmShiftARM(opcode, shift_t);
8956 
8957         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8958         if (Rd == 15 && setflags)
8959             return EmulateSUBSPcLrEtc (opcode, encoding);
8960         break;
8961     default:
8962         return false;
8963     }
8964     // Read the register value from register Rn.
8965     uint32_t val1 = ReadCoreReg(Rn, &success);
8966     if (!success)
8967         return false;
8968 
8969     // Read the register value from register Rm.
8970     uint32_t val2 = ReadCoreReg(Rm, &success);
8971     if (!success)
8972         return false;
8973 
8974     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8975     if (!success)
8976         return false;
8977     AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
8978 
8979     EmulateInstruction::Context context;
8980     context.type = EmulateInstruction::eContextImmediate;
8981     context.SetNoArgs();
8982     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8983         return false;
8984 
8985     return true;
8986 }
8987 
8988 // Subtract with Carry (immediate) subtracts an immediate value and the value of
8989 // NOT (Carry flag) from a register value, and writes the result to the destination register.
8990 // It can optionally update the condition flags based on the result.
8991 bool
8992 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding)
8993 {
8994 #if 0
8995     // ARM pseudo code...
8996     if ConditionPassed() then
8997         EncodingSpecificOperations();
8998         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
8999         if d == 15 then         // Can only occur for ARM encoding
9000             ALUWritePC(result); // setflags is always FALSE here
9001         else
9002             R[d] = result;
9003             if setflags then
9004                 APSR.N = result<31>;
9005                 APSR.Z = IsZeroBit(result);
9006                 APSR.C = carry;
9007                 APSR.V = overflow;
9008 #endif
9009 
9010     bool success = false;
9011 
9012     uint32_t Rd; // the destination register
9013     uint32_t Rn; // the first operand
9014     bool setflags;
9015     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
9016     switch (encoding) {
9017     case eEncodingT1:
9018         Rd = Bits32(opcode, 11, 8);
9019         Rn = Bits32(opcode, 19, 16);
9020         setflags = BitIsSet(opcode, 20);
9021         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9022         if (BadReg(Rd) || BadReg(Rn))
9023             return false;
9024         break;
9025     case eEncodingA1:
9026         Rd = Bits32(opcode, 15, 12);
9027         Rn = Bits32(opcode, 19, 16);
9028         setflags = BitIsSet(opcode, 20);
9029         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9030 
9031         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9032         if (Rd == 15 && setflags)
9033             return EmulateSUBSPcLrEtc (opcode, encoding);
9034         break;
9035     default:
9036         return false;
9037     }
9038     // Read the register value from the operand register Rn.
9039     uint32_t reg_val = ReadCoreReg(Rn, &success);
9040     if (!success)
9041         return false;
9042 
9043     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
9044 
9045     EmulateInstruction::Context context;
9046     context.type = EmulateInstruction::eContextImmediate;
9047     context.SetNoArgs ();
9048 
9049     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9050         return false;
9051 
9052     return true;
9053 }
9054 
9055 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of
9056 // NOT (Carry flag) from a register value, and writes the result to the destination register.
9057 // It can optionally update the condition flags based on the result.
9058 bool
9059 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding)
9060 {
9061 #if 0
9062     // ARM pseudo code...
9063     if ConditionPassed() then
9064         EncodingSpecificOperations();
9065         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9066         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
9067         if d == 15 then         // Can only occur for ARM encoding
9068             ALUWritePC(result); // setflags is always FALSE here
9069         else
9070             R[d] = result;
9071             if setflags then
9072                 APSR.N = result<31>;
9073                 APSR.Z = IsZeroBit(result);
9074                 APSR.C = carry;
9075                 APSR.V = overflow;
9076 #endif
9077 
9078     bool success = false;
9079 
9080     uint32_t Rd; // the destination register
9081     uint32_t Rn; // the first operand
9082     uint32_t Rm; // the second operand
9083     bool setflags;
9084     ARM_ShifterType shift_t;
9085     uint32_t shift_n; // the shift applied to the value read from Rm
9086     switch (encoding) {
9087     case eEncodingT1:
9088         Rd = Rn = Bits32(opcode, 2, 0);
9089         Rm = Bits32(opcode, 5, 3);
9090         setflags = !InITBlock();
9091         shift_t = SRType_LSL;
9092         shift_n = 0;
9093         break;
9094     case eEncodingT2:
9095         Rd = Bits32(opcode, 11, 8);
9096         Rn = Bits32(opcode, 19, 16);
9097         Rm = Bits32(opcode, 3, 0);
9098         setflags = BitIsSet(opcode, 20);
9099         shift_n = DecodeImmShiftThumb(opcode, shift_t);
9100         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9101             return false;
9102         break;
9103     case eEncodingA1:
9104         Rd = Bits32(opcode, 15, 12);
9105         Rn = Bits32(opcode, 19, 16);
9106         Rm = Bits32(opcode, 3, 0);
9107         setflags = BitIsSet(opcode, 20);
9108         shift_n = DecodeImmShiftARM(opcode, shift_t);
9109 
9110         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9111         if (Rd == 15 && setflags)
9112             return EmulateSUBSPcLrEtc (opcode, encoding);
9113         break;
9114     default:
9115         return false;
9116     }
9117     // Read the register value from register Rn.
9118     uint32_t val1 = ReadCoreReg(Rn, &success);
9119     if (!success)
9120         return false;
9121 
9122     // Read the register value from register Rm.
9123     uint32_t val2 = ReadCoreReg(Rm, &success);
9124     if (!success)
9125         return false;
9126 
9127     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9128     if (!success)
9129         return false;
9130     AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
9131 
9132     EmulateInstruction::Context context;
9133     context.type = EmulateInstruction::eContextImmediate;
9134     context.SetNoArgs();
9135     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9136         return false;
9137 
9138     return true;
9139 }
9140 
9141 // This instruction subtracts an immediate value from a register value, and writes the result
9142 // to the destination register.  It can optionally update the condition flags based on the result.
9143 bool
9144 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding)
9145 {
9146 #if 0
9147     // ARM pseudo code...
9148     if ConditionPassed() then
9149         EncodingSpecificOperations();
9150         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9151         R[d] = result;
9152         if setflags then
9153             APSR.N = result<31>;
9154             APSR.Z = IsZeroBit(result);
9155             APSR.C = carry;
9156             APSR.V = overflow;
9157 #endif
9158 
9159     bool success = false;
9160 
9161     uint32_t Rd; // the destination register
9162     uint32_t Rn; // the first operand
9163     bool setflags;
9164     uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9165     switch (encoding) {
9166     case eEncodingT1:
9167         Rd = Bits32(opcode, 2, 0);
9168         Rn = Bits32(opcode, 5, 3);
9169         setflags = !InITBlock();
9170         imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9171         break;
9172     case eEncodingT2:
9173         Rd = Rn = Bits32(opcode, 10, 8);
9174         setflags = !InITBlock();
9175         imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9176         break;
9177     case eEncodingT3:
9178         Rd = Bits32(opcode, 11, 8);
9179         Rn = Bits32(opcode, 19, 16);
9180         setflags = BitIsSet(opcode, 20);
9181         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9182 
9183         // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9184         if (Rd == 15 && setflags)
9185             return EmulateCMPImm (opcode, eEncodingT2);
9186 
9187         // if Rn == '1101' then SEE SUB (SP minus immediate);
9188         if (Rn == 13)
9189             return EmulateSUBSPImm (opcode, eEncodingT2);
9190 
9191         // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9192         if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9193             return false;
9194         break;
9195     case eEncodingT4:
9196         Rd = Bits32(opcode, 11, 8);
9197         Rn = Bits32(opcode, 19, 16);
9198         setflags = BitIsSet(opcode, 20);
9199         imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9200 
9201         // if Rn == '1111' then SEE ADR;
9202         if (Rn == 15)
9203             return EmulateADR (opcode, eEncodingT2);
9204 
9205         // if Rn == '1101' then SEE SUB (SP minus immediate);
9206         if (Rn == 13)
9207             return EmulateSUBSPImm (opcode, eEncodingT3);
9208 
9209         if (BadReg(Rd))
9210             return false;
9211         break;
9212     default:
9213         return false;
9214     }
9215     // Read the register value from the operand register Rn.
9216     uint32_t reg_val = ReadCoreReg(Rn, &success);
9217     if (!success)
9218         return false;
9219 
9220     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9221 
9222     EmulateInstruction::Context context;
9223     context.type = EmulateInstruction::eContextImmediate;
9224     context.SetNoArgs ();
9225 
9226     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9227         return false;
9228 
9229     return true;
9230 }
9231 
9232 // This instruction subtracts an immediate value from a register value, and writes the result
9233 // to the destination register.  It can optionally update the condition flags based on the result.
9234 bool
9235 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9236 {
9237 #if 0
9238     // ARM pseudo code...
9239     if ConditionPassed() then
9240         EncodingSpecificOperations();
9241         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9242         if d == 15 then
9243             ALUWritePC(result); // setflags is always FALSE here
9244         else
9245             R[d] = result;
9246             if setflags then
9247                 APSR.N = result<31>;
9248                 APSR.Z = IsZeroBit(result);
9249                 APSR.C = carry;
9250                 APSR.V = overflow;
9251 #endif
9252 
9253     bool success = false;
9254 
9255     if (ConditionPassed(opcode))
9256     {
9257         uint32_t Rd; // the destination register
9258         uint32_t Rn; // the first operand
9259         bool setflags;
9260         uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9261         switch (encoding) {
9262         case eEncodingA1:
9263             Rd = Bits32(opcode, 15, 12);
9264             Rn = Bits32(opcode, 19, 16);
9265             setflags = BitIsSet(opcode, 20);
9266             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9267 
9268             // if Rn == '1111' && S == '0' then SEE ADR;
9269             if (Rn == 15 && !setflags)
9270                 return EmulateADR (opcode, eEncodingA2);
9271 
9272             // if Rn == '1101' then SEE SUB (SP minus immediate);
9273             if (Rn == 13)
9274                 return EmulateSUBSPImm (opcode, eEncodingA1);
9275 
9276             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9277             if (Rd == 15 && setflags)
9278                 return EmulateSUBSPcLrEtc (opcode, encoding);
9279             break;
9280         default:
9281             return false;
9282         }
9283         // Read the register value from the operand register Rn.
9284         uint32_t reg_val = ReadCoreReg(Rn, &success);
9285         if (!success)
9286             return false;
9287 
9288         AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9289 
9290         EmulateInstruction::Context context;
9291         if (Rd == 13)
9292             context.type = EmulateInstruction::eContextAdjustStackPointer;
9293         else
9294             context.type = EmulateInstruction::eContextRegisterPlusOffset;
9295 
9296         RegisterInfo dwarf_reg;
9297         GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
9298         int64_t imm32_signed = imm32;
9299         context.SetRegisterPlusOffset (dwarf_reg, -imm32_signed);
9300 
9301         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9302             return false;
9303     }
9304     return true;
9305 }
9306 
9307 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an
9308 // immediate value.  It updates the condition flags based on the result, and discards the result.
9309 bool
9310 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding)
9311 {
9312 #if 0
9313     // ARM pseudo code...
9314     if ConditionPassed() then
9315         EncodingSpecificOperations();
9316         result = R[n] EOR imm32;
9317         APSR.N = result<31>;
9318         APSR.Z = IsZeroBit(result);
9319         APSR.C = carry;
9320         // APSR.V unchanged
9321 #endif
9322 
9323     bool success = false;
9324 
9325     if (ConditionPassed(opcode))
9326     {
9327         uint32_t Rn;
9328         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9329         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9330         switch (encoding)
9331         {
9332         case eEncodingT1:
9333             Rn = Bits32(opcode, 19, 16);
9334             imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9335             if (BadReg(Rn))
9336                 return false;
9337             break;
9338         case eEncodingA1:
9339             Rn = Bits32(opcode, 19, 16);
9340             imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9341             break;
9342         default:
9343             return false;
9344         }
9345 
9346         // Read the first operand.
9347         uint32_t val1 = ReadCoreReg(Rn, &success);
9348         if (!success)
9349             return false;
9350 
9351         uint32_t result = val1 ^ imm32;
9352 
9353         EmulateInstruction::Context context;
9354         context.type = EmulateInstruction::eContextImmediate;
9355         context.SetNoArgs ();
9356 
9357         if (!WriteFlags(context, result, carry))
9358             return false;
9359     }
9360     return true;
9361 }
9362 
9363 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an
9364 // optionally-shifted register value.  It updates the condition flags based on the result, and discards
9365 // the result.
9366 bool
9367 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding)
9368 {
9369 #if 0
9370     // ARM pseudo code...
9371     if ConditionPassed() then
9372         EncodingSpecificOperations();
9373         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9374         result = R[n] EOR shifted;
9375         APSR.N = result<31>;
9376         APSR.Z = IsZeroBit(result);
9377         APSR.C = carry;
9378         // APSR.V unchanged
9379 #endif
9380 
9381     bool success = false;
9382 
9383     if (ConditionPassed(opcode))
9384     {
9385         uint32_t Rn, Rm;
9386         ARM_ShifterType shift_t;
9387         uint32_t shift_n; // the shift applied to the value read from Rm
9388         uint32_t carry;
9389         switch (encoding)
9390         {
9391         case eEncodingT1:
9392             Rn = Bits32(opcode, 19, 16);
9393             Rm = Bits32(opcode, 3, 0);
9394             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9395             if (BadReg(Rn) || BadReg(Rm))
9396                 return false;
9397             break;
9398         case eEncodingA1:
9399             Rn = Bits32(opcode, 19, 16);
9400             Rm = Bits32(opcode, 3, 0);
9401             shift_n = DecodeImmShiftARM(opcode, shift_t);
9402             break;
9403         default:
9404             return false;
9405         }
9406 
9407         // Read the first operand.
9408         uint32_t val1 = ReadCoreReg(Rn, &success);
9409         if (!success)
9410             return false;
9411 
9412         // Read the second operand.
9413         uint32_t val2 = ReadCoreReg(Rm, &success);
9414         if (!success)
9415             return false;
9416 
9417         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9418         if (!success)
9419             return false;
9420         uint32_t result = val1 ^ shifted;
9421 
9422         EmulateInstruction::Context context;
9423         context.type = EmulateInstruction::eContextImmediate;
9424         context.SetNoArgs ();
9425 
9426         if (!WriteFlags(context, result, carry))
9427             return false;
9428     }
9429     return true;
9430 }
9431 
9432 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value.
9433 // It updates the condition flags based on the result, and discards the result.
9434 bool
9435 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding)
9436 {
9437 #if 0
9438     // ARM pseudo code...
9439     if ConditionPassed() then
9440         EncodingSpecificOperations();
9441         result = R[n] AND imm32;
9442         APSR.N = result<31>;
9443         APSR.Z = IsZeroBit(result);
9444         APSR.C = carry;
9445         // APSR.V unchanged
9446 #endif
9447 
9448     bool success = false;
9449 
9450     if (ConditionPassed(opcode))
9451     {
9452         uint32_t Rn;
9453         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9454         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9455         switch (encoding)
9456         {
9457         case eEncodingT1:
9458             Rn = Bits32(opcode, 19, 16);
9459             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9460             if (BadReg(Rn))
9461                 return false;
9462             break;
9463         case eEncodingA1:
9464             Rn = Bits32(opcode, 19, 16);
9465             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9466             break;
9467         default:
9468             return false;
9469         }
9470 
9471         // Read the first operand.
9472         uint32_t val1 = ReadCoreReg(Rn, &success);
9473         if (!success)
9474             return false;
9475 
9476         uint32_t result = val1 & imm32;
9477 
9478         EmulateInstruction::Context context;
9479         context.type = EmulateInstruction::eContextImmediate;
9480         context.SetNoArgs ();
9481 
9482         if (!WriteFlags(context, result, carry))
9483             return false;
9484     }
9485     return true;
9486 }
9487 
9488 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value.
9489 // It updates the condition flags based on the result, and discards the result.
9490 bool
9491 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding)
9492 {
9493 #if 0
9494     // ARM pseudo code...
9495     if ConditionPassed() then
9496         EncodingSpecificOperations();
9497         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9498         result = R[n] AND shifted;
9499         APSR.N = result<31>;
9500         APSR.Z = IsZeroBit(result);
9501         APSR.C = carry;
9502         // APSR.V unchanged
9503 #endif
9504 
9505     bool success = false;
9506 
9507     if (ConditionPassed(opcode))
9508     {
9509         uint32_t Rn, Rm;
9510         ARM_ShifterType shift_t;
9511         uint32_t shift_n; // the shift applied to the value read from Rm
9512         uint32_t carry;
9513         switch (encoding)
9514         {
9515         case eEncodingT1:
9516             Rn = Bits32(opcode, 2, 0);
9517             Rm = Bits32(opcode, 5, 3);
9518             shift_t = SRType_LSL;
9519             shift_n = 0;
9520             break;
9521         case eEncodingT2:
9522             Rn = Bits32(opcode, 19, 16);
9523             Rm = Bits32(opcode, 3, 0);
9524             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9525             if (BadReg(Rn) || BadReg(Rm))
9526                 return false;
9527             break;
9528         case eEncodingA1:
9529             Rn = Bits32(opcode, 19, 16);
9530             Rm = Bits32(opcode, 3, 0);
9531             shift_n = DecodeImmShiftARM(opcode, shift_t);
9532             break;
9533         default:
9534             return false;
9535         }
9536 
9537         // Read the first operand.
9538         uint32_t val1 = ReadCoreReg(Rn, &success);
9539         if (!success)
9540             return false;
9541 
9542         // Read the second operand.
9543         uint32_t val2 = ReadCoreReg(Rm, &success);
9544         if (!success)
9545             return false;
9546 
9547         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9548         if (!success)
9549             return false;
9550         uint32_t result = val1 & shifted;
9551 
9552         EmulateInstruction::Context context;
9553         context.type = EmulateInstruction::eContextImmediate;
9554         context.SetNoArgs ();
9555 
9556         if (!WriteFlags(context, result, carry))
9557             return false;
9558     }
9559     return true;
9560 }
9561 
9562 // A8.6.216 SUB (SP minus register)
9563 bool
9564 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding)
9565 {
9566 #if 0
9567     if ConditionPassed() then
9568         EncodingSpecificOperations();
9569         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9570         (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
9571         if d == 15 then // Can only occur for ARM encoding
9572             ALUWritePC(result); // setflags is always FALSE here
9573         else
9574             R[d] = result;
9575             if setflags then
9576                 APSR.N = result<31>;
9577                 APSR.Z = IsZeroBit(result);
9578                 APSR.C = carry;
9579                 APSR.V = overflow;
9580 #endif
9581 
9582     bool success = false;
9583 
9584     if (ConditionPassed(opcode))
9585     {
9586         uint32_t d;
9587         uint32_t m;
9588         bool setflags;
9589         ARM_ShifterType shift_t;
9590         uint32_t shift_n;
9591 
9592         switch (encoding)
9593         {
9594             case eEncodingT1:
9595                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
9596                 d = Bits32 (opcode, 11, 8);
9597                 m = Bits32 (opcode, 3, 0);
9598                 setflags = BitIsSet (opcode, 20);
9599 
9600                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9601                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9602 
9603                 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE;
9604                 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
9605                     return false;
9606 
9607                 // if d == 15 || BadReg(m) then UNPREDICTABLE;
9608                 if ((d == 15) || BadReg (m))
9609                     return false;
9610                 break;
9611 
9612             case eEncodingA1:
9613                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
9614                 d = Bits32 (opcode, 15, 12);
9615                 m = Bits32 (opcode, 3, 0);
9616                 setflags = BitIsSet (opcode, 20);
9617 
9618                 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9619                 if (d == 15 && setflags)
9620                     EmulateSUBSPcLrEtc (opcode, encoding);
9621 
9622                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9623                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9624                 break;
9625 
9626             default:
9627                 return false;
9628         }
9629 
9630         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9631         uint32_t Rm = ReadCoreReg (m, &success);
9632         if (!success)
9633             return false;
9634 
9635         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9636         if (!success)
9637             return false;
9638 
9639         // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
9640         uint32_t sp_val = ReadCoreReg (SP_REG, &success);
9641         if (!success)
9642             return false;
9643 
9644         AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1);
9645 
9646         EmulateInstruction::Context context;
9647         context.type = eContextArithmetic;
9648         RegisterInfo sp_reg;
9649         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
9650         RegisterInfo dwarf_reg;
9651         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
9652         context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
9653 
9654         if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9655             return false;
9656     }
9657     return true;
9658 }
9659 
9660 
9661 // A8.6.7 ADD (register-shifted register)
9662 bool
9663 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding)
9664 {
9665 #if 0
9666     if ConditionPassed() then
9667         EncodingSpecificOperations();
9668         shift_n = UInt(R[s]<7:0>);
9669         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9670         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
9671         R[d] = result;
9672         if setflags then
9673             APSR.N = result<31>;
9674             APSR.Z = IsZeroBit(result);
9675             APSR.C = carry;
9676             APSR.V = overflow;
9677 #endif
9678 
9679     bool success = false;
9680 
9681     if (ConditionPassed(opcode))
9682     {
9683         uint32_t d;
9684         uint32_t n;
9685         uint32_t m;
9686         uint32_t s;
9687         bool setflags;
9688         ARM_ShifterType shift_t;
9689 
9690         switch (encoding)
9691         {
9692             case eEncodingA1:
9693                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
9694                 d = Bits32 (opcode, 15, 12);
9695                 n = Bits32 (opcode, 19, 16);
9696                 m = Bits32 (opcode, 3, 0);
9697                 s = Bits32 (opcode, 11, 8);
9698 
9699                 // setflags = (S == '1'); shift_t = DecodeRegShift(type);
9700                 setflags = BitIsSet (opcode, 20);
9701                 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5));
9702 
9703                 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
9704                 if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
9705                     return false;
9706                 break;
9707 
9708             default:
9709                 return false;
9710         }
9711 
9712         // shift_n = UInt(R[s]<7:0>);
9713         uint32_t Rs = ReadCoreReg (s, &success);
9714         if (!success)
9715             return false;
9716 
9717         uint32_t shift_n = Bits32 (Rs, 7, 0);
9718 
9719         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9720         uint32_t Rm = ReadCoreReg (m, &success);
9721         if (!success)
9722             return false;
9723 
9724         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9725         if (!success)
9726             return false;
9727 
9728         // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
9729         uint32_t Rn = ReadCoreReg (n, &success);
9730         if (!success)
9731             return false;
9732 
9733         AddWithCarryResult res = AddWithCarry (Rn, shifted, 0);
9734 
9735         // R[d] = result;
9736         EmulateInstruction::Context context;
9737         context.type = eContextArithmetic;
9738         RegisterInfo reg_n;
9739         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9740         RegisterInfo reg_m;
9741         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9742 
9743         context.SetRegisterRegisterOperands (reg_n, reg_m);
9744 
9745         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result))
9746             return false;
9747 
9748         // if setflags then
9749             // APSR.N = result<31>;
9750             // APSR.Z = IsZeroBit(result);
9751             // APSR.C = carry;
9752             // APSR.V = overflow;
9753         if (setflags)
9754             return WriteFlags (context, res.result, res.carry_out, res.overflow);
9755     }
9756     return true;
9757 }
9758 
9759 // A8.6.213 SUB (register)
9760 bool
9761 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding)
9762 {
9763 #if 0
9764     if ConditionPassed() then
9765         EncodingSpecificOperations();
9766         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9767         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
9768         if d == 15 then // Can only occur for ARM encoding
9769             ALUWritePC(result); // setflags is always FALSE here
9770         else
9771             R[d] = result;
9772             if setflags then
9773                 APSR.N = result<31>;
9774                 APSR.Z = IsZeroBit(result);
9775                 APSR.C = carry;
9776                 APSR.V = overflow;
9777 #endif
9778 
9779     bool success = false;
9780 
9781     if (ConditionPassed(opcode))
9782     {
9783         uint32_t d;
9784         uint32_t n;
9785         uint32_t m;
9786         bool setflags;
9787         ARM_ShifterType shift_t;
9788         uint32_t shift_n;
9789 
9790         switch (encoding)
9791         {
9792             case eEncodingT1:
9793                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
9794                 d = Bits32 (opcode, 2, 0);
9795                 n = Bits32 (opcode, 5, 3);
9796                 m = Bits32 (opcode, 8, 6);
9797                 setflags = !InITBlock();
9798 
9799                 // (shift_t, shift_n) = (SRType_LSL, 0);
9800                 shift_t = SRType_LSL;
9801                 shift_n = 0;
9802 
9803                 break;
9804 
9805             case eEncodingT2:
9806                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1");
9807                 d = Bits32 (opcode, 11, 8);
9808                 n = Bits32 (opcode, 19, 16);
9809                 m = Bits32 (opcode, 3, 0);
9810                 setflags = BitIsSet (opcode, 20);
9811 
9812                 // if Rd == "1111" && S == "1" then SEE CMP (register);
9813                 if (d == 15 && setflags == 1)
9814                     return EmulateCMPImm (opcode, eEncodingT3);
9815 
9816                 // if Rn == "1101" then SEE SUB (SP minus register);
9817                 if (n == 13)
9818                     return EmulateSUBSPReg (opcode, eEncodingT1);
9819 
9820                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9821                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9822 
9823                 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE;
9824                 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m))
9825                     return false;
9826 
9827                 break;
9828 
9829             case eEncodingA1:
9830                 // if Rn == '1101' then SEE SUB (SP minus register);
9831                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
9832                 d = Bits32 (opcode, 15, 12);
9833                 n = Bits32 (opcode, 19, 16);
9834                 m = Bits32 (opcode, 3, 0);
9835                 setflags = BitIsSet (opcode, 20);
9836 
9837                 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9838                 if ((d == 15) && setflags)
9839                     EmulateSUBSPcLrEtc (opcode, encoding);
9840 
9841                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9842                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9843 
9844                 break;
9845 
9846             default:
9847                 return false;
9848         }
9849 
9850         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9851         uint32_t Rm = ReadCoreReg (m, &success);
9852         if (!success)
9853             return false;
9854 
9855         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9856         if (!success)
9857             return false;
9858 
9859         // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
9860         uint32_t Rn = ReadCoreReg (n, &success);
9861         if (!success)
9862             return false;
9863 
9864         AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1);
9865 
9866         // if d == 15 then // Can only occur for ARM encoding
9867             // ALUWritePC(result); // setflags is always FALSE here
9868         // else
9869             // R[d] = result;
9870             // if setflags then
9871                 // APSR.N = result<31>;
9872                 // APSR.Z = IsZeroBit(result);
9873                 // APSR.C = carry;
9874                 // APSR.V = overflow;
9875 
9876         EmulateInstruction::Context context;
9877         context.type = eContextArithmetic;
9878         RegisterInfo reg_n;
9879         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9880         RegisterInfo reg_m;
9881         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9882         context.SetRegisterRegisterOperands (reg_n, reg_m);
9883 
9884         if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9885             return false;
9886     }
9887     return true;
9888 }
9889 
9890 // A8.6.202 STREX
9891 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a
9892 // word from a register to memory if the executing processor has exclusive access to the memory addressed.
9893 bool
9894 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding)
9895 {
9896 #if 0
9897     if ConditionPassed() then
9898         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9899         address = R[n] + imm32;
9900         if ExclusiveMonitorsPass(address,4) then
9901             MemA[address,4] = R[t];
9902             R[d] = 0;
9903         else
9904             R[d] = 1;
9905 #endif
9906 
9907     bool success = false;
9908 
9909     if (ConditionPassed(opcode))
9910     {
9911         uint32_t d;
9912         uint32_t t;
9913         uint32_t n;
9914         uint32_t imm32;
9915         const uint32_t addr_byte_size = GetAddressByteSize();
9916 
9917         switch (encoding)
9918         {
9919             case eEncodingT1:
9920                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
9921                 d = Bits32 (opcode, 11, 8);
9922                 t = Bits32 (opcode, 15, 12);
9923                 n = Bits32 (opcode, 19, 16);
9924                 imm32 = Bits32 (opcode, 7, 0) << 2;
9925 
9926                 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
9927                 if (BadReg (d) || BadReg (t) || (n == 15))
9928                   return false;
9929 
9930                 // if d == n || d == t then UNPREDICTABLE;
9931                 if ((d == n) || (d == t))
9932                   return false;
9933 
9934                 break;
9935 
9936             case eEncodingA1:
9937                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset
9938                 d = Bits32 (opcode, 15, 12);
9939                 t = Bits32 (opcode, 3, 0);
9940                 n = Bits32 (opcode, 19, 16);
9941                 imm32 = 0;
9942 
9943                 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
9944                 if ((d == 15) || (t == 15) || (n == 15))
9945                     return false;
9946 
9947                 // if d == n || d == t then UNPREDICTABLE;
9948                 if ((d == n) || (d == t))
9949                     return false;
9950 
9951                 break;
9952 
9953             default:
9954                 return false;
9955         }
9956 
9957         // address = R[n] + imm32;
9958         uint32_t Rn = ReadCoreReg (n, &success);
9959         if (!success)
9960             return false;
9961 
9962         addr_t address = Rn + imm32;
9963 
9964         RegisterInfo base_reg;
9965         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9966         RegisterInfo data_reg;
9967         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9968         EmulateInstruction::Context context;
9969         context.type = eContextRegisterStore;
9970         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32);
9971 
9972         // if ExclusiveMonitorsPass(address,4) then
9973         // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this
9974         //                                                         always return true.
9975         if (true)
9976         {
9977             // MemA[address,4] = R[t];
9978             uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
9979             if (!success)
9980                 return false;
9981 
9982             if (!MemAWrite (context, address, Rt, addr_byte_size))
9983                 return false;
9984 
9985             // R[d] = 0;
9986             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0))
9987                 return false;
9988         }
9989 #if 0 // unreachable because if true
9990         else
9991         {
9992             // R[d] = 1;
9993             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
9994                 return false;
9995         }
9996 #endif // unreachable because if true
9997     }
9998     return true;
9999 }
10000 
10001 // A8.6.197 STRB (immediate, ARM)
10002 bool
10003 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding)
10004 {
10005 #if 0
10006     if ConditionPassed() then
10007         EncodingSpecificOperations();
10008         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10009         address = if index then offset_addr else R[n];
10010         MemU[address,1] = R[t]<7:0>;
10011         if wback then R[n] = offset_addr;
10012 #endif
10013 
10014     bool success = false;
10015 
10016     if (ConditionPassed(opcode))
10017     {
10018         uint32_t t;
10019         uint32_t n;
10020         uint32_t imm32;
10021         bool index;
10022         bool add;
10023         bool wback;
10024 
10025         switch (encoding)
10026         {
10027             case eEncodingA1:
10028                 // if P == '0' && W == '1' then SEE STRBT;
10029                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10030                 t = Bits32 (opcode, 15, 12);
10031                 n = Bits32 (opcode, 19, 16);
10032                 imm32 = Bits32 (opcode, 11, 0);
10033 
10034                 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10035                 index = BitIsSet (opcode, 24);
10036                 add = BitIsSet (opcode, 23);
10037                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10038 
10039                 // if t == 15 then UNPREDICTABLE;
10040                 if (t == 15)
10041                     return false;
10042 
10043                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10044                 if (wback && ((n == 15) || (n == t)))
10045                     return false;
10046 
10047                 break;
10048 
10049             default:
10050                 return false;
10051         }
10052 
10053         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10054         uint32_t Rn = ReadCoreReg (n, &success);
10055         if (!success)
10056             return false;
10057 
10058         addr_t offset_addr;
10059         if (add)
10060             offset_addr = Rn + imm32;
10061         else
10062             offset_addr = Rn - imm32;
10063 
10064         // address = if index then offset_addr else R[n];
10065         addr_t address;
10066         if (index)
10067             address = offset_addr;
10068         else
10069             address = Rn;
10070 
10071         // MemU[address,1] = R[t]<7:0>;
10072         uint32_t Rt = ReadCoreReg (t, &success);
10073         if (!success)
10074             return false;
10075 
10076         RegisterInfo base_reg;
10077         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10078         RegisterInfo data_reg;
10079         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10080         EmulateInstruction::Context context;
10081         context.type = eContextRegisterStore;
10082         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10083 
10084         if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1))
10085             return false;
10086 
10087         // if wback then R[n] = offset_addr;
10088         if (wback)
10089         {
10090             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10091                 return false;
10092         }
10093     }
10094     return true;
10095 }
10096 
10097 // A8.6.194 STR (immediate, ARM)
10098 bool
10099 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding)
10100 {
10101 #if 0
10102     if ConditionPassed() then
10103         EncodingSpecificOperations();
10104         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10105         address = if index then offset_addr else R[n];
10106         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10107         if wback then R[n] = offset_addr;
10108 #endif
10109 
10110     bool success = false;
10111 
10112     if (ConditionPassed(opcode))
10113     {
10114         uint32_t t;
10115         uint32_t n;
10116         uint32_t imm32;
10117         bool index;
10118         bool add;
10119         bool wback;
10120 
10121         const uint32_t addr_byte_size = GetAddressByteSize();
10122 
10123         switch (encoding)
10124         {
10125             case eEncodingA1:
10126                 // if P == '0' && W == '1' then SEE STRT;
10127                 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == '000000000100' then SEE PUSH;
10128                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10129                 t = Bits32 (opcode, 15, 12);
10130                 n = Bits32 (opcode, 19, 16);
10131                 imm32 = Bits32 (opcode, 11, 0);
10132 
10133                 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10134                 index = BitIsSet (opcode, 24);
10135                 add = BitIsSet (opcode, 23);
10136                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10137 
10138                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10139                 if (wback && ((n == 15) || (n == t)))
10140                     return false;
10141 
10142                 break;
10143 
10144             default:
10145                 return false;
10146         }
10147 
10148         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10149         uint32_t Rn = ReadCoreReg (n, &success);
10150         if (!success)
10151             return false;
10152 
10153         addr_t offset_addr;
10154         if (add)
10155             offset_addr = Rn + imm32;
10156         else
10157             offset_addr = Rn - imm32;
10158 
10159         // address = if index then offset_addr else R[n];
10160         addr_t address;
10161         if (index)
10162             address = offset_addr;
10163         else
10164             address = Rn;
10165 
10166         RegisterInfo base_reg;
10167         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10168         RegisterInfo data_reg;
10169         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10170         EmulateInstruction::Context context;
10171         context.type = eContextRegisterStore;
10172         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10173 
10174         // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10175         uint32_t Rt = ReadCoreReg (t, &success);
10176         if (!success)
10177             return false;
10178 
10179         if (t == 15)
10180         {
10181             uint32_t pc_value = ReadCoreReg (PC_REG, &success);
10182             if (!success)
10183                 return false;
10184 
10185             if (!MemUWrite (context, address, pc_value, addr_byte_size))
10186                 return false;
10187         }
10188         else
10189         {
10190             if (!MemUWrite (context, address, Rt, addr_byte_size))
10191                   return false;
10192         }
10193 
10194         // if wback then R[n] = offset_addr;
10195         if (wback)
10196         {
10197             context.type = eContextAdjustBaseRegister;
10198             context.SetImmediate (offset_addr);
10199 
10200             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10201                 return false;
10202         }
10203     }
10204     return true;
10205 }
10206 
10207 // A8.6.66 LDRD (immediate)
10208 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two
10209 // words from memory, and writes them to two registers.  It can use offset, post-indexed, or pre-indexed addressing.
10210 bool
10211 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding)
10212 {
10213 #if 0
10214     if ConditionPassed() then
10215         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10216         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10217         address = if index then offset_addr else R[n];
10218         R[t] = MemA[address,4];
10219         R[t2] = MemA[address+4,4];
10220         if wback then R[n] = offset_addr;
10221 #endif
10222 
10223     bool success = false;
10224 
10225     if (ConditionPassed(opcode))
10226     {
10227         uint32_t t;
10228         uint32_t t2;
10229         uint32_t n;
10230         uint32_t imm32;
10231         bool index;
10232         bool add;
10233         bool wback;
10234 
10235         switch (encoding)
10236         {
10237             case eEncodingT1:
10238                 //if P == '0' && W == '0' then SEE 'Related encodings';
10239                 //if Rn == '1111' then SEE LDRD (literal);
10240                 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
10241                 t = Bits32 (opcode, 15, 12);
10242                 t2 = Bits32 (opcode, 11, 8);
10243                 n = Bits32 (opcode, 19, 16);
10244                 imm32 = Bits32 (opcode, 7, 0) << 2;
10245 
10246                 //index = (P == '1'); add = (U == '1'); wback = (W == '1');
10247                 index = BitIsSet (opcode, 24);
10248                 add = BitIsSet (opcode, 23);
10249                 wback = BitIsSet (opcode, 21);
10250 
10251                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10252                 if (wback && ((n == t) || (n == t2)))
10253                     return false;
10254 
10255                 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10256                 if (BadReg (t) || BadReg (t2) || (t == t2))
10257                     return false;
10258 
10259                 break;
10260 
10261             case eEncodingA1:
10262                 //if Rn == '1111' then SEE LDRD (literal);
10263                 //if Rt<0> == '1' then UNPREDICTABLE;
10264                 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10265                 t = Bits32 (opcode, 15, 12);
10266                 if (BitIsSet (t, 0))
10267                     return false;
10268                 t2 = t + 1;
10269                 n = Bits32 (opcode, 19, 16);
10270                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10271 
10272                 //index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10273                 index = BitIsSet (opcode, 24);
10274                 add = BitIsSet (opcode, 23);
10275                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10276 
10277                 //if P == '0' && W == '1' then UNPREDICTABLE;
10278                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10279                     return false;
10280 
10281                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10282                 if (wback && ((n == t) || (n == t2)))
10283                     return false;
10284 
10285                 //if t2 == 15 then UNPREDICTABLE;
10286                 if (t2 == 15)
10287                     return false;
10288 
10289                 break;
10290 
10291             default:
10292                 return false;
10293         }
10294 
10295         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10296         uint32_t Rn = ReadCoreReg (n, &success);
10297         if (!success)
10298             return false;
10299 
10300         addr_t offset_addr;
10301         if (add)
10302                   offset_addr = Rn + imm32;
10303         else
10304             offset_addr = Rn - imm32;
10305 
10306         //address = if index then offset_addr else R[n];
10307         addr_t address;
10308         if (index)
10309             address = offset_addr;
10310         else
10311             address = Rn;
10312 
10313         //R[t] = MemA[address,4];
10314         RegisterInfo base_reg;
10315         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10316 
10317         EmulateInstruction::Context context;
10318         if (n == 13)
10319             context.type = eContextPopRegisterOffStack;
10320         else
10321             context.type = eContextRegisterLoad;
10322         context.SetAddress(address);
10323 
10324         const uint32_t addr_byte_size = GetAddressByteSize();
10325         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10326         if (!success)
10327             return false;
10328 
10329         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10330             return false;
10331 
10332         //R[t2] = MemA[address+4,4];
10333         context.SetAddress(address + 4);
10334         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10335         if (!success)
10336             return false;
10337 
10338         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10339             return false;
10340 
10341         //if wback then R[n] = offset_addr;
10342         if (wback)
10343         {
10344             context.type = eContextAdjustBaseRegister;
10345             context.SetAddress (offset_addr);
10346 
10347             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10348                 return false;
10349         }
10350     }
10351     return true;
10352 }
10353 
10354 // A8.6.68 LDRD (register)
10355 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two
10356 // words from memory, and writes them to two registers.  It can use offset, post-indexed or pre-indexed addressing.
10357 bool
10358 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding)
10359 {
10360 #if 0
10361     if ConditionPassed() then
10362         EncodingSpecificOperations();
10363         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10364         address = if index then offset_addr else R[n];
10365         R[t] = MemA[address,4];
10366         R[t2] = MemA[address+4,4];
10367         if wback then R[n] = offset_addr;
10368 #endif
10369 
10370     bool success = false;
10371 
10372     if (ConditionPassed(opcode))
10373     {
10374         uint32_t t;
10375         uint32_t t2;
10376         uint32_t n;
10377         uint32_t m;
10378         bool index;
10379         bool add;
10380         bool wback;
10381 
10382         switch (encoding)
10383         {
10384             case eEncodingA1:
10385                 // if Rt<0> == '1' then UNPREDICTABLE;
10386                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10387                 t = Bits32 (opcode, 15, 12);
10388                 if (BitIsSet (t, 0))
10389                     return false;
10390                 t2 = t + 1;
10391                 n = Bits32 (opcode, 19, 16);
10392                 m = Bits32 (opcode, 3, 0);
10393 
10394                 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10395                 index = BitIsSet (opcode, 24);
10396                 add = BitIsSet (opcode, 23);
10397                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10398 
10399                 // if P == '0' && W == '1' then UNPREDICTABLE;
10400                   if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10401                   return false;
10402 
10403                 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10404                   if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10405                   return false;
10406 
10407                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10408                   if (wback && ((n == 15) || (n == t) || (n == t2)))
10409                   return false;
10410 
10411                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10412                 if ((ArchVersion() < 6) && wback && (m == n))
10413                   return false;
10414                 break;
10415 
10416             default:
10417                 return false;
10418         }
10419 
10420         uint32_t Rn = ReadCoreReg (n, &success);
10421         if (!success)
10422             return false;
10423         RegisterInfo base_reg;
10424         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10425 
10426         uint32_t Rm = ReadCoreReg (m, &success);
10427         if (!success)
10428             return false;
10429         RegisterInfo offset_reg;
10430         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10431 
10432         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10433         addr_t offset_addr;
10434         if (add)
10435             offset_addr = Rn + Rm;
10436         else
10437             offset_addr = Rn - Rm;
10438 
10439         // address = if index then offset_addr else R[n];
10440         addr_t address;
10441         if (index)
10442             address = offset_addr;
10443         else
10444             address = Rn;
10445 
10446         EmulateInstruction::Context context;
10447         if (n == 13)
10448             context.type = eContextPopRegisterOffStack;
10449         else
10450             context.type = eContextRegisterLoad;
10451         context.SetAddress(address);
10452 
10453         // R[t] = MemA[address,4];
10454         const uint32_t addr_byte_size = GetAddressByteSize();
10455         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10456         if (!success)
10457             return false;
10458 
10459         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10460             return false;
10461 
10462         // R[t2] = MemA[address+4,4];
10463 
10464         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10465         if (!success)
10466             return false;
10467 
10468         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10469             return false;
10470 
10471         // if wback then R[n] = offset_addr;
10472         if (wback)
10473         {
10474             context.type = eContextAdjustBaseRegister;
10475             context.SetAddress (offset_addr);
10476 
10477             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10478                 return false;
10479         }
10480     }
10481     return true;
10482 }
10483 
10484 // A8.6.200 STRD (immediate)
10485 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and
10486 // stores two words from two registers to memory.  It can use offset, post-indexed, or pre-indexed addressing.
10487 bool
10488 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding)
10489 {
10490 #if 0
10491     if ConditionPassed() then
10492         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10493         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10494         address = if index then offset_addr else R[n];
10495         MemA[address,4] = R[t];
10496         MemA[address+4,4] = R[t2];
10497         if wback then R[n] = offset_addr;
10498 #endif
10499 
10500     bool success = false;
10501 
10502     if (ConditionPassed(opcode))
10503     {
10504         uint32_t t;
10505         uint32_t t2;
10506         uint32_t n;
10507         uint32_t imm32;
10508         bool index;
10509         bool add;
10510         bool wback;
10511 
10512         switch (encoding)
10513         {
10514             case eEncodingT1:
10515                 // if P == '0' && W == '0' then SEE 'Related encodings';
10516                 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
10517                 t = Bits32 (opcode, 15, 12);
10518                 t2 = Bits32 (opcode, 11, 8);
10519                 n = Bits32 (opcode, 19, 16);
10520                 imm32 = Bits32 (opcode, 7, 0) << 2;
10521 
10522                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
10523                 index = BitIsSet (opcode, 24);
10524                 add = BitIsSet (opcode, 23);
10525                 wback = BitIsSet (opcode, 21);
10526 
10527                 // if wback && (n == t || n == t2) then UNPREDICTABLE;
10528                 if (wback && ((n == t) || (n == t2)))
10529                     return false;
10530 
10531                 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10532                 if ((n == 15) || BadReg (t) || BadReg (t2))
10533                     return false;
10534 
10535                 break;
10536 
10537             case eEncodingA1:
10538                 // if Rt<0> == '1' then UNPREDICTABLE;
10539                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10540                 t = Bits32 (opcode, 15, 12);
10541                 if (BitIsSet (t, 0))
10542                     return false;
10543 
10544                 t2 = t + 1;
10545                 n = Bits32 (opcode, 19, 16);
10546                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10547 
10548                 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10549                 index = BitIsSet (opcode, 24);
10550                 add = BitIsSet (opcode, 23);
10551                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10552 
10553                 // if P == '0' && W == '1' then UNPREDICTABLE;
10554                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10555                     return false;
10556 
10557                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10558                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10559                     return false;
10560 
10561                 // if t2 == 15 then UNPREDICTABLE;
10562                 if (t2 == 15)
10563                     return false;
10564 
10565                 break;
10566 
10567             default:
10568                 return false;
10569         }
10570 
10571         RegisterInfo base_reg;
10572         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10573 
10574         uint32_t Rn = ReadCoreReg (n, &success);
10575         if (!success)
10576             return false;
10577 
10578         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10579         addr_t offset_addr;
10580         if (add)
10581             offset_addr = Rn + imm32;
10582         else
10583             offset_addr = Rn - imm32;
10584 
10585         //address = if index then offset_addr else R[n];
10586         addr_t address;
10587         if (index)
10588             address = offset_addr;
10589         else
10590             address = Rn;
10591 
10592         //MemA[address,4] = R[t];
10593         RegisterInfo data_reg;
10594         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10595 
10596         uint32_t data = ReadCoreReg (t, &success);
10597         if (!success)
10598             return false;
10599 
10600         EmulateInstruction::Context context;
10601         if (n == 13)
10602             context.type = eContextPushRegisterOnStack;
10603         else
10604             context.type = eContextRegisterStore;
10605         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10606 
10607         const uint32_t addr_byte_size = GetAddressByteSize();
10608 
10609         if (!MemAWrite (context, address, data, addr_byte_size))
10610             return false;
10611 
10612         //MemA[address+4,4] = R[t2];
10613         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10614         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10615 
10616         data = ReadCoreReg (t2, &success);
10617         if (!success)
10618             return false;
10619 
10620         if (!MemAWrite (context, address + 4, data, addr_byte_size))
10621             return false;
10622 
10623         //if wback then R[n] = offset_addr;
10624         if (wback)
10625         {
10626             if (n == 13)
10627                 context.type = eContextAdjustStackPointer;
10628             else
10629                 context.type = eContextAdjustBaseRegister;
10630             context.SetAddress (offset_addr);
10631 
10632             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10633                 return false;
10634         }
10635     }
10636     return true;
10637 }
10638 
10639 
10640 // A8.6.201 STRD (register)
10641 bool
10642 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding)
10643 {
10644 #if 0
10645     if ConditionPassed() then
10646         EncodingSpecificOperations();
10647         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10648         address = if index then offset_addr else R[n];
10649         MemA[address,4] = R[t];
10650         MemA[address+4,4] = R[t2];
10651         if wback then R[n] = offset_addr;
10652 #endif
10653 
10654     bool success = false;
10655 
10656     if (ConditionPassed(opcode))
10657     {
10658         uint32_t t;
10659         uint32_t t2;
10660         uint32_t n;
10661         uint32_t m;
10662         bool index;
10663         bool add;
10664         bool wback;
10665 
10666         switch (encoding)
10667         {
10668             case eEncodingA1:
10669                 // if Rt<0> == '1' then UNPREDICTABLE;
10670                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10671                 t = Bits32 (opcode, 15, 12);
10672                 if (BitIsSet (t, 0))
10673                    return false;
10674 
10675                 t2 = t+1;
10676                 n = Bits32 (opcode, 19, 16);
10677                 m = Bits32 (opcode, 3, 0);
10678 
10679                 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10680                 index = BitIsSet (opcode, 24);
10681                 add = BitIsSet (opcode, 23);
10682                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10683 
10684                 // if P == '0' && W == '1' then UNPREDICTABLE;
10685                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10686                    return false;
10687 
10688                 // if t2 == 15 || m == 15 then UNPREDICTABLE;
10689                 if ((t2 == 15) || (m == 15))
10690                    return false;
10691 
10692                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10693                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10694                    return false;
10695 
10696                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10697                 if ((ArchVersion() < 6) && wback && (m == n))
10698                    return false;
10699 
10700                 break;
10701 
10702             default:
10703                 return false;
10704         }
10705 
10706         RegisterInfo base_reg;
10707         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10708         RegisterInfo offset_reg;
10709         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10710         RegisterInfo data_reg;
10711 
10712         uint32_t Rn = ReadCoreReg (n, &success);
10713         if (!success)
10714             return false;
10715 
10716         uint32_t Rm = ReadCoreReg (m, &success);
10717         if (!success)
10718             return false;
10719 
10720         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10721         addr_t offset_addr;
10722         if (add)
10723             offset_addr = Rn + Rm;
10724         else
10725             offset_addr = Rn - Rm;
10726 
10727         // address = if index then offset_addr else R[n];
10728         addr_t address;
10729         if (index)
10730             address = offset_addr;
10731         else
10732             address = Rn;
10733                           // MemA[address,4] = R[t];
10734         uint32_t Rt = ReadCoreReg (t, &success);
10735         if (!success)
10736             return false;
10737 
10738         EmulateInstruction::Context context;
10739         if (t == 13)
10740             context.type = eContextPushRegisterOnStack;
10741         else
10742             context.type = eContextRegisterStore;
10743 
10744         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10745         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10746 
10747         const uint32_t addr_byte_size = GetAddressByteSize();
10748 
10749         if (!MemAWrite (context, address, Rt, addr_byte_size))
10750             return false;
10751 
10752         // MemA[address+4,4] = R[t2];
10753         uint32_t Rt2 = ReadCoreReg (t2, &success);
10754         if (!success)
10755             return false;
10756 
10757         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10758 
10759         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10760 
10761         if (!MemAWrite (context, address + 4, Rt2, addr_byte_size))
10762             return false;
10763 
10764         // if wback then R[n] = offset_addr;
10765         if (wback)
10766         {
10767             context.type = eContextAdjustBaseRegister;
10768             context.SetAddress (offset_addr);
10769 
10770             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10771                 return false;
10772 
10773         }
10774     }
10775     return true;
10776 }
10777 
10778 // A8.6.319 VLDM
10779 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from
10780 // an ARM core register.
10781 bool
10782 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding)
10783 {
10784 #if 0
10785     if ConditionPassed() then
10786         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10787         address = if add then R[n] else R[n]-imm32;
10788         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10789         for r = 0 to regs-1
10790             if single_regs then
10791                 S[d+r] = MemA[address,4]; address = address+4;
10792             else
10793                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10794                 // Combine the word-aligned words in the correct order for current endianness.
10795                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10796 #endif
10797 
10798     bool success = false;
10799 
10800     if (ConditionPassed(opcode))
10801     {
10802         bool single_regs;
10803         bool add;
10804         bool wback;
10805         uint32_t d;
10806         uint32_t n;
10807         uint32_t imm32;
10808         uint32_t regs;
10809 
10810         switch (encoding)
10811         {
10812             case eEncodingT1:
10813             case eEncodingA1:
10814                 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
10815                 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
10816                 // if P == '1' && W == '0' then SEE VLDR;
10817                 // if P == U && W == '1' then UNDEFINED;
10818                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10819                     return false;
10820 
10821                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10822                 // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
10823                 single_regs = false;
10824                 add = BitIsSet (opcode, 23);
10825                 wback = BitIsSet (opcode, 21);
10826 
10827                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
10828                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10829                 n = Bits32 (opcode, 19, 16);
10830                 imm32 = Bits32 (opcode, 7, 0) << 2;
10831 
10832                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'.
10833                 regs = Bits32 (opcode, 7, 0) / 2;
10834 
10835                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10836                 if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
10837                     return false;
10838 
10839                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10840                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10841                     return false;
10842 
10843                 break;
10844 
10845             case eEncodingT2:
10846             case eEncodingA2:
10847                 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
10848                 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
10849                 // if P == '1' && W == '0' then SEE VLDR;
10850                 // if P == U && W == '1' then UNDEFINED;
10851                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10852                     return false;
10853 
10854                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10855                 // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn);
10856                 single_regs = true;
10857                 add = BitIsSet (opcode, 23);
10858                 wback = BitIsSet (opcode, 21);
10859                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10860                 n = Bits32 (opcode, 19, 16);
10861 
10862                 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
10863                 imm32 = Bits32 (opcode, 7, 0) << 2;
10864                 regs = Bits32 (opcode, 7, 0);
10865 
10866                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10867                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10868                     return false;
10869 
10870                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10871                 if ((regs == 0) || ((d + regs) > 32))
10872                     return false;
10873                 break;
10874 
10875             default:
10876                 return false;
10877         }
10878 
10879         RegisterInfo base_reg;
10880         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10881 
10882         uint32_t Rn = ReadCoreReg (n, &success);
10883         if (!success)
10884             return false;
10885 
10886         // address = if add then R[n] else R[n]-imm32;
10887         addr_t address;
10888         if (add)
10889             address = Rn;
10890         else
10891             address = Rn - imm32;
10892 
10893         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10894         EmulateInstruction::Context context;
10895 
10896         if (wback)
10897         {
10898             uint32_t value;
10899             if (add)
10900                 value = Rn + imm32;
10901             else
10902                 value = Rn - imm32;
10903 
10904             context.type = eContextAdjustBaseRegister;
10905             context.SetImmediateSigned (value - Rn);
10906             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10907                 return false;
10908 
10909         }
10910 
10911         const uint32_t addr_byte_size = GetAddressByteSize();
10912         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10913 
10914         context.type = eContextRegisterLoad;
10915 
10916         // for r = 0 to regs-1
10917         for (uint32_t r = 0; r < regs; ++r)
10918         {
10919             if (single_regs)
10920             {
10921                 // S[d+r] = MemA[address,4]; address = address+4;
10922                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10923 
10924                 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10925                 if (!success)
10926                     return false;
10927 
10928                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10929                     return false;
10930 
10931                 address = address + 4;
10932             }
10933             else
10934             {
10935                 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10936                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10937                 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10938                 if (!success)
10939                     return false;
10940 
10941                 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10942                 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10943                 if (!success)
10944                     return false;
10945 
10946                 address = address + 8;
10947                 // // Combine the word-aligned words in the correct order for current endianness.
10948                 // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10949                 uint64_t data;
10950                 if (GetByteOrder() == eByteOrderBig)
10951                 {
10952                     data = word1;
10953                     data = (data << 32) | word2;
10954                 }
10955                 else
10956                 {
10957                     data = word2;
10958                     data = (data << 32) | word1;
10959                 }
10960 
10961                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10962                     return false;
10963             }
10964         }
10965     }
10966     return true;
10967 }
10968 
10969 // A8.6.399 VSTM
10970 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an
10971 // ARM core register.
10972 bool
10973 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding)
10974 {
10975 #if 0
10976     if ConditionPassed() then
10977         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10978         address = if add then R[n] else R[n]-imm32;
10979         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10980         for r = 0 to regs-1
10981             if single_regs then
10982                 MemA[address,4] = S[d+r]; address = address+4;
10983             else
10984                 // Store as two word-aligned words in the correct order for current endianness.
10985                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10986                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10987                 address = address+8;
10988 #endif
10989 
10990     bool success = false;
10991 
10992     if (ConditionPassed (opcode))
10993     {
10994         bool single_regs;
10995         bool add;
10996         bool wback;
10997         uint32_t d;
10998         uint32_t n;
10999         uint32_t imm32;
11000         uint32_t regs;
11001 
11002         switch (encoding)
11003         {
11004             case eEncodingT1:
11005             case eEncodingA1:
11006                 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11007                 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11008                 // if P == '1' && W == '0' then SEE VSTR;
11009                 // if P == U && W == '1' then UNDEFINED;
11010                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
11011                     return false;
11012 
11013                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
11014                 // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
11015                 single_regs = false;
11016                 add = BitIsSet (opcode, 23);
11017                 wback = BitIsSet (opcode, 21);
11018 
11019                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
11020                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11021                 n = Bits32 (opcode, 19, 16);
11022                 imm32 = Bits32 (opcode, 7, 0) << 2;
11023 
11024                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'.
11025                 regs = Bits32 (opcode, 7, 0) / 2;
11026 
11027                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
11028                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11029                     return false;
11030 
11031                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11032                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11033                     return false;
11034 
11035                 break;
11036 
11037             case eEncodingT2:
11038             case eEncodingA2:
11039                 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11040                 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11041                 // if P == '1' && W == '0' then SEE VSTR;
11042                 // if P == U && W == '1' then UNDEFINED;
11043                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
11044                     return false;
11045 
11046                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
11047                 // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn);
11048                 single_regs = true;
11049                 add = BitIsSet (opcode, 23);
11050                 wback = BitIsSet (opcode, 21);
11051                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11052                 n = Bits32 (opcode, 19, 16);
11053 
11054                 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
11055                 imm32 = Bits32 (opcode, 7, 0) << 2;
11056                 regs = Bits32 (opcode, 7, 0);
11057 
11058                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
11059                 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM)))
11060                     return false;
11061 
11062                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11063                 if ((regs == 0) || ((d + regs) > 32))
11064                     return false;
11065 
11066                 break;
11067 
11068             default:
11069                 return false;
11070         }
11071 
11072         RegisterInfo base_reg;
11073         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11074 
11075         uint32_t Rn = ReadCoreReg (n, &success);
11076         if (!success)
11077             return false;
11078 
11079         // address = if add then R[n] else R[n]-imm32;
11080         addr_t address;
11081         if (add)
11082             address = Rn;
11083         else
11084             address = Rn - imm32;
11085 
11086         EmulateInstruction::Context context;
11087         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11088         if (wback)
11089         {
11090             uint32_t value;
11091             if (add)
11092                 value = Rn + imm32;
11093             else
11094                 value = Rn - imm32;
11095 
11096             context.type = eContextAdjustBaseRegister;
11097             context.SetRegisterPlusOffset (base_reg, value - Rn);
11098 
11099             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11100                 return false;
11101         }
11102 
11103         const uint32_t addr_byte_size = GetAddressByteSize();
11104         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11105 
11106         context.type = eContextRegisterStore;
11107         // for r = 0 to regs-1
11108         for (uint32_t r = 0; r < regs; ++r)
11109         {
11110 
11111             if (single_regs)
11112             {
11113                 // MemA[address,4] = S[d+r]; address = address+4;
11114                 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
11115                 if (!success)
11116                     return false;
11117 
11118                 RegisterInfo data_reg;
11119                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
11120                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11121                 if (!MemAWrite (context, address, data, addr_byte_size))
11122                     return false;
11123 
11124                 address = address + 4;
11125             }
11126             else
11127             {
11128                 // // Store as two word-aligned words in the correct order for current endianness.
11129                 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
11130                 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
11131                 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
11132                 if (!success)
11133                     return false;
11134 
11135                 RegisterInfo data_reg;
11136                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
11137 
11138                 if (GetByteOrder() == eByteOrderBig)
11139                 {
11140                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11141                     if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11142                         return false;
11143 
11144                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11145                     if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size))
11146                         return false;
11147                 }
11148                 else
11149                 {
11150                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11151                     if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11152                         return false;
11153 
11154                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11155                     if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11156                         return false;
11157                 }
11158                 // address = address+8;
11159                 address = address + 8;
11160             }
11161         }
11162     }
11163     return true;
11164 }
11165 
11166 // A8.6.320
11167 // This instruction loads a single extension register from memory, using an address from an ARM core register, with
11168 // an optional offset.
11169 bool
11170 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
11171 {
11172 #if 0
11173     if ConditionPassed() then
11174         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11175         base = if n == 15 then Align(PC,4) else R[n];
11176         address = if add then (base + imm32) else (base - imm32);
11177         if single_reg then
11178             S[d] = MemA[address,4];
11179         else
11180             word1 = MemA[address,4]; word2 = MemA[address+4,4];
11181             // Combine the word-aligned words in the correct order for current endianness.
11182             D[d] = if BigEndian() then word1:word2 else word2:word1;
11183 #endif
11184 
11185     bool success = false;
11186 
11187     if (ConditionPassed (opcode))
11188     {
11189         bool single_reg;
11190         bool add;
11191         uint32_t imm32;
11192         uint32_t d;
11193         uint32_t n;
11194 
11195         switch (encoding)
11196         {
11197             case eEncodingT1:
11198             case eEncodingA1:
11199                 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11200                 single_reg = false;
11201                 add = BitIsSet (opcode, 23);
11202                 imm32 = Bits32 (opcode, 7, 0) << 2;
11203 
11204                 // d = UInt(D:Vd); n = UInt(Rn);
11205                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11206                 n = Bits32 (opcode, 19, 16);
11207 
11208                 break;
11209 
11210             case eEncodingT2:
11211             case eEncodingA2:
11212                 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11213                 single_reg = true;
11214                 add = BitIsSet (opcode, 23);
11215                 imm32 = Bits32 (opcode, 7, 0) << 2;
11216 
11217                 // d = UInt(Vd:D); n = UInt(Rn);
11218                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11219                 n = Bits32 (opcode, 19, 16);
11220 
11221                 break;
11222 
11223             default:
11224                 return false;
11225         }
11226         RegisterInfo base_reg;
11227         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11228 
11229         uint32_t Rn = ReadCoreReg (n, &success);
11230         if (!success)
11231             return false;
11232 
11233         // base = if n == 15 then Align(PC,4) else R[n];
11234         uint32_t base;
11235         if (n == 15)
11236             base = AlignPC (Rn);
11237         else
11238             base = Rn;
11239 
11240         // address = if add then (base + imm32) else (base - imm32);
11241         addr_t address;
11242         if (add)
11243             address = base + imm32;
11244         else
11245             address = base - imm32;
11246 
11247         const uint32_t addr_byte_size = GetAddressByteSize();
11248         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11249 
11250         EmulateInstruction::Context context;
11251         context.type = eContextRegisterLoad;
11252         context.SetRegisterPlusOffset (base_reg, address - base);
11253 
11254         if (single_reg)
11255         {
11256             // S[d] = MemA[address,4];
11257             uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
11258             if (!success)
11259                 return false;
11260 
11261             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data))
11262                 return false;
11263         }
11264         else
11265         {
11266             // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11267             uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
11268             if (!success)
11269                 return false;
11270 
11271             context.SetRegisterPlusOffset (base_reg, (address + 4) - base);
11272             uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
11273             if (!success)
11274                 return false;
11275             // // Combine the word-aligned words in the correct order for current endianness.
11276             // D[d] = if BigEndian() then word1:word2 else word2:word1;
11277             uint64_t data64;
11278             if (GetByteOrder() == eByteOrderBig)
11279             {
11280                 data64 = word1;
11281                 data64 = (data64 << 32) | word2;
11282             }
11283             else
11284             {
11285                 data64 = word2;
11286                 data64 = (data64 << 32) | word1;
11287             }
11288 
11289             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64))
11290                 return false;
11291         }
11292     }
11293     return true;
11294 }
11295 
11296 // A8.6.400 VSTR
11297 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an
11298 // optional offset.
11299 bool
11300 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
11301 {
11302 #if 0
11303     if ConditionPassed() then
11304         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11305         address = if add then (R[n] + imm32) else (R[n] - imm32);
11306         if single_reg then
11307             MemA[address,4] = S[d];
11308         else
11309             // Store as two word-aligned words in the correct order for current endianness.
11310             MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11311             MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11312 #endif
11313 
11314     bool success = false;
11315 
11316     if (ConditionPassed (opcode))
11317     {
11318         bool single_reg;
11319         bool add;
11320         uint32_t imm32;
11321         uint32_t d;
11322         uint32_t n;
11323 
11324         switch (encoding)
11325         {
11326             case eEncodingT1:
11327             case eEncodingA1:
11328                 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11329                 single_reg = false;
11330                 add = BitIsSet (opcode, 23);
11331                 imm32 = Bits32 (opcode, 7, 0) << 2;
11332 
11333                 // d = UInt(D:Vd); n = UInt(Rn);
11334                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11335                 n = Bits32 (opcode, 19, 16);
11336 
11337                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11338                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11339                     return false;
11340 
11341                 break;
11342 
11343             case eEncodingT2:
11344             case eEncodingA2:
11345                 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11346                 single_reg = true;
11347                 add = BitIsSet (opcode, 23);
11348                 imm32 = Bits32 (opcode, 7, 0) << 2;
11349 
11350                 // d = UInt(Vd:D); n = UInt(Rn);
11351                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11352                 n = Bits32 (opcode, 19, 16);
11353 
11354                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11355                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11356                     return false;
11357 
11358                 break;
11359 
11360             default:
11361                 return false;
11362         }
11363 
11364         RegisterInfo base_reg;
11365         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11366 
11367         uint32_t Rn = ReadCoreReg (n, &success);
11368         if (!success)
11369             return false;
11370 
11371         // address = if add then (R[n] + imm32) else (R[n] - imm32);
11372         addr_t address;
11373         if (add)
11374             address = Rn + imm32;
11375         else
11376             address = Rn - imm32;
11377 
11378         const uint32_t addr_byte_size = GetAddressByteSize();
11379         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11380 
11381         RegisterInfo data_reg;
11382         GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg);
11383         EmulateInstruction::Context context;
11384         context.type = eContextRegisterStore;
11385         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11386 
11387         if (single_reg)
11388         {
11389             // MemA[address,4] = S[d];
11390             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11391             if (!success)
11392                 return false;
11393 
11394             if (!MemAWrite (context, address, data, addr_byte_size))
11395                 return false;
11396         }
11397         else
11398         {
11399             // // Store as two word-aligned words in the correct order for current endianness.
11400             // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11401             // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11402             uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11403             if (!success)
11404                 return false;
11405 
11406             if (GetByteOrder() == eByteOrderBig)
11407             {
11408                 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11409                     return false;
11410 
11411                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11412                 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size))
11413                     return false;
11414             }
11415             else
11416             {
11417                 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11418                     return false;
11419 
11420                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11421                 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11422                     return false;
11423             }
11424         }
11425     }
11426     return true;
11427 }
11428 
11429 // A8.6.307 VLDI1 (multiple single elements)
11430 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving.  Every
11431 // element of each register is loaded.
11432 bool
11433 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding)
11434 {
11435 #if 0
11436     if ConditionPassed() then
11437         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11438         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11439         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11440         for r = 0 to regs-1
11441             for e = 0 to elements-1
11442                 Elem[D[d+r],e,esize] = MemU[address,ebytes];
11443                 address = address + ebytes;
11444 #endif
11445 
11446     bool success = false;
11447 
11448     if (ConditionPassed (opcode))
11449     {
11450         uint32_t regs;
11451         uint32_t alignment;
11452         uint32_t ebytes;
11453         uint32_t esize;
11454         uint32_t elements;
11455         uint32_t d;
11456         uint32_t n;
11457         uint32_t m;
11458         bool wback;
11459         bool register_index;
11460 
11461         switch (encoding)
11462         {
11463             case eEncodingT1:
11464             case eEncodingA1:
11465             {
11466                 // case type of
11467                     // when '0111'
11468                         // regs = 1; if align<1> == '1' then UNDEFINED;
11469                     // when '1010'
11470                         // regs = 2; if align == '11' then UNDEFINED;
11471                     // when '0110'
11472                         // regs = 3; if align<1> == '1' then UNDEFINED;
11473                     // when '0010'
11474                         // regs = 4;
11475                     // otherwise
11476                         // SEE 'Related encodings';
11477                 uint32_t type = Bits32 (opcode, 11, 8);
11478                 uint32_t align = Bits32 (opcode, 5, 4);
11479                 if (type == 7) // '0111'
11480                 {
11481                     regs = 1;
11482                     if (BitIsSet (align, 1))
11483                         return false;
11484                 }
11485                 else if (type == 10) // '1010'
11486                 {
11487                     regs = 2;
11488                     if (align == 3)
11489                         return false;
11490 
11491                 }
11492                 else if (type == 6) // '0110'
11493                 {
11494                     regs = 3;
11495                     if (BitIsSet (align, 1))
11496                         return false;
11497                 }
11498                 else if (type == 2) // '0010'
11499                 {
11500                     regs = 4;
11501                 }
11502                 else
11503                     return false;
11504 
11505                 // alignment = if align == '00' then 1 else 4 << UInt(align);
11506                 if (align == 0)
11507                     alignment = 1;
11508                 else
11509                     alignment = 4 << align;
11510 
11511                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11512                 ebytes = 1 << Bits32 (opcode, 7, 6);
11513                 esize = 8 * ebytes;
11514                 elements = 8 / ebytes;
11515 
11516                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11517                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11518                 n = Bits32 (opcode, 19, 15);
11519                 m = Bits32 (opcode, 3, 0);
11520 
11521                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11522                 wback = (m != 15);
11523                 register_index = ((m != 15) && (m != 13));
11524 
11525                 // if d+regs > 32 then UNPREDICTABLE;
11526                 if ((d + regs) > 32)
11527                     return false;
11528             }
11529                 break;
11530 
11531             default:
11532                 return false;
11533         }
11534 
11535         RegisterInfo base_reg;
11536         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11537 
11538         uint32_t Rn = ReadCoreReg (n, &success);
11539         if (!success)
11540             return false;
11541 
11542         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11543         addr_t address = Rn;
11544         if ((address % alignment) != 0)
11545             return false;
11546 
11547         EmulateInstruction::Context context;
11548         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11549         if (wback)
11550         {
11551             uint32_t Rm = ReadCoreReg (m, &success);
11552             if (!success)
11553                 return false;
11554 
11555             uint32_t offset;
11556             if (register_index)
11557                 offset = Rm;
11558             else
11559                 offset = 8 * regs;
11560 
11561             uint32_t value = Rn + offset;
11562             context.type = eContextAdjustBaseRegister;
11563             context.SetRegisterPlusOffset (base_reg, offset);
11564 
11565             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11566                 return false;
11567 
11568         }
11569 
11570         // for r = 0 to regs-1
11571         for (uint32_t r = 0; r < regs; ++r)
11572         {
11573             // for e = 0 to elements-1
11574             uint64_t assembled_data = 0;
11575             for (uint32_t e = 0; e < elements; ++e)
11576             {
11577                 // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11578                 context.type = eContextRegisterLoad;
11579                 context.SetRegisterPlusOffset (base_reg, address - Rn);
11580                 uint64_t data = MemURead (context, address, ebytes, 0, &success);
11581                 if (!success)
11582                     return false;
11583 
11584                 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data
11585 
11586                 // address = address + ebytes;
11587                 address = address + ebytes;
11588             }
11589             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data))
11590                 return false;
11591         }
11592     }
11593     return true;
11594 }
11595 
11596 // A8.6.308 VLD1 (single element to one lane)
11597 //
11598 bool
11599 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding)
11600 {
11601 #if 0
11602     if ConditionPassed() then
11603         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11604         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11605         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11606         Elem[D[d],index,esize] = MemU[address,ebytes];
11607 #endif
11608 
11609     bool success = false;
11610 
11611     if (ConditionPassed (opcode))
11612     {
11613         uint32_t ebytes;
11614         uint32_t esize;
11615         uint32_t index;
11616         uint32_t alignment;
11617         uint32_t d;
11618         uint32_t n;
11619         uint32_t m;
11620         bool wback;
11621         bool register_index;
11622 
11623         switch (encoding)
11624         {
11625             case eEncodingT1:
11626             case eEncodingA1:
11627             {
11628                 uint32_t size = Bits32 (opcode, 11, 10);
11629                 uint32_t index_align = Bits32 (opcode, 7, 4);
11630                 // if size == '11' then SEE VLD1 (single element to all lanes);
11631                 if (size == 3)
11632                    return EmulateVLD1SingleAll (opcode, encoding);
11633                 // case size of
11634                 if (size == 0) // when '00'
11635                 {
11636                     // if index_align<0> != '0' then UNDEFINED;
11637                     if (BitIsClear (index_align, 0))
11638                         return false;
11639 
11640                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11641                     ebytes = 1;
11642                     esize = 8;
11643                     index = Bits32 (index_align, 3, 1);
11644                     alignment = 1;
11645                 }
11646                 else if (size == 1) // when '01'
11647                 {
11648                     // if index_align<1> != '0' then UNDEFINED;
11649                     if (BitIsClear (index_align, 1))
11650                         return false;
11651 
11652                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11653                     ebytes = 2;
11654                     esize = 16;
11655                     index = Bits32 (index_align, 3, 2);
11656 
11657                     // alignment = if index_align<0> == '0' then 1 else 2;
11658                     if (BitIsClear (index_align, 0))
11659                         alignment = 1;
11660                     else
11661                         alignment = 2;
11662                 }
11663                 else if (size == 2) // when '10'
11664                 {
11665                     // if index_align<2> != '0' then UNDEFINED;
11666                     if (BitIsClear (index_align, 2))
11667                         return false;
11668 
11669                     // if index_align<1:0> != '00' && index_align<1:0> != '11' then UNDEFINED;
11670                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11671                         return false;
11672 
11673                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11674                     ebytes = 4;
11675                     esize = 32;
11676                     index = Bit32 (index_align, 3);
11677 
11678                     // alignment = if index_align<1:0> == '00' then 1 else 4;
11679                     if (Bits32 (index_align, 1, 0) == 0)
11680                         alignment = 1;
11681                     else
11682                         alignment = 4;
11683                 }
11684                 else
11685                 {
11686                     return false;
11687                 }
11688                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11689                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11690                 n = Bits32 (opcode, 19, 16);
11691                 m = Bits32 (opcode, 3, 0);
11692 
11693                 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
11694                 wback = (m != 15);
11695                 register_index = ((m != 15) && (m != 13));
11696 
11697                 if (n == 15)
11698                     return false;
11699 
11700             }
11701                 break;
11702 
11703             default:
11704                 return false;
11705         }
11706 
11707         RegisterInfo base_reg;
11708         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11709 
11710         uint32_t Rn = ReadCoreReg (n, &success);
11711         if (!success)
11712             return false;
11713 
11714         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11715         addr_t address = Rn;
11716         if ((address % alignment) != 0)
11717             return false;
11718 
11719         EmulateInstruction::Context context;
11720         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11721         if (wback)
11722         {
11723             uint32_t Rm = ReadCoreReg (m, &success);
11724             if (!success)
11725                 return false;
11726 
11727             uint32_t offset;
11728             if (register_index)
11729                 offset = Rm;
11730             else
11731                 offset = ebytes;
11732 
11733             uint32_t value = Rn + offset;
11734 
11735             context.type = eContextAdjustBaseRegister;
11736             context.SetRegisterPlusOffset (base_reg, offset);
11737 
11738             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11739                 return false;
11740         }
11741 
11742         // Elem[D[d],index,esize] = MemU[address,ebytes];
11743         uint32_t element = MemURead (context, address, esize, 0, &success);
11744         if (!success)
11745             return false;
11746 
11747         element = element << (index * esize);
11748 
11749         uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11750         if (!success)
11751             return false;
11752 
11753         uint64_t all_ones = -1;
11754         uint64_t mask = all_ones << ((index+1) * esize);  // mask is all 1's to left of where 'element' goes, & all 0's
11755                                                           // at element & to the right of element.
11756         if (index > 0)
11757             mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes.
11758                                                                      // now mask should be 0's where element goes & 1's
11759                                                                      // everywhere else.
11760 
11761         uint64_t masked_reg = reg_data & mask;  // Take original reg value & zero out 'element' bits
11762         reg_data = masked_reg & element;        // Put 'element' into those bits in reg_data.
11763 
11764         context.type = eContextRegisterLoad;
11765         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data))
11766             return false;
11767     }
11768     return true;
11769 }
11770 
11771 // A8.6.391 VST1 (multiple single elements)
11772 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four registers, without
11773 // interleaving.  Every element of each register is stored.
11774 bool
11775 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding)
11776 {
11777 #if 0
11778     if ConditionPassed() then
11779         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11780         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11781         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11782         for r = 0 to regs-1
11783             for e = 0 to elements-1
11784                 MemU[address,ebytes] = Elem[D[d+r],e,esize];
11785                 address = address + ebytes;
11786 #endif
11787 
11788     bool success = false;
11789 
11790     if (ConditionPassed (opcode))
11791     {
11792         uint32_t regs;
11793         uint32_t alignment;
11794         uint32_t ebytes;
11795         uint32_t esize;
11796         uint32_t elements;
11797         uint32_t d;
11798         uint32_t n;
11799         uint32_t m;
11800         bool wback;
11801         bool register_index;
11802 
11803         switch (encoding)
11804         {
11805             case eEncodingT1:
11806             case eEncodingA1:
11807             {
11808                 uint32_t type = Bits32 (opcode, 11, 8);
11809                 uint32_t align = Bits32 (opcode, 5, 4);
11810 
11811                 // case type of
11812                 if (type == 7)    // when '0111'
11813                 {
11814                     // regs = 1; if align<1> == '1' then UNDEFINED;
11815                     regs = 1;
11816                     if (BitIsSet (align, 1))
11817                         return false;
11818                 }
11819                 else if (type == 10) // when '1010'
11820                 {
11821                     // regs = 2; if align == '11' then UNDEFINED;
11822                     regs = 2;
11823                     if (align == 3)
11824                         return false;
11825                 }
11826                 else if (type == 6) // when '0110'
11827                 {
11828                     // regs = 3; if align<1> == '1' then UNDEFINED;
11829                     regs = 3;
11830                     if (BitIsSet (align, 1))
11831                         return false;
11832                 }
11833                 else if (type == 2) // when '0010'
11834                     // regs = 4;
11835                     regs = 4;
11836                 else // otherwise
11837                     // SEE 'Related encodings';
11838                     return false;
11839 
11840                 // alignment = if align == '00' then 1 else 4 << UInt(align);
11841                 if (align == 0)
11842                     alignment = 1;
11843                 else
11844                     alignment = 4 << align;
11845 
11846                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11847                 ebytes = 1 << Bits32 (opcode,7, 6);
11848                 esize = 8 * ebytes;
11849                 elements = 8 / ebytes;
11850 
11851                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11852                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11853                 n = Bits32 (opcode, 19, 16);
11854                 m = Bits32 (opcode, 3, 0);
11855 
11856                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11857                 wback = (m != 15);
11858                 register_index = ((m != 15) && (m != 13));
11859 
11860                 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11861                 if ((d + regs) > 32)
11862                     return false;
11863 
11864                 if (n == 15)
11865                     return false;
11866 
11867             }
11868                 break;
11869 
11870             default:
11871                 return false;
11872         }
11873 
11874         RegisterInfo base_reg;
11875         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11876 
11877         uint32_t Rn = ReadCoreReg (n, &success);
11878         if (!success)
11879             return false;
11880 
11881         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11882         addr_t address = Rn;
11883         if ((address % alignment) != 0)
11884             return false;
11885 
11886         EmulateInstruction::Context context;
11887         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11888         if (wback)
11889         {
11890             uint32_t Rm = ReadCoreReg (m, &success);
11891             if (!success)
11892                 return false;
11893 
11894             uint32_t offset;
11895             if (register_index)
11896                 offset = Rm;
11897             else
11898                 offset = 8 * regs;
11899 
11900             context.type = eContextAdjustBaseRegister;
11901             context.SetRegisterPlusOffset (base_reg, offset);
11902 
11903             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11904                 return false;
11905         }
11906 
11907         RegisterInfo data_reg;
11908         context.type = eContextRegisterStore;
11909         // for r = 0 to regs-1
11910         for (uint32_t r = 0; r < regs; ++r)
11911         {
11912             GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
11913             uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
11914             if (!success)
11915                 return false;
11916 
11917              // for e = 0 to elements-1
11918             for (uint32_t e = 0; e < elements; ++e)
11919             {
11920                 // MemU[address,ebytes] = Elem[D[d+r],e,esize];
11921                 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize);
11922 
11923                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11924                 if (!MemUWrite (context, address, word, ebytes))
11925                     return false;
11926 
11927                 // address = address + ebytes;
11928                 address = address + ebytes;
11929             }
11930         }
11931     }
11932     return true;
11933 }
11934 
11935 // A8.6.392 VST1 (single element from one lane)
11936 // This instruction stores one element to memory from one element of a register.
11937 bool
11938 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding)
11939 {
11940 #if 0
11941     if ConditionPassed() then
11942         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11943         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11944         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11945         MemU[address,ebytes] = Elem[D[d],index,esize];
11946 #endif
11947 
11948     bool success = false;
11949 
11950     if (ConditionPassed (opcode))
11951     {
11952         uint32_t ebytes;
11953         uint32_t esize;
11954         uint32_t index;
11955         uint32_t alignment;
11956         uint32_t d;
11957         uint32_t n;
11958         uint32_t m;
11959         bool wback;
11960         bool register_index;
11961 
11962         switch (encoding)
11963         {
11964             case eEncodingT1:
11965             case eEncodingA1:
11966             {
11967                 uint32_t size = Bits32 (opcode, 11, 10);
11968                 uint32_t index_align = Bits32 (opcode, 7, 4);
11969 
11970                 // if size == '11' then UNDEFINED;
11971                 if (size == 3)
11972                     return false;
11973 
11974                 // case size of
11975                 if (size == 0) // when '00'
11976                 {
11977                     // if index_align<0> != '0' then UNDEFINED;
11978                     if (BitIsClear (index_align, 0))
11979                         return false;
11980                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11981                     ebytes = 1;
11982                     esize = 8;
11983                     index = Bits32 (index_align, 3, 1);
11984                     alignment = 1;
11985                 }
11986                 else if (size == 1) // when '01'
11987                 {
11988                     // if index_align<1> != '0' then UNDEFINED;
11989                     if (BitIsClear (index_align, 1))
11990                         return false;
11991 
11992                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11993                     ebytes = 2;
11994                     esize = 16;
11995                     index = Bits32 (index_align, 3, 2);
11996 
11997                     // alignment = if index_align<0> == '0' then 1 else 2;
11998                     if (BitIsClear (index_align, 0))
11999                         alignment = 1;
12000                     else
12001                         alignment = 2;
12002                 }
12003                 else if (size == 2) // when '10'
12004                 {
12005                     // if index_align<2> != '0' then UNDEFINED;
12006                     if (BitIsClear (index_align, 2))
12007                         return false;
12008 
12009                     // if index_align<1:0> != '00' && index_align<1:0> != '11' then UNDEFINED;
12010                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
12011                         return false;
12012 
12013                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
12014                     ebytes = 4;
12015                     esize = 32;
12016                     index = Bit32 (index_align, 3);
12017 
12018                     // alignment = if index_align<1:0> == '00' then 1 else 4;
12019                     if (Bits32 (index_align, 1, 0) == 0)
12020                         alignment = 1;
12021                     else
12022                         alignment = 4;
12023                 }
12024                 else
12025                 {
12026                     return false;
12027                 }
12028                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12029                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
12030                 n = Bits32 (opcode, 19, 16);
12031                 m = Bits32 (opcode, 3, 0);
12032 
12033                 // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15 then UNPREDICTABLE;
12034                 wback = (m != 15);
12035                 register_index = ((m != 15) && (m != 13));
12036 
12037                 if (n == 15)
12038                     return false;
12039             }
12040                 break;
12041 
12042             default:
12043                 return false;
12044         }
12045 
12046         RegisterInfo base_reg;
12047         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12048 
12049         uint32_t Rn = ReadCoreReg (n, &success);
12050         if (!success)
12051             return false;
12052 
12053         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12054         addr_t address = Rn;
12055         if ((address % alignment) != 0)
12056             return false;
12057 
12058         EmulateInstruction::Context context;
12059         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12060         if (wback)
12061         {
12062             uint32_t Rm = ReadCoreReg (m, &success);
12063             if (!success)
12064                 return false;
12065 
12066             uint32_t offset;
12067             if (register_index)
12068                 offset = Rm;
12069             else
12070                 offset = ebytes;
12071 
12072             context.type = eContextAdjustBaseRegister;
12073             context.SetRegisterPlusOffset (base_reg, offset);
12074 
12075             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
12076                 return false;
12077         }
12078 
12079         // MemU[address,ebytes] = Elem[D[d],index,esize];
12080         uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12081         if (!success)
12082             return false;
12083 
12084         uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1,  index * esize);
12085 
12086         RegisterInfo data_reg;
12087         GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg);
12088         context.type = eContextRegisterStore;
12089         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
12090 
12091         if (!MemUWrite (context, address, word, ebytes))
12092             return false;
12093     }
12094     return true;
12095 }
12096 
12097 // A8.6.309 VLD1 (single element to all lanes)
12098 // This instruction loads one element from memory into every element of one or two vectors.
12099 bool
12100 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding)
12101 {
12102 #if 0
12103     if ConditionPassed() then
12104         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12105         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12106         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12107         replicated_element = Replicate(MemU[address,ebytes], elements);
12108         for r = 0 to regs-1
12109             D[d+r] = replicated_element;
12110 #endif
12111 
12112     bool success = false;
12113 
12114     if (ConditionPassed (opcode))
12115     {
12116         uint32_t ebytes;
12117         uint32_t elements;
12118         uint32_t regs;
12119         uint32_t alignment;
12120         uint32_t d;
12121         uint32_t n;
12122         uint32_t m;
12123         bool wback;
12124         bool register_index;
12125 
12126         switch (encoding)
12127         {
12128             case eEncodingT1:
12129             case eEncodingA1:
12130             {
12131                 //if size == '11' || (size == '00' && a == '1') then UNDEFINED;
12132                 uint32_t size = Bits32 (opcode, 7, 6);
12133                 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4)))
12134                     return false;
12135 
12136                 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0' then 1 else 2;
12137                 ebytes = 1 << size;
12138                 elements = 8 / ebytes;
12139                 if (BitIsClear (opcode, 5))
12140                     regs = 1;
12141                 else
12142                     regs = 2;
12143 
12144                 //alignment = if a == '0' then 1 else ebytes;
12145                 if (BitIsClear (opcode, 4))
12146                     alignment = 1;
12147                 else
12148                     alignment = ebytes;
12149 
12150                 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12151                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
12152                 n = Bits32 (opcode, 19, 16);
12153                 m = Bits32 (opcode, 3, 0);
12154 
12155                 //wback = (m != 15); register_index = (m != 15 && m != 13);
12156                 wback = (m != 15);
12157                 register_index = ((m != 15) && (m != 13));
12158 
12159                 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12160                 if ((d + regs) > 32)
12161                     return false;
12162 
12163                 if (n == 15)
12164                     return false;
12165             }
12166             break;
12167 
12168             default:
12169                 return false;
12170         }
12171 
12172         RegisterInfo base_reg;
12173         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12174 
12175         uint32_t Rn = ReadCoreReg (n, &success);
12176         if (!success)
12177             return false;
12178 
12179         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12180         addr_t address = Rn;
12181         if ((address % alignment) != 0)
12182             return false;
12183 
12184         EmulateInstruction::Context context;
12185         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12186         if (wback)
12187         {
12188             uint32_t Rm = ReadCoreReg (m, &success);
12189             if (!success)
12190                 return false;
12191 
12192             uint32_t offset;
12193             if (register_index)
12194                 offset = Rm;
12195             else
12196                 offset = ebytes;
12197 
12198             context.type = eContextAdjustBaseRegister;
12199             context.SetRegisterPlusOffset (base_reg, offset);
12200 
12201             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
12202                 return false;
12203         }
12204 
12205         // replicated_element = Replicate(MemU[address,ebytes], elements);
12206 
12207         context.type = eContextRegisterLoad;
12208         uint64_t word = MemURead (context, address, ebytes, 0, &success);
12209         if (!success)
12210             return false;
12211 
12212         uint64_t replicated_element = 0;
12213         uint32_t esize = ebytes * 8;
12214         for (uint32_t e = 0; e < elements; ++e)
12215             replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0);
12216 
12217         // for r = 0 to regs-1
12218         for (uint32_t r = 0; r < regs; ++r)
12219         {
12220             // D[d+r] = replicated_element;
12221             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element))
12222                 return false;
12223         }
12224     }
12225     return true;
12226 }
12227 
12228 // B6.2.13 SUBS PC, LR and related instructions
12229 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack.  It subtracts the
12230 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR.
12231 bool
12232 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding)
12233 {
12234 #if 0
12235     if ConditionPassed() then
12236         EncodingSpecificOperations();
12237         if CurrentInstrSet() == InstrSet_ThumbEE then
12238             UNPREDICTABLE;
12239         operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12240         case opcode of
12241             when '0000' result = R[n] AND operand2; // AND
12242             when '0001' result = R[n] EOR operand2; // EOR
12243             when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12244             when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12245             when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12246             when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12247             when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12248             when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12249             when '1100' result = R[n] OR operand2; // ORR
12250             when '1101' result = operand2; // MOV
12251             when '1110' result = R[n] AND NOT(operand2); // BIC
12252             when '1111' result = NOT(operand2); // MVN
12253         CPSRWriteByInstr(SPSR[], '1111', TRUE);
12254         BranchWritePC(result);
12255 #endif
12256 
12257     bool success = false;
12258 
12259     if (ConditionPassed (opcode))
12260     {
12261         uint32_t n;
12262         uint32_t m;
12263         uint32_t imm32;
12264         bool register_form;
12265         ARM_ShifterType shift_t;
12266         uint32_t shift_n;
12267         uint32_t code;
12268 
12269         switch (encoding)
12270         {
12271             case eEncodingT1:
12272                 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
12273                 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010'; // = SUB
12274                 n = 14;
12275                 imm32 = Bits32 (opcode, 7, 0);
12276                 register_form = false;
12277                 code = 2;
12278 
12279                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12280                 if (InITBlock() && !LastInITBlock())
12281                     return false;
12282 
12283                 break;
12284 
12285             case eEncodingA1:
12286                 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12287                 n = Bits32 (opcode, 19, 16);
12288                 imm32 = ARMExpandImm (opcode);
12289                 register_form = false;
12290                 code = Bits32 (opcode, 24, 21);
12291 
12292                 break;
12293 
12294             case eEncodingA2:
12295                 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12296                 n = Bits32 (opcode, 19, 16);
12297                 m = Bits32 (opcode, 3, 0);
12298                 register_form = true;
12299 
12300                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12301                 shift_n = DecodeImmShiftARM (opcode, shift_t);
12302 
12303                 break;
12304 
12305             default:
12306                 return false;
12307         }
12308 
12309         // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12310         uint32_t operand2;
12311         if (register_form)
12312         {
12313             uint32_t Rm = ReadCoreReg (m, &success);
12314             if (!success)
12315                 return false;
12316 
12317             operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success);
12318             if (!success)
12319                 return false;
12320         }
12321         else
12322         {
12323             operand2 = imm32;
12324         }
12325 
12326         uint32_t Rn = ReadCoreReg (n, &success);
12327         if (!success)
12328             return false;
12329 
12330         AddWithCarryResult result;
12331 
12332         // case opcode of
12333         switch (code)
12334         {
12335             case 0: // when '0000'
12336                 // result = R[n] AND operand2; // AND
12337                 result.result = Rn & operand2;
12338                 break;
12339 
12340             case 1: // when '0001'
12341                 // result = R[n] EOR operand2; // EOR
12342                 result.result = Rn ^ operand2;
12343                 break;
12344 
12345             case 2: // when '0010'
12346                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12347                 result = AddWithCarry (Rn, ~(operand2), 1);
12348                 break;
12349 
12350             case 3: // when '0011'
12351                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12352                 result = AddWithCarry (~(Rn), operand2, 1);
12353                 break;
12354 
12355             case 4: // when '0100'
12356                 // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12357                 result = AddWithCarry (Rn, operand2, 0);
12358                 break;
12359 
12360             case 5: // when '0101'
12361                 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12362                 result = AddWithCarry (Rn, operand2, APSR_C);
12363                 break;
12364 
12365             case 6: // when '0110'
12366                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12367                 result = AddWithCarry (Rn, ~(operand2), APSR_C);
12368                 break;
12369 
12370             case 7: // when '0111'
12371                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12372                 result = AddWithCarry (~(Rn), operand2, APSR_C);
12373                 break;
12374 
12375             case 10: // when '1100'
12376                 // result = R[n] OR operand2; // ORR
12377                 result.result = Rn | operand2;
12378                 break;
12379 
12380             case 11: // when '1101'
12381                 // result = operand2; // MOV
12382                 result.result = operand2;
12383                 break;
12384 
12385             case 12: // when '1110'
12386                 // result = R[n] AND NOT(operand2); // BIC
12387                 result.result = Rn & ~(operand2);
12388                 break;
12389 
12390             case 15: // when '1111'
12391                 // result = NOT(operand2); // MVN
12392                 result.result = ~(operand2);
12393                 break;
12394 
12395             default:
12396                 return false;
12397         }
12398         // CPSRWriteByInstr(SPSR[], '1111', TRUE);
12399 
12400         // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for
12401         // the best.
12402         uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12403         if (!success)
12404             return false;
12405 
12406         CPSRWriteByInstr (spsr, 15, true);
12407 
12408         // BranchWritePC(result);
12409         EmulateInstruction::Context context;
12410         context.type = eContextAdjustPC;
12411         context.SetImmediate (result.result);
12412 
12413         BranchWritePC (context, result.result);
12414     }
12415     return true;
12416 }
12417 
12418 EmulateInstructionARM::ARMOpcode*
12419 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12420 {
12421     static ARMOpcode
12422     g_arm_opcodes[] =
12423     {
12424         //----------------------------------------------------------------------
12425         // Prologue instructions
12426         //----------------------------------------------------------------------
12427 
12428         // push register(s)
12429         { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12430         { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
12431 
12432         // set r7 to point to a stack offset
12433         { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
12434         { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12435         // copy the stack pointer to ip
12436         { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
12437         { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
12438         { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12439 
12440         // adjust the stack pointer
12441         { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12442         { 0x0fef0010, 0x004d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12443 
12444         // push one register
12445         // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12446         { 0x0e5f0000, 0x040d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
12447 
12448         // vector push consecutive extension register(s)
12449         { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12450         { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12451 
12452         //----------------------------------------------------------------------
12453         // Epilogue instructions
12454         //----------------------------------------------------------------------
12455 
12456         { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12457         { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12458         { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12459         { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12460 
12461         //----------------------------------------------------------------------
12462         // Supervisor Call (previously Software Interrupt)
12463         //----------------------------------------------------------------------
12464         { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12465 
12466         //----------------------------------------------------------------------
12467         // Branch instructions
12468         //----------------------------------------------------------------------
12469         // To resolve ambiguity, "blx <label>" should come before "b #imm24" and "bl <label>".
12470         { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12471         { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
12472         { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12473         { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12474         // for example, "bx lr"
12475         { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12476         // bxj
12477         { 0x0ffffff0, 0x012fff20, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12478 
12479         //----------------------------------------------------------------------
12480         // Data-processing instructions
12481         //----------------------------------------------------------------------
12482         // adc (immediate)
12483         { 0x0fe00000, 0x02a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12484         // adc (register)
12485         { 0x0fe00010, 0x00a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12486         // add (immediate)
12487         { 0x0fe00000, 0x02800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
12488         // add (register)
12489         { 0x0fe00010, 0x00800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12490         // add (register-shifted register)
12491         { 0x0fe00090, 0x00800010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12492         // adr
12493         { 0x0fff0000, 0x028f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12494         { 0x0fff0000, 0x024f0000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12495         // and (immediate)
12496         { 0x0fe00000, 0x02000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12497         // and (register)
12498         { 0x0fe00010, 0x00000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12499         // bic (immediate)
12500         { 0x0fe00000, 0x03c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12501         // bic (register)
12502         { 0x0fe00010, 0x01c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12503         // eor (immediate)
12504         { 0x0fe00000, 0x02200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12505         // eor (register)
12506         { 0x0fe00010, 0x00200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12507         // orr (immediate)
12508         { 0x0fe00000, 0x03800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12509         // orr (register)
12510         { 0x0fe00010, 0x01800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12511         // rsb (immediate)
12512         { 0x0fe00000, 0x02600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12513         // rsb (register)
12514         { 0x0fe00010, 0x00600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12515         // rsc (immediate)
12516         { 0x0fe00000, 0x02e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12517         // rsc (register)
12518         { 0x0fe00010, 0x00e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12519         // sbc (immediate)
12520         { 0x0fe00000, 0x02c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12521         // sbc (register)
12522         { 0x0fe00010, 0x00c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12523         // sub (immediate, ARM)
12524         { 0x0fe00000, 0x02400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
12525         // sub (sp minus immediate)
12526         { 0x0fef0000, 0x024d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12527         // sub (register)
12528         { 0x0fe00010, 0x00400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12529         // teq (immediate)
12530         { 0x0ff0f000, 0x03300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12531         // teq (register)
12532         { 0x0ff0f010, 0x01300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12533         // tst (immediate)
12534         { 0x0ff0f000, 0x03100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12535         // tst (register)
12536         { 0x0ff0f010, 0x01100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12537 
12538         // mov (immediate)
12539         { 0x0fef0000, 0x03a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12540         { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
12541         // mov (register)
12542         { 0x0fef0ff0, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12543         // mvn (immediate)
12544         { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12545         // mvn (register)
12546         { 0x0fef0010, 0x01e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12547         // cmn (immediate)
12548         { 0x0ff0f000, 0x03700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12549         // cmn (register)
12550         { 0x0ff0f010, 0x01700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12551         // cmp (immediate)
12552         { 0x0ff0f000, 0x03500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
12553         // cmp (register)
12554         { 0x0ff0f010, 0x01500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
12555         // asr (immediate)
12556         { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
12557         // asr (register)
12558         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
12559         // lsl (immediate)
12560         { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
12561         // lsl (register)
12562         { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
12563         // lsr (immediate)
12564         { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
12565         // lsr (register)
12566         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
12567         // rrx is a special case encoding of ror (immediate)
12568         { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
12569         // ror (immediate)
12570         { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
12571         // ror (register)
12572         { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
12573         // mul
12574         { 0x0fe000f0, 0x00000090, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
12575 
12576         // subs pc, lr and related instructions
12577         { 0x0e10f000, 0x0210f000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" },
12578         { 0x0e10f010, 0x0010f000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" },
12579 
12580         //----------------------------------------------------------------------
12581         // Load instructions
12582         //----------------------------------------------------------------------
12583         { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12584         { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
12585         { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12586         { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
12587         { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
12588         { 0x0e500010, 0x06100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
12589         { 0x0e5f0000, 0x045f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
12590         { 0xfe500010, 0x06500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
12591         { 0x0e5f00f0, 0x005f00b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12592         { 0x0e5000f0, 0x001000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"  },
12593         { 0x0e5000f0, 0x005000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
12594         { 0x0e5f00f0, 0x005f00d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
12595         { 0x0e5000f0, 0x001000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12596         { 0x0e5000f0, 0x005000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
12597         { 0x0e5f00f0, 0x005f00f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12598         { 0x0e5000f0, 0x001000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12599         { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
12600         { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12601         { 0x0e100f00, 0x0c100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12602         { 0x0e100f00, 0x0c100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12603         { 0x0f300f00, 0x0d100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12604         { 0x0f300f00, 0x0d100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12605         { 0xffb00000, 0xf4200000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12606         { 0xffb00300, 0xf4a00000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12607         { 0xffb00f00, 0xf4a00c00, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12608 
12609         //----------------------------------------------------------------------
12610         // Store instructions
12611         //----------------------------------------------------------------------
12612         { 0x0fd00000, 0x08800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12613         { 0x0fd00000, 0x08000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
12614         { 0x0fd00000, 0x09000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12615         { 0x0fd00000, 0x09800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
12616         { 0x0e500010, 0x06000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
12617         { 0x0e5000f0, 0x000000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
12618         { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
12619         { 0x0e500000, 0x04400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12620         { 0x0e500000, 0x04000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12621         { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
12622         { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12623         { 0x0e100f00, 0x0c000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12624         { 0x0e100f00, 0x0c000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12625         { 0x0f300f00, 0x0d000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
12626         { 0x0f300f00, 0x0d000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
12627         { 0xffb00000, 0xf4000000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12628         { 0xffb00300, 0xf4800000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12629 
12630         //----------------------------------------------------------------------
12631         // Other instructions
12632         //----------------------------------------------------------------------
12633         { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
12634         { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
12635         { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
12636         { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
12637         { 0xfe500000, 0xf8100000, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
12638 
12639     };
12640     static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes);
12641 
12642     for (size_t i=0; i<k_num_arm_opcodes; ++i)
12643     {
12644         if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
12645             (g_arm_opcodes[i].variants & arm_isa) != 0)
12646             return &g_arm_opcodes[i];
12647     }
12648     return NULL;
12649 }
12650 
12651 
12652 EmulateInstructionARM::ARMOpcode*
12653 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12654 {
12655 
12656     static ARMOpcode
12657     g_thumb_opcodes[] =
12658     {
12659         //----------------------------------------------------------------------
12660         // Prologue instructions
12661         //----------------------------------------------------------------------
12662 
12663         // push register(s)
12664         { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12665         { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
12666         { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
12667 
12668         // set r7 to point to a stack offset
12669         { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
12670         // copy the stack pointer to r7
12671         { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
12672         // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
12673         { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
12674 
12675         // PC-relative load into register (see also EmulateADDSPRm)
12676         { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
12677 
12678         // adjust the stack pointer
12679         { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
12680         { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
12681         { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
12682         { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
12683         { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12684 
12685         // vector push consecutive extension register(s)
12686         { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12687         { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12688 
12689         //----------------------------------------------------------------------
12690         // Epilogue instructions
12691         //----------------------------------------------------------------------
12692 
12693         { 0xfffff800, 0x0000a800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
12694         { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
12695         { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12696         { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
12697         { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
12698         { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12699         { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12700 
12701         //----------------------------------------------------------------------
12702         // Supervisor Call (previously Software Interrupt)
12703         //----------------------------------------------------------------------
12704         { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
12705 
12706         //----------------------------------------------------------------------
12707         // If Then makes up to four following instructions conditional.
12708         //----------------------------------------------------------------------
12709         // The next 5 opcode _must_ come before the if then instruction
12710         { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"},
12711         { 0xffffffff, 0x0000bf10, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
12712         { 0xffffffff, 0x0000bf20, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
12713         { 0xffffffff, 0x0000bf30, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
12714         { 0xffffffff, 0x0000bf40, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
12715         { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
12716 
12717         //----------------------------------------------------------------------
12718         // Branch instructions
12719         //----------------------------------------------------------------------
12720         // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
12721         { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
12722         { 0xfffff800, 0x0000e000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
12723         { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
12724         { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
12725         // J1 == J2 == 1
12726         { 0xf800d000, 0xf000d000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12727         // J1 == J2 == 1
12728         { 0xf800d001, 0xf000c000, ARMV5_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12729         { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12730         // for example, "bx lr"
12731         { 0xffffff87, 0x00004700, ARMvAll,       eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12732         // bxj
12733         { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12734         // compare and branch
12735         { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
12736         // table branch byte
12737         { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
12738         // table branch halfword
12739         { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
12740 
12741         //----------------------------------------------------------------------
12742         // Data-processing instructions
12743         //----------------------------------------------------------------------
12744         // adc (immediate)
12745         { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
12746         // adc (register)
12747         { 0xffffffc0, 0x00004140, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
12748         { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12749         // add (register)
12750         { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
12751         // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
12752         { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
12753         // adr
12754         { 0xfffff800, 0x0000a000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12755         { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12756         { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12757         // and (immediate)
12758         { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
12759         // and (register)
12760         { 0xffffffc0, 0x00004000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
12761         { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12762         // bic (immediate)
12763         { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
12764         // bic (register)
12765         { 0xffffffc0, 0x00004380, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
12766         { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12767         // eor (immediate)
12768         { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
12769         // eor (register)
12770         { 0xffffffc0, 0x00004040, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
12771         { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12772         // orr (immediate)
12773         { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
12774         // orr (register)
12775         { 0xffffffc0, 0x00004300, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
12776         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12777         // rsb (immediate)
12778         { 0xffffffc0, 0x00004240, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
12779         { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
12780         // rsb (register)
12781         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12782         // sbc (immediate)
12783         { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12784         // sbc (register)
12785         { 0xffffffc0, 0x00004180, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
12786         { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12787         // add (immediate, Thumb)
12788         { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
12789         { 0xfffff800, 0x00003000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
12790         { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
12791         { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
12792         // sub (immediate, Thumb)
12793         { 0xfffffe00, 0x00001e00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
12794         { 0xfffff800, 0x00003800, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
12795         { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
12796         { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
12797         // sub (sp minus immediate)
12798         { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
12799         { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
12800         // sub (register)
12801         { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
12802         { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
12803         // teq (immediate)
12804         { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
12805         // teq (register)
12806         { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12807         // tst (immediate)
12808         { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
12809         // tst (register)
12810         { 0xffffffc0, 0x00004200, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
12811         { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
12812 
12813 
12814         // move from high register to high register
12815         { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
12816         // move from low register to low register
12817         { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
12818         // mov{s}<c>.w <Rd>, <Rm>
12819         { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
12820         // move immediate
12821         { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
12822         { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
12823         { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
12824         // mvn (immediate)
12825         { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
12826         // mvn (register)
12827         { 0xffffffc0, 0x000043c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
12828         { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
12829         // cmn (immediate)
12830         { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12831         // cmn (register)
12832         { 0xffffffc0, 0x000042c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
12833         { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12834         // cmp (immediate)
12835         { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
12836         { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
12837         // cmp (register) (Rn and Rm both from r0-r7)
12838         { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12839         // cmp (register) (Rn and Rm not both from r0-r7)
12840         { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12841         { 0xfff08f00, 0xebb00f00, ARMvAll,       eEncodingT3, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c>.w <Rn>, <Rm> {, <shift>}"},
12842         // asr (immediate)
12843         { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
12844         { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
12845         // asr (register)
12846         { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
12847         { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12848         // lsl (immediate)
12849         { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
12850         { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
12851         // lsl (register)
12852         { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
12853         { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
12854         // lsr (immediate)
12855         { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
12856         { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
12857         // lsr (register)
12858         { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
12859         { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12860         // rrx is a special case encoding of ror (immediate)
12861         { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
12862         // ror (immediate)
12863         { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
12864         // ror (register)
12865         { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
12866         { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
12867         // mul
12868         { 0xffffffc0, 0x00004340, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
12869         // mul
12870         { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
12871 
12872         // subs pc, lr and related instructions
12873         { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" },
12874 
12875         //----------------------------------------------------------------------
12876         // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table;
12877         // otherwise the wrong instructions will be selected.
12878         //----------------------------------------------------------------------
12879 
12880         { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
12881         { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
12882 
12883         //----------------------------------------------------------------------
12884         // Load instructions
12885         //----------------------------------------------------------------------
12886         { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12887         { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
12888         { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12889         { 0xfffff800, 0x00006800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
12890         { 0xfffff800, 0x00009800, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
12891         { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
12892         { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
12893                   // Thumb2 PC-relative load into register
12894         { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
12895         { 0xfffffe00, 0x00005800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
12896         { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
12897         { 0xfffff800, 0x00007800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
12898         { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12899         { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" },
12900         { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
12901         { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
12902         { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
12903         { 0xfffff800, 0x00008800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"  },
12904         { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12905         { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"  },
12906         { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12907         { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
12908         { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12909         { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
12910         { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12911         { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
12912         { 0xfffffe00, 0x00005600, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
12913         { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"  },
12914         { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
12915         { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12916         { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12917         { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
12918         { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12919         { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
12920         { 0xfe100f00, 0xec100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12921         { 0xfe100f00, 0xec100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
12922         { 0xffe00f00, 0xed100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12923         { 0xff300f00, 0xed100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
12924         { 0xffb00000, 0xf9200000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12925         { 0xffb00300, 0xf9a00000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12926         { 0xffb00f00, 0xf9a00c00, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12927 
12928         //----------------------------------------------------------------------
12929         // Store instructions
12930         //----------------------------------------------------------------------
12931         { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12932         { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
12933         { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12934         { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
12935         { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
12936         { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
12937         { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
12938         { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
12939         { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
12940         { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
12941         { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
12942         { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
12943         { 0xfffffe00, 0x00005200, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
12944         { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12945         { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
12946         { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
12947         { 0xfe100f00, 0xec000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12948         { 0xfea00f00, 0xec000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12949         { 0xff300f00, 0xed000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12950         { 0xff300f00, 0xed000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12951         { 0xffb00000, 0xf9000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12952         { 0xffb00300, 0xf9800000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12953 
12954         //----------------------------------------------------------------------
12955         // Other instructions
12956         //----------------------------------------------------------------------
12957         { 0xffffffc0, 0x0000b240, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
12958         { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12959         { 0xffffffc0, 0x0000b200, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
12960         { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12961         { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
12962         { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12963         { 0xffffffc0, 0x0000b280, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
12964         { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12965     };
12966 
12967     const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes);
12968     for (size_t i=0; i<k_num_thumb_opcodes; ++i)
12969     {
12970         if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
12971             (g_thumb_opcodes[i].variants & arm_isa) != 0)
12972             return &g_thumb_opcodes[i];
12973     }
12974     return NULL;
12975 }
12976 
12977 bool
12978 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
12979 {
12980     m_arch = arch;
12981     m_arm_isa = 0;
12982     const char *arch_cstr = arch.GetArchitectureName ();
12983     if (arch_cstr)
12984     {
12985         if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
12986         else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
12987         else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
12988         else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
12989         else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
12990         else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
12991         else if (0 == ::strcasecmp(arch_cstr, "armv7s"))    m_arm_isa = ARMv7S;
12992         else if (0 == ::strcasecmp(arch_cstr, "arm"))       m_arm_isa = ARMvAll;
12993         else if (0 == ::strcasecmp(arch_cstr, "thumb"))     m_arm_isa = ARMvAll;
12994         else if (0 == ::strncasecmp(arch_cstr,"armv4", 5))  m_arm_isa = ARMv4;
12995         else if (0 == ::strncasecmp(arch_cstr,"armv6", 5))  m_arm_isa = ARMv6;
12996         else if (0 == ::strncasecmp(arch_cstr,"armv7", 5))  m_arm_isa = ARMv7;
12997         else if (0 == ::strncasecmp(arch_cstr,"armv8", 5))  m_arm_isa = ARMv8;
12998     }
12999     return m_arm_isa != 0;
13000 }
13001 
13002 bool
13003 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
13004 {
13005     if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
13006     {
13007         if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
13008             m_opcode_mode = eModeThumb;
13009         else
13010         {
13011             AddressClass addr_class = inst_addr.GetAddressClass();
13012 
13013             if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
13014                 m_opcode_mode = eModeARM;
13015             else if (addr_class == eAddressClassCodeAlternateISA)
13016                 m_opcode_mode = eModeThumb;
13017             else
13018                 return false;
13019         }
13020         if (m_opcode_mode == eModeThumb)
13021             m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
13022         else
13023             m_opcode_cpsr = CPSR_MODE_USR;
13024         return true;
13025     }
13026     return false;
13027 }
13028 
13029 bool
13030 EmulateInstructionARM::ReadInstruction ()
13031 {
13032     bool success = false;
13033     m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
13034     if (success)
13035     {
13036         addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
13037         if (success)
13038         {
13039             Context read_inst_context;
13040             read_inst_context.type = eContextReadOpcode;
13041             read_inst_context.SetNoArgs ();
13042 
13043             if (m_opcode_cpsr & MASK_CPSR_T)
13044             {
13045                 m_opcode_mode = eModeThumb;
13046                 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
13047 
13048                 if (success)
13049                 {
13050                     if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
13051                     {
13052                         m_opcode.SetOpcode16 (thumb_opcode, GetByteOrder());
13053                     }
13054                     else
13055                     {
13056                         m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success), GetByteOrder());
13057                     }
13058                 }
13059             }
13060             else
13061             {
13062                 m_opcode_mode = eModeARM;
13063                 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success), GetByteOrder());
13064             }
13065         }
13066     }
13067     if (!success)
13068     {
13069         m_opcode_mode = eModeInvalid;
13070         m_addr = LLDB_INVALID_ADDRESS;
13071     }
13072     return success;
13073 }
13074 
13075 uint32_t
13076 EmulateInstructionARM::ArchVersion ()
13077 {
13078     return m_arm_isa;
13079 }
13080 
13081 bool
13082 EmulateInstructionARM::ConditionPassed (const uint32_t opcode)
13083 {
13084    // If we are ignoring conditions, then always return true.
13085    // this allows us to iterate over disassembly code and still
13086    // emulate an instruction even if we don't have all the right
13087    // bits set in the CPSR register...
13088     if (m_ignore_conditions)
13089         return true;
13090 
13091     const uint32_t cond = CurrentCond (opcode);
13092     if (cond == UINT32_MAX)
13093         return false;
13094 
13095     bool result = false;
13096     switch (UnsignedBits(cond, 3, 1))
13097     {
13098     case 0:
13099 		if (m_opcode_cpsr == 0)
13100 			result = true;
13101         else
13102             result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
13103 		break;
13104     case 1:
13105         if (m_opcode_cpsr == 0)
13106             result = true;
13107         else
13108             result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
13109 		break;
13110     case 2:
13111         if (m_opcode_cpsr == 0)
13112             result = true;
13113         else
13114             result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
13115 		break;
13116     case 3:
13117         if (m_opcode_cpsr == 0)
13118             result = true;
13119         else
13120             result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
13121 		break;
13122     case 4:
13123         if (m_opcode_cpsr == 0)
13124             result = true;
13125         else
13126             result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13127 		break;
13128     case 5:
13129         if (m_opcode_cpsr == 0)
13130             result = true;
13131         else
13132 		{
13133             bool n = (m_opcode_cpsr & MASK_CPSR_N);
13134             bool v = (m_opcode_cpsr & MASK_CPSR_V);
13135             result = n == v;
13136         }
13137         break;
13138     case 6:
13139         if (m_opcode_cpsr == 0)
13140             result = true;
13141         else
13142 		{
13143             bool n = (m_opcode_cpsr & MASK_CPSR_N);
13144             bool v = (m_opcode_cpsr & MASK_CPSR_V);
13145             result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13146         }
13147         break;
13148     case 7:
13149         // Always execute (cond == 0b1110, or the special 0b1111 which gives
13150         // opcodes different meanings, but always means execution happens.
13151         return true;
13152     }
13153 
13154     if (cond & 1)
13155         result = !result;
13156     return result;
13157 }
13158 
13159 uint32_t
13160 EmulateInstructionARM::CurrentCond (const uint32_t opcode)
13161 {
13162     switch (m_opcode_mode)
13163     {
13164     case eModeInvalid:
13165         break;
13166 
13167     case eModeARM:
13168         return UnsignedBits(opcode, 31, 28);
13169 
13170     case eModeThumb:
13171         // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
13172         // 'cond' field of the encoding.
13173         {
13174             const uint32_t byte_size = m_opcode.GetByteSize();
13175             if (byte_size == 2)
13176             {
13177                 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f)
13178                     return Bits32(opcode, 11, 8);
13179             }
13180             else if (byte_size == 4)
13181             {
13182                 if (Bits32(opcode, 31, 27) == 0x1e &&
13183                     Bits32(opcode, 15, 14) == 0x02 &&
13184                     Bits32(opcode, 12, 12) == 0x00 &&
13185                     Bits32(opcode, 25, 22) <= 0x0d)
13186                 {
13187                     return Bits32(opcode, 25, 22);
13188                 }
13189             }
13190             else
13191                 // We have an invalid thumb instruction, let's bail out.
13192                 break;
13193 
13194             return m_it_session.GetCond();
13195         }
13196     }
13197     return UINT32_MAX;  // Return invalid value
13198 }
13199 
13200 bool
13201 EmulateInstructionARM::InITBlock()
13202 {
13203     return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13204 }
13205 
13206 bool
13207 EmulateInstructionARM::LastInITBlock()
13208 {
13209     return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13210 }
13211 
13212 bool
13213 EmulateInstructionARM::BadMode (uint32_t mode)
13214 {
13215 
13216     switch (mode)
13217     {
13218         case 16: return false; // '10000'
13219         case 17: return false; // '10001'
13220         case 18: return false; // '10010'
13221         case 19: return false; // '10011'
13222         case 22: return false; // '10110'
13223         case 23: return false; // '10111'
13224         case 27: return false; // '11011'
13225         case 31: return false; // '11111'
13226         default: return true;
13227     }
13228     return true;
13229 }
13230 
13231 bool
13232 EmulateInstructionARM::CurrentModeIsPrivileged ()
13233 {
13234     uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
13235 
13236     if (BadMode (mode))
13237         return false;
13238 
13239     if (mode == 16)
13240         return false;
13241 
13242     return true;
13243 }
13244 
13245 void
13246 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
13247 {
13248     bool privileged = CurrentModeIsPrivileged();
13249 
13250     uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20;
13251 
13252     if (BitIsSet (bytemask, 3))
13253     {
13254         tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
13255         if (affect_execstate)
13256             tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
13257     }
13258 
13259     if (BitIsSet (bytemask, 2))
13260     {
13261         tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
13262     }
13263 
13264     if (BitIsSet (bytemask, 1))
13265     {
13266         if (affect_execstate)
13267             tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
13268         tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
13269         if (privileged)
13270             tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
13271     }
13272 
13273     if (BitIsSet (bytemask, 0))
13274     {
13275         if (privileged)
13276             tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
13277         if (affect_execstate)
13278             tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
13279         if (privileged)
13280             tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
13281     }
13282 
13283     m_opcode_cpsr = tmp_cpsr;
13284 }
13285 
13286 
13287 bool
13288 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
13289 {
13290     addr_t target;
13291 
13292     // Check the current instruction set.
13293     if (CurrentInstrSet() == eModeARM)
13294         target = addr & 0xfffffffc;
13295     else
13296         target = addr & 0xfffffffe;
13297 
13298     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13299         return false;
13300 
13301     return true;
13302 }
13303 
13304 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
13305 bool
13306 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
13307 {
13308     addr_t target;
13309     // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
13310     // we want to record it and issue a WriteRegister callback so the clients
13311     // can track the mode changes accordingly.
13312     bool cpsr_changed = false;
13313 
13314     if (BitIsSet(addr, 0))
13315     {
13316         if (CurrentInstrSet() != eModeThumb)
13317         {
13318             SelectInstrSet(eModeThumb);
13319             cpsr_changed = true;
13320         }
13321         target = addr & 0xfffffffe;
13322         context.SetISA (eModeThumb);
13323     }
13324     else if (BitIsClear(addr, 1))
13325     {
13326         if (CurrentInstrSet() != eModeARM)
13327         {
13328             SelectInstrSet(eModeARM);
13329             cpsr_changed = true;
13330         }
13331         target = addr & 0xfffffffc;
13332         context.SetISA (eModeARM);
13333     }
13334     else
13335         return false; // address<1:0> == '10' => UNPREDICTABLE
13336 
13337     if (cpsr_changed)
13338     {
13339         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13340             return false;
13341     }
13342     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13343         return false;
13344 
13345     return true;
13346 }
13347 
13348 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
13349 bool
13350 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
13351 {
13352     if (ArchVersion() >= ARMv5T)
13353         return BXWritePC(context, addr);
13354     else
13355         return BranchWritePC((const Context)context, addr);
13356 }
13357 
13358 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
13359 bool
13360 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
13361 {
13362     if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
13363         return BXWritePC(context, addr);
13364     else
13365         return BranchWritePC((const Context)context, addr);
13366 }
13367 
13368 EmulateInstructionARM::Mode
13369 EmulateInstructionARM::CurrentInstrSet ()
13370 {
13371     return m_opcode_mode;
13372 }
13373 
13374 // Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
13375 // ReadInstruction() is performed.  This function has a side effect of updating
13376 // the m_new_inst_cpsr member variable if necessary.
13377 bool
13378 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
13379 {
13380     m_new_inst_cpsr = m_opcode_cpsr;
13381     switch (arm_or_thumb)
13382     {
13383     default:
13384         return false;
13385     case eModeARM:
13386         // Clear the T bit.
13387         m_new_inst_cpsr &= ~MASK_CPSR_T;
13388         break;
13389     case eModeThumb:
13390         // Set the T bit.
13391         m_new_inst_cpsr |= MASK_CPSR_T;
13392         break;
13393     }
13394     return true;
13395 }
13396 
13397 // This function returns TRUE if the processor currently provides support for
13398 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
13399 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
13400 bool
13401 EmulateInstructionARM::UnalignedSupport()
13402 {
13403     return (ArchVersion() >= ARMv7);
13404 }
13405 
13406 // The main addition and subtraction instructions can produce status information
13407 // about both unsigned carry and signed overflow conditions.  This status
13408 // information can be used to synthesize multi-word additions and subtractions.
13409 EmulateInstructionARM::AddWithCarryResult
13410 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
13411 {
13412     uint32_t result;
13413     uint8_t carry_out;
13414     uint8_t overflow;
13415 
13416     uint64_t unsigned_sum = x + y + carry_in;
13417     int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
13418 
13419     result = UnsignedBits(unsigned_sum, 31, 0);
13420 //    carry_out = (result == unsigned_sum ? 0 : 1);
13421     overflow = ((int32_t)result == signed_sum ? 0 : 1);
13422 
13423     if (carry_in)
13424         carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0;
13425     else
13426         carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0;
13427 
13428     AddWithCarryResult res = { result, carry_out, overflow };
13429     return res;
13430 }
13431 
13432 uint32_t
13433 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
13434 {
13435     lldb::RegisterKind reg_kind;
13436     uint32_t reg_num;
13437     switch (num)
13438     {
13439     case SP_REG:
13440         reg_kind = eRegisterKindGeneric;
13441         reg_num  = LLDB_REGNUM_GENERIC_SP;
13442         break;
13443     case LR_REG:
13444         reg_kind = eRegisterKindGeneric;
13445         reg_num  = LLDB_REGNUM_GENERIC_RA;
13446         break;
13447     case PC_REG:
13448         reg_kind = eRegisterKindGeneric;
13449         reg_num  = LLDB_REGNUM_GENERIC_PC;
13450         break;
13451     default:
13452         if (num < SP_REG)
13453         {
13454             reg_kind = eRegisterKindDWARF;
13455             reg_num  = dwarf_r0 + num;
13456         }
13457         else
13458         {
13459             //assert(0 && "Invalid register number");
13460             *success = false;
13461             return UINT32_MAX;
13462         }
13463         break;
13464     }
13465 
13466     // Read our register.
13467     uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
13468 
13469     // When executing an ARM instruction , PC reads as the address of the current
13470     // instruction plus 8.
13471     // When executing a Thumb instruction , PC reads as the address of the current
13472     // instruction plus 4.
13473     if (num == 15)
13474     {
13475         if (CurrentInstrSet() == eModeARM)
13476             val += 8;
13477         else
13478             val += 4;
13479     }
13480 
13481     return val;
13482 }
13483 
13484 // Write the result to the ARM core register Rd, and optionally update the
13485 // condition flags based on the result.
13486 //
13487 // This helper method tries to encapsulate the following pseudocode from the
13488 // ARM Architecture Reference Manual:
13489 //
13490 // if d == 15 then         // Can only occur for encoding A1
13491 //     ALUWritePC(result); // setflags is always FALSE here
13492 // else
13493 //     R[d] = result;
13494 //     if setflags then
13495 //         APSR.N = result<31>;
13496 //         APSR.Z = IsZeroBit(result);
13497 //         APSR.C = carry;
13498 //         // APSR.V unchanged
13499 //
13500 // In the above case, the API client does not pass in the overflow arg, which
13501 // defaults to ~0u.
13502 bool
13503 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
13504                                                   const uint32_t result,
13505                                                   const uint32_t Rd,
13506                                                   bool setflags,
13507                                                   const uint32_t carry,
13508                                                   const uint32_t overflow)
13509 {
13510     if (Rd == 15)
13511     {
13512         if (!ALUWritePC (context, result))
13513             return false;
13514     }
13515     else
13516     {
13517         lldb::RegisterKind reg_kind;
13518         uint32_t reg_num;
13519         switch (Rd)
13520         {
13521         case SP_REG:
13522             reg_kind = eRegisterKindGeneric;
13523             reg_num  = LLDB_REGNUM_GENERIC_SP;
13524             break;
13525         case LR_REG:
13526             reg_kind = eRegisterKindGeneric;
13527             reg_num  = LLDB_REGNUM_GENERIC_RA;
13528             break;
13529         default:
13530             reg_kind = eRegisterKindDWARF;
13531             reg_num  = dwarf_r0 + Rd;
13532         }
13533         if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
13534             return false;
13535         if (setflags)
13536             return WriteFlags (context, result, carry, overflow);
13537     }
13538     return true;
13539 }
13540 
13541 // This helper method tries to encapsulate the following pseudocode from the
13542 // ARM Architecture Reference Manual:
13543 //
13544 // APSR.N = result<31>;
13545 // APSR.Z = IsZeroBit(result);
13546 // APSR.C = carry;
13547 // APSR.V = overflow
13548 //
13549 // Default arguments can be specified for carry and overflow parameters, which means
13550 // not to update the respective flags.
13551 bool
13552 EmulateInstructionARM::WriteFlags (Context &context,
13553                                    const uint32_t result,
13554                                    const uint32_t carry,
13555                                    const uint32_t overflow)
13556 {
13557     m_new_inst_cpsr = m_opcode_cpsr;
13558     SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
13559     SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
13560     if (carry != ~0u)
13561         SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
13562     if (overflow != ~0u)
13563         SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
13564     if (m_new_inst_cpsr != m_opcode_cpsr)
13565     {
13566         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13567             return false;
13568     }
13569     return true;
13570 }
13571 
13572 bool
13573 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
13574 {
13575     // Advance the ITSTATE bits to their values for the next instruction.
13576     if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
13577         m_it_session.ITAdvance();
13578 
13579     ARMOpcode *opcode_data = NULL;
13580 
13581     if (m_opcode_mode == eModeThumb)
13582         opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13583     else if (m_opcode_mode == eModeARM)
13584         opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13585 
13586     if (opcode_data == NULL)
13587         return false;
13588 
13589     const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
13590     m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
13591 
13592     bool success = false;
13593     if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
13594     {
13595         m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF,
13596                                                 dwarf_cpsr,
13597                                                 0,
13598                                                 &success);
13599     }
13600 
13601     // Only return false if we are unable to read the CPSR if we care about conditions
13602     if (success == false && m_ignore_conditions == false)
13603         return false;
13604 
13605     uint32_t orig_pc_value = 0;
13606     if (auto_advance_pc)
13607     {
13608         orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13609         if (!success)
13610             return false;
13611     }
13612 
13613     // Call the Emulate... function.
13614     success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
13615     if (!success)
13616         return false;
13617 
13618     if (auto_advance_pc)
13619     {
13620         uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13621         if (!success)
13622             return false;
13623 
13624         if (auto_advance_pc && (after_pc_value == orig_pc_value))
13625         {
13626             if (opcode_data->size == eSize32)
13627                 after_pc_value += 4;
13628             else if (opcode_data->size == eSize16)
13629                 after_pc_value += 2;
13630 
13631             EmulateInstruction::Context context;
13632             context.type = eContextAdvancePC;
13633             context.SetNoArgs();
13634             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
13635                 return false;
13636 
13637         }
13638     }
13639     return true;
13640 }
13641 
13642 bool
13643 EmulateInstructionARM::IsInstructionConditional()
13644 {
13645     const uint32_t cond = CurrentCond (m_opcode.GetOpcode32());
13646     return cond != 0xe && cond != 0xf && cond != UINT32_MAX;
13647 }
13648 
13649 bool
13650 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data)
13651 {
13652     if (!test_data)
13653     {
13654         out_stream->Printf ("TestEmulation: Missing test data.\n");
13655         return false;
13656     }
13657 
13658     static ConstString opcode_key ("opcode");
13659     static ConstString before_key ("before_state");
13660     static ConstString after_key ("after_state");
13661 
13662     OptionValueSP value_sp = test_data->GetValueForKey (opcode_key);
13663 
13664     uint32_t test_opcode;
13665     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64))
13666     {
13667         out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n");
13668         return false;
13669     }
13670     test_opcode = value_sp->GetUInt64Value ();
13671 
13672     if (arch.GetTriple().getArch() == llvm::Triple::arm)
13673     {
13674         m_opcode_mode = eModeARM;
13675         m_opcode.SetOpcode32 (test_opcode, GetByteOrder());
13676     }
13677     else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
13678     {
13679         m_opcode_mode = eModeThumb;
13680         if (test_opcode < 0x10000)
13681             m_opcode.SetOpcode16 (test_opcode, GetByteOrder());
13682         else
13683             m_opcode.SetOpcode32 (test_opcode, GetByteOrder());
13684 
13685     }
13686     else
13687     {
13688         out_stream->Printf ("TestEmulation:  Invalid arch.\n");
13689         return false;
13690     }
13691 
13692     EmulationStateARM before_state;
13693     EmulationStateARM after_state;
13694 
13695     value_sp = test_data->GetValueForKey (before_key);
13696     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13697     {
13698         out_stream->Printf ("TestEmulation:  Failed to find 'before' state.\n");
13699         return false;
13700     }
13701 
13702     OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary ();
13703     if (!before_state.LoadStateFromDictionary (state_dictionary))
13704     {
13705         out_stream->Printf ("TestEmulation:  Failed loading 'before' state.\n");
13706         return false;
13707     }
13708 
13709     value_sp = test_data->GetValueForKey (after_key);
13710     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13711     {
13712         out_stream->Printf ("TestEmulation:  Failed to find 'after' state.\n");
13713         return false;
13714     }
13715 
13716     state_dictionary = value_sp->GetAsDictionary ();
13717     if (!after_state.LoadStateFromDictionary (state_dictionary))
13718     {
13719         out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n");
13720         return false;
13721     }
13722 
13723     SetBaton ((void *) &before_state);
13724     SetCallbacks (&EmulationStateARM::ReadPseudoMemory,
13725                   &EmulationStateARM::WritePseudoMemory,
13726                   &EmulationStateARM::ReadPseudoRegister,
13727                   &EmulationStateARM::WritePseudoRegister);
13728 
13729     bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC);
13730     if (!success)
13731     {
13732         out_stream->Printf ("TestEmulation:  EvaluateInstruction() failed.\n");
13733         return false;
13734     }
13735 
13736     success = before_state.CompareState (after_state);
13737     if (!success)
13738         out_stream->Printf ("TestEmulation:  'before' and 'after' states do not match.\n");
13739 
13740     return success;
13741 }
13742 //
13743 //
13744 //const char *
13745 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
13746 //{
13747 //    if (reg_kind == eRegisterKindGeneric)
13748 //    {
13749 //        switch (reg_num)
13750 //        {
13751 //        case LLDB_REGNUM_GENERIC_PC:    return "pc";
13752 //        case LLDB_REGNUM_GENERIC_SP:    return "sp";
13753 //        case LLDB_REGNUM_GENERIC_FP:    return "fp";
13754 //        case LLDB_REGNUM_GENERIC_RA:    return "lr";
13755 //        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
13756 //        default: return NULL;
13757 //        }
13758 //    }
13759 //    else if (reg_kind == eRegisterKindDWARF)
13760 //    {
13761 //        return GetARMDWARFRegisterName (reg_num);
13762 //    }
13763 //    return NULL;
13764 //}
13765 //
13766 bool
13767 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
13768 {
13769     unwind_plan.Clear();
13770     unwind_plan.SetRegisterKind (eRegisterKindDWARF);
13771 
13772     UnwindPlan::RowSP row(new UnwindPlan::Row);
13773 
13774     // Our previous Call Frame Address is the stack pointer
13775     row->GetCFAValue().SetIsRegisterPlusOffset (dwarf_sp, 0);
13776 
13777     unwind_plan.AppendRow (row);
13778     unwind_plan.SetSourceName ("EmulateInstructionARM");
13779     unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
13780     unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
13781     unwind_plan.SetReturnAddressRegister (dwarf_lr);
13782     return true;
13783 }
13784