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     bool is_apple = false;
294     if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
295         is_apple = true;
296     switch (m_arch.GetTriple().getOS())
297     {
298             case llvm::Triple::Darwin:
299             case llvm::Triple::MacOSX:
300             case llvm::Triple::IOS:
301                 is_apple = true;
302                 break;
303             default:
304                 break;
305     }
306 
307     /* On Apple iOS et al, the frame pointer register is always r7.
308      * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
309      */
310 
311     uint32_t fp_regnum = 11;
312 
313     if (is_apple)
314         fp_regnum = 7;
315 
316     if (m_opcode_mode == eModeThumb)
317         fp_regnum = 7;
318 
319     return fp_regnum;
320 }
321 
322 uint32_t
323 EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const
324 {
325     bool is_apple = false;
326     if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
327         is_apple = true;
328     switch (m_arch.GetTriple().getOS())
329     {
330             case llvm::Triple::Darwin:
331             case llvm::Triple::MacOSX:
332             case llvm::Triple::IOS:
333                 is_apple = true;
334                 break;
335             default:
336                 break;
337     }
338 
339     /* On Apple iOS et al, the frame pointer register is always r7.
340      * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
341      */
342 
343     uint32_t fp_regnum = dwarf_r11;
344 
345     if (is_apple)
346         fp_regnum = dwarf_r7;
347 
348     if (m_opcode_mode == eModeThumb)
349         fp_regnum = dwarf_r7;
350 
351     return fp_regnum;
352 }
353 
354 // Push Multiple Registers stores multiple registers to the stack, storing to
355 // consecutive memory locations ending just below the address in SP, and updates
356 // SP to point to the start of the stored data.
357 bool
358 EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding)
359 {
360 #if 0
361     // ARM pseudo code...
362     if (ConditionPassed())
363     {
364         EncodingSpecificOperations();
365         NullCheckIfThumbEE(13);
366         address = SP - 4*BitCount(registers);
367 
368         for (i = 0 to 14)
369         {
370             if (registers<i> == '1')
371             {
372                 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
373                     MemA[address,4] = bits(32) UNKNOWN;
374                 else
375                     MemA[address,4] = R[i];
376                 address = address + 4;
377             }
378         }
379 
380         if (registers<15> == '1') // Only possible for encoding A1 or A2
381             MemA[address,4] = PCStoreValue();
382 
383         SP = SP - 4*BitCount(registers);
384     }
385 #endif
386 
387     bool conditional = false;
388     bool success = false;
389     if (ConditionPassed(opcode, &conditional))
390     {
391         const uint32_t addr_byte_size = GetAddressByteSize();
392         const addr_t sp = ReadCoreReg (SP_REG, &success);
393         if (!success)
394             return false;
395         uint32_t registers = 0;
396         uint32_t Rt; // the source register
397         switch (encoding) {
398         case eEncodingT1:
399             registers = Bits32(opcode, 7, 0);
400             // The M bit represents LR.
401             if (Bit32(opcode, 8))
402                 registers |= (1u << 14);
403             // if BitCount(registers) < 1 then UNPREDICTABLE;
404             if (BitCount(registers) < 1)
405                 return false;
406             break;
407         case eEncodingT2:
408             // Ignore bits 15 & 13.
409             registers = Bits32(opcode, 15, 0) & ~0xa000;
410             // if BitCount(registers) < 2 then UNPREDICTABLE;
411             if (BitCount(registers) < 2)
412                 return false;
413             break;
414         case eEncodingT3:
415             Rt = Bits32(opcode, 15, 12);
416             // if BadReg(t) then UNPREDICTABLE;
417             if (BadReg(Rt))
418                 return false;
419             registers = (1u << Rt);
420             break;
421         case eEncodingA1:
422             registers = Bits32(opcode, 15, 0);
423             // Instead of return false, let's handle the following case as well,
424             // which amounts to pushing one reg onto the full descending stacks.
425             // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
426             break;
427         case eEncodingA2:
428             Rt = Bits32(opcode, 15, 12);
429             // if t == 13 then UNPREDICTABLE;
430             if (Rt == dwarf_sp)
431                 return false;
432             registers = (1u << Rt);
433             break;
434         default:
435             return false;
436         }
437         addr_t sp_offset = addr_byte_size * BitCount (registers);
438         addr_t addr = sp - sp_offset;
439         uint32_t i;
440 
441         EmulateInstruction::Context context;
442         if (conditional)
443             context.type = EmulateInstruction::eContextRegisterStore;
444         else
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     bool conditional = false;
512     if (ConditionPassed(opcode, &conditional))
513     {
514         const uint32_t addr_byte_size = GetAddressByteSize();
515         const addr_t sp = ReadCoreReg (SP_REG, &success);
516         if (!success)
517             return false;
518         uint32_t registers = 0;
519         uint32_t Rt; // the destination register
520         switch (encoding) {
521         case eEncodingT1:
522             registers = Bits32(opcode, 7, 0);
523             // The P bit represents PC.
524             if (Bit32(opcode, 8))
525                 registers |= (1u << 15);
526             // if BitCount(registers) < 1 then UNPREDICTABLE;
527             if (BitCount(registers) < 1)
528                 return false;
529             break;
530         case eEncodingT2:
531             // Ignore bit 13.
532             registers = Bits32(opcode, 15, 0) & ~0x2000;
533             // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
534             if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
535                 return false;
536             // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
537             if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
538                 return false;
539             break;
540         case eEncodingT3:
541             Rt = Bits32(opcode, 15, 12);
542             // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
543             if (Rt == 13)
544                 return false;
545             if (Rt == 15 && InITBlock() && !LastInITBlock())
546                 return false;
547             registers = (1u << Rt);
548             break;
549         case eEncodingA1:
550             registers = Bits32(opcode, 15, 0);
551             // Instead of return false, let's handle the following case as well,
552             // which amounts to popping one reg from the full descending stacks.
553             // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
554 
555             // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
556             if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
557                 return false;
558             break;
559         case eEncodingA2:
560             Rt = Bits32(opcode, 15, 12);
561             // if t == 13 then UNPREDICTABLE;
562             if (Rt == dwarf_sp)
563                 return false;
564             registers = (1u << Rt);
565             break;
566         default:
567             return false;
568         }
569         addr_t sp_offset = addr_byte_size * BitCount (registers);
570         addr_t addr = sp;
571         uint32_t i, data;
572 
573         EmulateInstruction::Context context;
574         if (conditional)
575             context.type = EmulateInstruction::eContextRegisterLoad;
576         else
577             context.type = EmulateInstruction::eContextPopRegisterOffStack;
578 
579         RegisterInfo sp_reg;
580         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
581 
582         for (i=0; i<15; ++i)
583         {
584             if (BitIsSet (registers, i))
585             {
586                 context.SetRegisterPlusOffset (sp_reg, addr - sp);
587                 data = MemARead(context, addr, 4, 0, &success);
588                 if (!success)
589                     return false;
590                 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data))
591                     return false;
592                 addr += addr_byte_size;
593             }
594         }
595 
596         if (BitIsSet (registers, 15))
597         {
598             context.SetRegisterPlusOffset (sp_reg, addr - sp);
599             data = MemARead(context, addr, 4, 0, &success);
600             if (!success)
601                 return false;
602             // In ARMv5T and above, this is an interworking branch.
603             if (!LoadWritePC(context, data))
604                 return false;
605             //addr += addr_byte_size;
606         }
607 
608         context.type = EmulateInstruction::eContextAdjustStackPointer;
609         context.SetImmediateSigned (sp_offset);
610 
611         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
612             return false;
613     }
614     return true;
615 }
616 
617 // Set r7 or ip to point to saved value residing within the stack.
618 // ADD (SP plus immediate)
619 bool
620 EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding)
621 {
622 #if 0
623     // ARM pseudo code...
624     if (ConditionPassed())
625     {
626         EncodingSpecificOperations();
627         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
628         if d == 15 then
629            ALUWritePC(result); // setflags is always FALSE here
630         else
631             R[d] = result;
632             if setflags then
633                 APSR.N = result<31>;
634                 APSR.Z = IsZeroBit(result);
635                 APSR.C = carry;
636                 APSR.V = overflow;
637     }
638 #endif
639 
640     bool success = false;
641 
642     if (ConditionPassed(opcode))
643     {
644         const addr_t sp = ReadCoreReg (SP_REG, &success);
645         if (!success)
646             return false;
647         uint32_t Rd; // the destination register
648         uint32_t imm32;
649         switch (encoding) {
650         case eEncodingT1:
651             Rd = 7;
652             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
653             break;
654         case eEncodingA1:
655             Rd = Bits32(opcode, 15, 12);
656             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
657             break;
658         default:
659             return false;
660         }
661         addr_t sp_offset = imm32;
662         addr_t addr = sp + sp_offset; // a pointer to the stack area
663 
664         EmulateInstruction::Context context;
665         context.type = eContextSetFramePointer;
666         RegisterInfo sp_reg;
667         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
668         context.SetRegisterPlusOffset (sp_reg, sp_offset);
669 
670         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
671             return false;
672     }
673     return true;
674 }
675 
676 // Set r7 or ip to the current stack pointer.
677 // MOV (register)
678 bool
679 EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding)
680 {
681 #if 0
682     // ARM pseudo code...
683     if (ConditionPassed())
684     {
685         EncodingSpecificOperations();
686         result = R[m];
687         if d == 15 then
688             ALUWritePC(result); // setflags is always FALSE here
689         else
690             R[d] = result;
691             if setflags then
692                 APSR.N = result<31>;
693                 APSR.Z = IsZeroBit(result);
694                 // APSR.C unchanged
695                 // APSR.V unchanged
696     }
697 #endif
698 
699     bool success = false;
700 
701     if (ConditionPassed(opcode))
702     {
703         const addr_t sp = ReadCoreReg (SP_REG, &success);
704         if (!success)
705             return false;
706         uint32_t Rd; // the destination register
707         switch (encoding) {
708         case eEncodingT1:
709             Rd = 7;
710             break;
711         case eEncodingA1:
712             Rd = 12;
713             break;
714         default:
715             return false;
716         }
717 
718         EmulateInstruction::Context context;
719         if (Rd == GetFramePointerRegisterNumber())
720             context.type = EmulateInstruction::eContextSetFramePointer;
721         else
722             context.type = EmulateInstruction::eContextRegisterPlusOffset;
723         RegisterInfo sp_reg;
724         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
725         context.SetRegisterPlusOffset (sp_reg, 0);
726 
727         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
728             return false;
729     }
730     return true;
731 }
732 
733 // Move from high register (r8-r15) to low register (r0-r7).
734 // MOV (register)
735 bool
736 EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding)
737 {
738     return EmulateMOVRdRm (opcode, encoding);
739 }
740 
741 // Move from register to register.
742 // MOV (register)
743 bool
744 EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding)
745 {
746 #if 0
747     // ARM pseudo code...
748     if (ConditionPassed())
749     {
750         EncodingSpecificOperations();
751         result = R[m];
752         if d == 15 then
753             ALUWritePC(result); // setflags is always FALSE here
754         else
755             R[d] = result;
756             if setflags then
757                 APSR.N = result<31>;
758                 APSR.Z = IsZeroBit(result);
759                 // APSR.C unchanged
760                 // APSR.V unchanged
761     }
762 #endif
763 
764     bool success = false;
765 
766     if (ConditionPassed(opcode))
767     {
768         uint32_t Rm; // the source register
769         uint32_t Rd; // the destination register
770         bool setflags;
771         switch (encoding) {
772         case eEncodingT1:
773             Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
774             Rm = Bits32(opcode, 6, 3);
775             setflags = false;
776             if (Rd == 15 && InITBlock() && !LastInITBlock())
777                 return false;
778             break;
779         case eEncodingT2:
780             Rd = Bits32(opcode, 2, 0);
781             Rm = Bits32(opcode, 5, 3);
782             setflags = true;
783             if (InITBlock())
784                 return false;
785             break;
786         case eEncodingT3:
787             Rd = Bits32(opcode, 11, 8);
788             Rm = Bits32(opcode, 3, 0);
789             setflags = BitIsSet(opcode, 20);
790             // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
791             if (setflags && (BadReg(Rd) || BadReg(Rm)))
792                 return false;
793             // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE;
794             if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
795                 return false;
796             break;
797         case eEncodingA1:
798             Rd = Bits32(opcode, 15, 12);
799             Rm = Bits32(opcode, 3, 0);
800             setflags = BitIsSet(opcode, 20);
801 
802             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
803             if (Rd == 15 && setflags)
804                 return EmulateSUBSPcLrEtc (opcode, encoding);
805             break;
806         default:
807             return false;
808         }
809         uint32_t result = ReadCoreReg(Rm, &success);
810         if (!success)
811             return false;
812 
813         // The context specifies that Rm is to be moved into Rd.
814         EmulateInstruction::Context context;
815         context.type = EmulateInstruction::eContextRegisterLoad;
816         RegisterInfo dwarf_reg;
817         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
818         context.SetRegister (dwarf_reg);
819 
820         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
821             return false;
822     }
823     return true;
824 }
825 
826 // Move (immediate) writes an immediate value to the destination register.  It
827 // can optionally update the condition flags based on the value.
828 // MOV (immediate)
829 bool
830 EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding)
831 {
832 #if 0
833     // ARM pseudo code...
834     if (ConditionPassed())
835     {
836         EncodingSpecificOperations();
837         result = imm32;
838         if d == 15 then         // Can only occur for ARM encoding
839             ALUWritePC(result); // setflags is always FALSE here
840         else
841             R[d] = result;
842             if setflags then
843                 APSR.N = result<31>;
844                 APSR.Z = IsZeroBit(result);
845                 APSR.C = carry;
846                 // APSR.V unchanged
847     }
848 #endif
849 
850     if (ConditionPassed(opcode))
851     {
852         uint32_t Rd; // the destination register
853         uint32_t imm32; // the immediate value to be written to Rd
854         uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
855                             // for setflags == false, this value is a don't care
856                             // initialized to 0 to silence the static analyzer
857         bool setflags;
858         switch (encoding) {
859             case eEncodingT1:
860                 Rd = Bits32(opcode, 10, 8);
861                 setflags = !InITBlock();
862                 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
863                 carry = APSR_C;
864 
865                 break;
866 
867             case eEncodingT2:
868                 Rd = Bits32(opcode, 11, 8);
869                 setflags = BitIsSet(opcode, 20);
870                 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
871                 if (BadReg(Rd))
872                   return false;
873 
874                 break;
875 
876             case eEncodingT3:
877             {
878                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32);
879                 Rd = Bits32 (opcode, 11, 8);
880                 setflags = false;
881                 uint32_t imm4 = Bits32 (opcode, 19, 16);
882                 uint32_t imm3 = Bits32 (opcode, 14, 12);
883                 uint32_t i = Bit32 (opcode, 26);
884                 uint32_t imm8 = Bits32 (opcode, 7, 0);
885                 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
886 
887                 // if BadReg(d) then UNPREDICTABLE;
888                 if (BadReg (Rd))
889                     return false;
890             }
891                 break;
892 
893             case eEncodingA1:
894                 // d = UInt(Rd); setflags = (S == �1�); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C);
895                 Rd = Bits32 (opcode, 15, 12);
896                 setflags = BitIsSet (opcode, 20);
897                 imm32 = ARMExpandImm_C (opcode, APSR_C, carry);
898 
899                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
900                 if ((Rd == 15) && setflags)
901                     return EmulateSUBSPcLrEtc (opcode, encoding);
902 
903                 break;
904 
905             case eEncodingA2:
906             {
907                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
908                 Rd = Bits32 (opcode, 15, 12);
909                 setflags = false;
910                 uint32_t imm4 = Bits32 (opcode, 19, 16);
911                 uint32_t imm12 = Bits32 (opcode, 11, 0);
912                 imm32 = (imm4 << 12) | imm12;
913 
914                 // if d == 15 then UNPREDICTABLE;
915                 if (Rd == 15)
916                     return false;
917             }
918                 break;
919 
920             default:
921                 return false;
922         }
923         uint32_t result = imm32;
924 
925         // The context specifies that an immediate is to be moved into Rd.
926         EmulateInstruction::Context context;
927         context.type = EmulateInstruction::eContextImmediate;
928         context.SetNoArgs ();
929 
930         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
931             return false;
932     }
933     return true;
934 }
935 
936 // MUL multiplies two register values.  The least significant 32 bits of the result are written to the destination
937 // register.  These 32 bits do not depend on whether the source register values are considered to be signed values or
938 // unsigned values.
939 //
940 // Optionally, it can update the condition flags based on the result.  In the Thumb instruction set, this option is
941 // limited to only a few forms of the instruction.
942 bool
943 EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding)
944 {
945 #if 0
946     if ConditionPassed() then
947         EncodingSpecificOperations();
948         operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
949         operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
950         result = operand1 * operand2;
951         R[d] = result<31:0>;
952         if setflags then
953             APSR.N = result<31>;
954             APSR.Z = IsZeroBit(result);
955             if ArchVersion() == 4 then
956                 APSR.C = bit UNKNOWN;
957             // else APSR.C unchanged
958             // APSR.V always unchanged
959 #endif
960 
961     if (ConditionPassed(opcode))
962     {
963         uint32_t d;
964         uint32_t n;
965         uint32_t m;
966         bool setflags;
967 
968         // EncodingSpecificOperations();
969         switch (encoding)
970         {
971             case eEncodingT1:
972                 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
973                 d = Bits32 (opcode, 2, 0);
974                 n = Bits32 (opcode, 5, 3);
975                 m = Bits32 (opcode, 2, 0);
976                 setflags = !InITBlock();
977 
978                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
979                 if ((ArchVersion() < ARMv6) && (d == n))
980                     return false;
981 
982                 break;
983 
984             case eEncodingT2:
985                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
986                 d = Bits32 (opcode, 11, 8);
987                 n = Bits32 (opcode, 19, 16);
988                 m = Bits32 (opcode, 3, 0);
989                 setflags = false;
990 
991                 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
992                 if (BadReg (d) || BadReg (n) || BadReg (m))
993                     return false;
994 
995                 break;
996 
997             case eEncodingA1:
998                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
999                 d = Bits32 (opcode, 19, 16);
1000                 n = Bits32 (opcode, 3, 0);
1001                 m = Bits32 (opcode, 11, 8);
1002                 setflags = BitIsSet (opcode, 20);
1003 
1004                 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
1005                 if ((d == 15) ||  (n == 15) || (m == 15))
1006                     return false;
1007 
1008                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1009                 if ((ArchVersion() < ARMv6) && (d == n))
1010                     return false;
1011 
1012                 break;
1013 
1014             default:
1015                 return false;
1016         }
1017 
1018         bool success = false;
1019 
1020         // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
1021         uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
1022         if (!success)
1023             return false;
1024 
1025         // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
1026         uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
1027         if (!success)
1028             return false;
1029 
1030         // result = operand1 * operand2;
1031         uint64_t result = operand1 * operand2;
1032 
1033         // R[d] = result<31:0>;
1034         RegisterInfo op1_reg;
1035         RegisterInfo op2_reg;
1036         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
1037         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
1038 
1039         EmulateInstruction::Context context;
1040         context.type = eContextArithmetic;
1041         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
1042 
1043         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result)))
1044             return false;
1045 
1046         // if setflags then
1047         if (setflags)
1048         {
1049             // APSR.N = result<31>;
1050             // APSR.Z = IsZeroBit(result);
1051             m_new_inst_cpsr = m_opcode_cpsr;
1052             SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31));
1053             SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1054             if (m_new_inst_cpsr != m_opcode_cpsr)
1055             {
1056                 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1057                     return false;
1058             }
1059 
1060             // if ArchVersion() == 4 then
1061                 // APSR.C = bit UNKNOWN;
1062         }
1063     }
1064     return true;
1065 }
1066 
1067 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register.
1068 // It can optionally update the condition flags based on the value.
1069 bool
1070 EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding)
1071 {
1072 #if 0
1073     // ARM pseudo code...
1074     if (ConditionPassed())
1075     {
1076         EncodingSpecificOperations();
1077         result = NOT(imm32);
1078         if d == 15 then         // Can only occur for ARM encoding
1079             ALUWritePC(result); // setflags is always FALSE here
1080         else
1081             R[d] = result;
1082             if setflags then
1083                 APSR.N = result<31>;
1084                 APSR.Z = IsZeroBit(result);
1085                 APSR.C = carry;
1086                 // APSR.V unchanged
1087     }
1088 #endif
1089 
1090     if (ConditionPassed(opcode))
1091     {
1092         uint32_t Rd; // the destination register
1093         uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1094         uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1095         bool setflags;
1096         switch (encoding) {
1097         case eEncodingT1:
1098             Rd = Bits32(opcode, 11, 8);
1099             setflags = BitIsSet(opcode, 20);
1100             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1101             break;
1102         case eEncodingA1:
1103             Rd = Bits32(opcode, 15, 12);
1104             setflags = BitIsSet(opcode, 20);
1105             imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1106 
1107             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1108             if (Rd == 15 && setflags)
1109                 return EmulateSUBSPcLrEtc (opcode, encoding);
1110             break;
1111         default:
1112             return false;
1113         }
1114         uint32_t result = ~imm32;
1115 
1116         // The context specifies that an immediate is to be moved into Rd.
1117         EmulateInstruction::Context context;
1118         context.type = EmulateInstruction::eContextImmediate;
1119         context.SetNoArgs ();
1120 
1121         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1122             return false;
1123     }
1124     return true;
1125 }
1126 
1127 // Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register.
1128 // It can optionally update the condition flags based on the result.
1129 bool
1130 EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding)
1131 {
1132 #if 0
1133     // ARM pseudo code...
1134     if (ConditionPassed())
1135     {
1136         EncodingSpecificOperations();
1137         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1138         result = NOT(shifted);
1139         if d == 15 then         // Can only occur for ARM encoding
1140             ALUWritePC(result); // setflags is always FALSE here
1141         else
1142             R[d] = result;
1143             if setflags then
1144                 APSR.N = result<31>;
1145                 APSR.Z = IsZeroBit(result);
1146                 APSR.C = carry;
1147                 // APSR.V unchanged
1148     }
1149 #endif
1150 
1151     if (ConditionPassed(opcode))
1152     {
1153         uint32_t Rm; // the source register
1154         uint32_t Rd; // the destination register
1155         ARM_ShifterType shift_t;
1156         uint32_t shift_n; // the shift applied to the value read from Rm
1157         bool setflags;
1158         uint32_t carry; // the carry bit after the shift operation
1159         switch (encoding) {
1160         case eEncodingT1:
1161             Rd = Bits32(opcode, 2, 0);
1162             Rm = Bits32(opcode, 5, 3);
1163             setflags = !InITBlock();
1164             shift_t = SRType_LSL;
1165             shift_n = 0;
1166             if (InITBlock())
1167                 return false;
1168             break;
1169         case eEncodingT2:
1170             Rd = Bits32(opcode, 11, 8);
1171             Rm = Bits32(opcode, 3, 0);
1172             setflags = BitIsSet(opcode, 20);
1173             shift_n = DecodeImmShiftThumb(opcode, shift_t);
1174             // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1175             if (BadReg(Rd) || BadReg(Rm))
1176                 return false;
1177             break;
1178         case eEncodingA1:
1179             Rd = Bits32(opcode, 15, 12);
1180             Rm = Bits32(opcode, 3, 0);
1181             setflags = BitIsSet(opcode, 20);
1182             shift_n = DecodeImmShiftARM(opcode, shift_t);
1183             break;
1184         default:
1185             return false;
1186         }
1187         bool success = false;
1188         uint32_t value = ReadCoreReg(Rm, &success);
1189         if (!success)
1190             return false;
1191 
1192         uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1193         if (!success)
1194             return false;
1195         uint32_t result = ~shifted;
1196 
1197         // The context specifies that an immediate is to be moved into Rd.
1198         EmulateInstruction::Context context;
1199         context.type = EmulateInstruction::eContextImmediate;
1200         context.SetNoArgs ();
1201 
1202         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1203             return false;
1204     }
1205     return true;
1206 }
1207 
1208 // PC relative immediate load into register, possibly followed by ADD (SP plus register).
1209 // LDR (literal)
1210 bool
1211 EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding)
1212 {
1213 #if 0
1214     // ARM pseudo code...
1215     if (ConditionPassed())
1216     {
1217         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1218         base = Align(PC,4);
1219         address = if add then (base + imm32) else (base - imm32);
1220         data = MemU[address,4];
1221         if t == 15 then
1222             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1223         elsif UnalignedSupport() || address<1:0> = '00' then
1224             R[t] = data;
1225         else // Can only apply before ARMv7
1226             if CurrentInstrSet() == InstrSet_ARM then
1227                 R[t] = ROR(data, 8*UInt(address<1:0>));
1228             else
1229                 R[t] = bits(32) UNKNOWN;
1230     }
1231 #endif
1232 
1233     if (ConditionPassed(opcode))
1234     {
1235         bool success = false;
1236         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1237         if (!success)
1238             return false;
1239 
1240         // PC relative immediate load context
1241         EmulateInstruction::Context context;
1242         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1243         RegisterInfo pc_reg;
1244         GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
1245         context.SetRegisterPlusOffset (pc_reg, 0);
1246 
1247         uint32_t Rt;    // the destination register
1248         uint32_t imm32; // immediate offset from the PC
1249         bool add;       // +imm32 or -imm32?
1250         addr_t base;    // the base address
1251         addr_t address; // the PC relative address
1252         uint32_t data;  // the literal data value from the PC relative load
1253         switch (encoding) {
1254         case eEncodingT1:
1255             Rt = Bits32(opcode, 10, 8);
1256             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1257             add = true;
1258             break;
1259         case eEncodingT2:
1260             Rt = Bits32(opcode, 15, 12);
1261             imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1262             add = BitIsSet(opcode, 23);
1263             if (Rt == 15 && InITBlock() && !LastInITBlock())
1264                 return false;
1265             break;
1266         default:
1267             return false;
1268         }
1269 
1270         base = Align(pc, 4);
1271         if (add)
1272             address = base + imm32;
1273         else
1274             address = base - imm32;
1275 
1276         context.SetRegisterPlusOffset(pc_reg, address - base);
1277         data = MemURead(context, address, 4, 0, &success);
1278         if (!success)
1279             return false;
1280 
1281         if (Rt == 15)
1282         {
1283             if (Bits32(address, 1, 0) == 0)
1284             {
1285                 // In ARMv5T and above, this is an interworking branch.
1286                 if (!LoadWritePC(context, data))
1287                     return false;
1288             }
1289             else
1290                 return false;
1291         }
1292         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
1293         {
1294             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
1295                 return false;
1296         }
1297         else // We don't handle ARM for now.
1298             return false;
1299 
1300     }
1301     return true;
1302 }
1303 
1304 // An add operation to adjust the SP.
1305 // ADD (SP plus immediate)
1306 bool
1307 EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding)
1308 {
1309 #if 0
1310     // ARM pseudo code...
1311     if (ConditionPassed())
1312     {
1313         EncodingSpecificOperations();
1314         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1315         if d == 15 then // Can only occur for ARM encoding
1316             ALUWritePC(result); // setflags is always FALSE here
1317         else
1318             R[d] = result;
1319             if setflags then
1320                 APSR.N = result<31>;
1321                 APSR.Z = IsZeroBit(result);
1322                 APSR.C = carry;
1323                 APSR.V = overflow;
1324     }
1325 #endif
1326 
1327     bool success = false;
1328 
1329     if (ConditionPassed(opcode))
1330     {
1331         const addr_t sp = ReadCoreReg (SP_REG, &success);
1332         if (!success)
1333             return false;
1334         uint32_t imm32; // the immediate operand
1335         uint32_t d;
1336         //bool setflags = false; // Add this back if/when support eEncodingT3 eEncodingA1
1337         switch (encoding)
1338         {
1339             case eEncodingT1:
1340                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1341                 d = Bits32 (opcode, 10, 8);
1342                 imm32 = (Bits32 (opcode, 7, 0) << 2);
1343 
1344                 break;
1345 
1346             case eEncodingT2:
1347                 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1348                 d = 13;
1349                 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1350 
1351                 break;
1352 
1353             default:
1354                 return false;
1355         }
1356         addr_t sp_offset = imm32;
1357         addr_t addr = sp + sp_offset; // the adjusted stack pointer value
1358 
1359         EmulateInstruction::Context context;
1360         if (d == 13)
1361             context.type = EmulateInstruction::eContextAdjustStackPointer;
1362         else
1363             context.type = EmulateInstruction::eContextRegisterPlusOffset;
1364 
1365         RegisterInfo sp_reg;
1366         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1367         context.SetRegisterPlusOffset (sp_reg, sp_offset);
1368 
1369         if (d == 15)
1370         {
1371             if (!ALUWritePC (context, addr))
1372                 return false;
1373         }
1374         else
1375         {
1376             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr))
1377                 return false;
1378 
1379             // Add this back if/when support eEncodingT3 eEncodingA1
1380             //if (setflags)
1381             //{
1382             //    APSR.N = result<31>;
1383             //    APSR.Z = IsZeroBit(result);
1384             //    APSR.C = carry;
1385             //    APSR.V = overflow;
1386             //}
1387         }
1388     }
1389     return true;
1390 }
1391 
1392 // An add operation to adjust the SP.
1393 // ADD (SP plus register)
1394 bool
1395 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding)
1396 {
1397 #if 0
1398     // ARM pseudo code...
1399     if (ConditionPassed())
1400     {
1401         EncodingSpecificOperations();
1402         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1403         (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1404         if d == 15 then
1405             ALUWritePC(result); // setflags is always FALSE here
1406         else
1407             R[d] = result;
1408             if setflags then
1409                 APSR.N = result<31>;
1410                 APSR.Z = IsZeroBit(result);
1411                 APSR.C = carry;
1412                 APSR.V = overflow;
1413     }
1414 #endif
1415 
1416     bool success = false;
1417 
1418     if (ConditionPassed(opcode))
1419     {
1420         const addr_t sp = ReadCoreReg (SP_REG, &success);
1421         if (!success)
1422             return false;
1423         uint32_t Rm; // the second operand
1424         switch (encoding) {
1425         case eEncodingT2:
1426             Rm = Bits32(opcode, 6, 3);
1427             break;
1428         default:
1429             return false;
1430         }
1431         int32_t reg_value = ReadCoreReg(Rm, &success);
1432         if (!success)
1433             return false;
1434 
1435         addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1436 
1437         EmulateInstruction::Context context;
1438         context.type = eContextArithmetic;
1439         RegisterInfo sp_reg;
1440         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1441 
1442         RegisterInfo other_reg;
1443         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1444         context.SetRegisterRegisterOperands (sp_reg, other_reg);
1445 
1446         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
1447             return false;
1448     }
1449     return true;
1450 }
1451 
1452 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
1453 // at a PC-relative address, and changes instruction set from ARM to Thumb, or
1454 // from Thumb to ARM.
1455 // BLX (immediate)
1456 bool
1457 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding)
1458 {
1459 #if 0
1460     // ARM pseudo code...
1461     if (ConditionPassed())
1462     {
1463         EncodingSpecificOperations();
1464         if CurrentInstrSet() == InstrSet_ARM then
1465             LR = PC - 4;
1466         else
1467             LR = PC<31:1> : '1';
1468         if targetInstrSet == InstrSet_ARM then
1469             targetAddress = Align(PC,4) + imm32;
1470         else
1471             targetAddress = PC + imm32;
1472         SelectInstrSet(targetInstrSet);
1473         BranchWritePC(targetAddress);
1474     }
1475 #endif
1476 
1477     bool success = true;
1478 
1479     if (ConditionPassed(opcode))
1480     {
1481         EmulateInstruction::Context context;
1482         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1483         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1484         if (!success)
1485             return false;
1486         addr_t lr; // next instruction address
1487         addr_t target; // target address
1488         int32_t imm32; // PC-relative offset
1489         switch (encoding) {
1490         case eEncodingT1:
1491             {
1492             lr = pc | 1u; // return address
1493             uint32_t S = Bit32(opcode, 26);
1494             uint32_t imm10 = Bits32(opcode, 25, 16);
1495             uint32_t J1 = Bit32(opcode, 13);
1496             uint32_t J2 = Bit32(opcode, 11);
1497             uint32_t imm11 = Bits32(opcode, 10, 0);
1498             uint32_t I1 = !(J1 ^ S);
1499             uint32_t I2 = !(J2 ^ S);
1500             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1501             imm32 = llvm::SignExtend32<25>(imm25);
1502             target = pc + imm32;
1503             SelectInstrSet (eModeThumb);
1504             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
1505             if (InITBlock() && !LastInITBlock())
1506                 return false;
1507             break;
1508             }
1509         case eEncodingT2:
1510             {
1511             lr = pc | 1u; // return address
1512             uint32_t S = Bit32(opcode, 26);
1513             uint32_t imm10H = Bits32(opcode, 25, 16);
1514             uint32_t J1 = Bit32(opcode, 13);
1515             uint32_t J2 = Bit32(opcode, 11);
1516             uint32_t imm10L = Bits32(opcode, 10, 1);
1517             uint32_t I1 = !(J1 ^ S);
1518             uint32_t I2 = !(J2 ^ S);
1519             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
1520             imm32 = llvm::SignExtend32<25>(imm25);
1521             target = Align(pc, 4) + imm32;
1522             SelectInstrSet (eModeARM);
1523             context.SetISAAndImmediateSigned (eModeARM, 4 + imm32);
1524             if (InITBlock() && !LastInITBlock())
1525                 return false;
1526             break;
1527             }
1528         case eEncodingA1:
1529             lr = pc - 4; // return address
1530             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1531             target = Align(pc, 4) + imm32;
1532             SelectInstrSet (eModeARM);
1533             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
1534             break;
1535         case eEncodingA2:
1536             lr = pc - 4; // return address
1537             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
1538             target = pc + imm32;
1539             SelectInstrSet (eModeThumb);
1540             context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32);
1541             break;
1542         default:
1543             return false;
1544         }
1545         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1546             return false;
1547         if (!BranchWritePC(context, target))
1548             return false;
1549         if (m_opcode_cpsr != m_new_inst_cpsr)
1550             if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1551                 return false;
1552     }
1553     return true;
1554 }
1555 
1556 // Branch with Link and Exchange (register) calls a subroutine at an address and
1557 // instruction set specified by a register.
1558 // BLX (register)
1559 bool
1560 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding)
1561 {
1562 #if 0
1563     // ARM pseudo code...
1564     if (ConditionPassed())
1565     {
1566         EncodingSpecificOperations();
1567         target = R[m];
1568         if CurrentInstrSet() == InstrSet_ARM then
1569             next_instr_addr = PC - 4;
1570             LR = next_instr_addr;
1571         else
1572             next_instr_addr = PC - 2;
1573             LR = next_instr_addr<31:1> : '1';
1574         BXWritePC(target);
1575     }
1576 #endif
1577 
1578     bool success = false;
1579 
1580     if (ConditionPassed(opcode))
1581     {
1582         EmulateInstruction::Context context;
1583         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1584         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1585         addr_t lr; // next instruction address
1586         if (!success)
1587             return false;
1588         uint32_t Rm; // the register with the target address
1589         switch (encoding) {
1590         case eEncodingT1:
1591             lr = (pc - 2) | 1u; // return address
1592             Rm = Bits32(opcode, 6, 3);
1593             // if m == 15 then UNPREDICTABLE;
1594             if (Rm == 15)
1595                 return false;
1596             if (InITBlock() && !LastInITBlock())
1597                 return false;
1598             break;
1599         case eEncodingA1:
1600             lr = pc - 4; // return address
1601             Rm = Bits32(opcode, 3, 0);
1602             // if m == 15 then UNPREDICTABLE;
1603             if (Rm == 15)
1604                 return false;
1605             break;
1606         default:
1607             return false;
1608         }
1609         addr_t target = ReadCoreReg (Rm, &success);
1610         if (!success)
1611             return false;
1612         RegisterInfo dwarf_reg;
1613         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1614         context.SetRegister (dwarf_reg);
1615         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1616             return false;
1617         if (!BXWritePC(context, target))
1618             return false;
1619     }
1620     return true;
1621 }
1622 
1623 // Branch and Exchange causes a branch to an address and instruction set specified by a register.
1624 bool
1625 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding)
1626 {
1627 #if 0
1628     // ARM pseudo code...
1629     if (ConditionPassed())
1630     {
1631         EncodingSpecificOperations();
1632         BXWritePC(R[m]);
1633     }
1634 #endif
1635 
1636     if (ConditionPassed(opcode))
1637     {
1638         EmulateInstruction::Context context;
1639         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1640         uint32_t Rm; // the register with the target address
1641         switch (encoding) {
1642         case eEncodingT1:
1643             Rm = Bits32(opcode, 6, 3);
1644             if (InITBlock() && !LastInITBlock())
1645                 return false;
1646             break;
1647         case eEncodingA1:
1648             Rm = Bits32(opcode, 3, 0);
1649             break;
1650         default:
1651             return false;
1652         }
1653         bool success = false;
1654         addr_t target = ReadCoreReg (Rm, &success);
1655         if (!success)
1656             return false;
1657 
1658         RegisterInfo dwarf_reg;
1659         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1660         context.SetRegister (dwarf_reg);
1661         if (!BXWritePC(context, target))
1662             return false;
1663     }
1664     return true;
1665 }
1666 
1667 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an
1668 // address and instruction set specified by a register as though it were a BX instruction.
1669 //
1670 // TODO: Emulate Jazelle architecture?
1671 //       We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation.
1672 bool
1673 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding)
1674 {
1675 #if 0
1676     // ARM pseudo code...
1677     if (ConditionPassed())
1678     {
1679         EncodingSpecificOperations();
1680         if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
1681             BXWritePC(R[m]);
1682         else
1683             if JazelleAcceptsExecution() then
1684                 SwitchToJazelleExecution();
1685             else
1686                 SUBARCHITECTURE_DEFINED handler call;
1687     }
1688 #endif
1689 
1690     if (ConditionPassed(opcode))
1691     {
1692         EmulateInstruction::Context context;
1693         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1694         uint32_t Rm; // the register with the target address
1695         switch (encoding) {
1696         case eEncodingT1:
1697             Rm = Bits32(opcode, 19, 16);
1698             if (BadReg(Rm))
1699                 return false;
1700             if (InITBlock() && !LastInITBlock())
1701                 return false;
1702             break;
1703         case eEncodingA1:
1704             Rm = Bits32(opcode, 3, 0);
1705             if (Rm == 15)
1706                 return false;
1707             break;
1708         default:
1709             return false;
1710         }
1711         bool success = false;
1712         addr_t target = ReadCoreReg (Rm, &success);
1713         if (!success)
1714             return false;
1715 
1716         RegisterInfo dwarf_reg;
1717         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1718         context.SetRegister (dwarf_reg);
1719         if (!BXWritePC(context, target))
1720             return false;
1721     }
1722     return true;
1723 }
1724 
1725 // Set r7 to point to some ip offset.
1726 // SUB (immediate)
1727 bool
1728 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding)
1729 {
1730 #if 0
1731     // ARM pseudo code...
1732     if (ConditionPassed())
1733     {
1734         EncodingSpecificOperations();
1735         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1736         if d == 15 then // Can only occur for ARM encoding
1737            ALUWritePC(result); // setflags is always FALSE here
1738         else
1739             R[d] = result;
1740             if setflags then
1741                 APSR.N = result<31>;
1742                 APSR.Z = IsZeroBit(result);
1743                 APSR.C = carry;
1744                 APSR.V = overflow;
1745     }
1746 #endif
1747 
1748     if (ConditionPassed(opcode))
1749     {
1750         bool success = false;
1751         const addr_t ip = ReadCoreReg (12, &success);
1752         if (!success)
1753             return false;
1754         uint32_t imm32;
1755         switch (encoding) {
1756         case eEncodingA1:
1757             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1758             break;
1759         default:
1760             return false;
1761         }
1762         addr_t ip_offset = imm32;
1763         addr_t addr = ip - ip_offset; // the adjusted ip value
1764 
1765         EmulateInstruction::Context context;
1766         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1767         RegisterInfo dwarf_reg;
1768         GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg);
1769         context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
1770 
1771         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
1772             return false;
1773     }
1774     return true;
1775 }
1776 
1777 // Set ip to point to some stack offset.
1778 // SUB (SP minus immediate)
1779 bool
1780 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding)
1781 {
1782 #if 0
1783     // ARM pseudo code...
1784     if (ConditionPassed())
1785     {
1786         EncodingSpecificOperations();
1787         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1788         if d == 15 then // Can only occur for ARM encoding
1789            ALUWritePC(result); // setflags is always FALSE here
1790         else
1791             R[d] = result;
1792             if setflags then
1793                 APSR.N = result<31>;
1794                 APSR.Z = IsZeroBit(result);
1795                 APSR.C = carry;
1796                 APSR.V = overflow;
1797     }
1798 #endif
1799 
1800     if (ConditionPassed(opcode))
1801     {
1802         bool success = false;
1803         const addr_t sp = ReadCoreReg (SP_REG, &success);
1804         if (!success)
1805             return false;
1806         uint32_t imm32;
1807         switch (encoding) {
1808         case eEncodingA1:
1809             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1810             break;
1811         default:
1812             return false;
1813         }
1814         addr_t sp_offset = imm32;
1815         addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1816 
1817         EmulateInstruction::Context context;
1818         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1819         RegisterInfo dwarf_reg;
1820         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
1821         context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
1822 
1823         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
1824             return false;
1825     }
1826     return true;
1827 }
1828 
1829 // This instruction subtracts an immediate value from the SP value, and writes
1830 // the result to the destination register.
1831 //
1832 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage.
1833 bool
1834 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding)
1835 {
1836 #if 0
1837     // ARM pseudo code...
1838     if (ConditionPassed())
1839     {
1840         EncodingSpecificOperations();
1841         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1842         if d == 15 then        // Can only occur for ARM encoding
1843            ALUWritePC(result); // setflags is always FALSE here
1844         else
1845             R[d] = result;
1846             if setflags then
1847                 APSR.N = result<31>;
1848                 APSR.Z = IsZeroBit(result);
1849                 APSR.C = carry;
1850                 APSR.V = overflow;
1851     }
1852 #endif
1853 
1854     bool success = false;
1855     if (ConditionPassed(opcode))
1856     {
1857         const addr_t sp = ReadCoreReg (SP_REG, &success);
1858         if (!success)
1859             return false;
1860 
1861         uint32_t Rd;
1862         bool setflags;
1863         uint32_t imm32;
1864         switch (encoding) {
1865         case eEncodingT1:
1866             Rd = 13;
1867             setflags = false;
1868             imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1869             break;
1870         case eEncodingT2:
1871             Rd = Bits32(opcode, 11, 8);
1872             setflags = BitIsSet(opcode, 20);
1873             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1874             if (Rd == 15 && setflags)
1875                 return EmulateCMPImm(opcode, eEncodingT2);
1876             if (Rd == 15 && !setflags)
1877                 return false;
1878             break;
1879         case eEncodingT3:
1880             Rd = Bits32(opcode, 11, 8);
1881             setflags = false;
1882             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
1883             if (Rd == 15)
1884                 return false;
1885             break;
1886         case eEncodingA1:
1887             Rd = Bits32(opcode, 15, 12);
1888             setflags = BitIsSet(opcode, 20);
1889             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1890 
1891             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1892             if (Rd == 15 && setflags)
1893                 return EmulateSUBSPcLrEtc (opcode, encoding);
1894             break;
1895         default:
1896             return false;
1897         }
1898         AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
1899 
1900         EmulateInstruction::Context context;
1901         if (Rd == 13)
1902         {
1903             uint64_t imm64 = imm32;  // Need to expand it to 64 bits before attempting to negate it, or the wrong
1904                                      // value gets passed down to context.SetImmediateSigned.
1905             context.type = EmulateInstruction::eContextAdjustStackPointer;
1906             context.SetImmediateSigned (-imm64); // the stack pointer offset
1907         }
1908         else
1909         {
1910             context.type = EmulateInstruction::eContextImmediate;
1911             context.SetNoArgs ();
1912         }
1913 
1914         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
1915             return false;
1916     }
1917     return true;
1918 }
1919 
1920 // A store operation to the stack that also updates the SP.
1921 bool
1922 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding)
1923 {
1924 #if 0
1925     // ARM pseudo code...
1926     if (ConditionPassed())
1927     {
1928         EncodingSpecificOperations();
1929         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1930         address = if index then offset_addr else R[n];
1931         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1932         if wback then R[n] = offset_addr;
1933     }
1934 #endif
1935 
1936     bool conditional = false;
1937     bool success = false;
1938     if (ConditionPassed(opcode, &conditional))
1939     {
1940         const uint32_t addr_byte_size = GetAddressByteSize();
1941         const addr_t sp = ReadCoreReg (SP_REG, &success);
1942         if (!success)
1943             return false;
1944         uint32_t Rt; // the source register
1945         uint32_t imm12;
1946         uint32_t Rn;  // This function assumes Rn is the SP, but we should verify that.
1947 
1948         bool index;
1949         bool add;
1950         bool wback;
1951         switch (encoding) {
1952         case eEncodingA1:
1953             Rt = Bits32(opcode, 15, 12);
1954             imm12 = Bits32(opcode, 11, 0);
1955             Rn = Bits32 (opcode, 19, 16);
1956 
1957             if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
1958                 return false;
1959 
1960             index = BitIsSet (opcode, 24);
1961             add = BitIsSet (opcode, 23);
1962             wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
1963 
1964             if (wback && ((Rn == 15) || (Rn == Rt)))
1965                 return false;
1966             break;
1967         default:
1968             return false;
1969         }
1970         addr_t offset_addr;
1971         if (add)
1972             offset_addr = sp + imm12;
1973         else
1974             offset_addr = sp - imm12;
1975 
1976         addr_t addr;
1977         if (index)
1978             addr = offset_addr;
1979         else
1980             addr = sp;
1981 
1982         EmulateInstruction::Context context;
1983         if (conditional)
1984             context.type = EmulateInstruction::eContextRegisterStore;
1985         else
1986             context.type = EmulateInstruction::eContextPushRegisterOnStack;
1987         RegisterInfo sp_reg;
1988         RegisterInfo dwarf_reg;
1989 
1990         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1991         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
1992         context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
1993         if (Rt != 15)
1994         {
1995             uint32_t reg_value = ReadCoreReg(Rt, &success);
1996             if (!success)
1997                 return false;
1998             if (!MemUWrite (context, addr, reg_value, addr_byte_size))
1999                 return false;
2000         }
2001         else
2002         {
2003             const uint32_t pc = ReadCoreReg(PC_REG, &success);
2004             if (!success)
2005                 return false;
2006             if (!MemUWrite (context, addr, pc, addr_byte_size))
2007                 return false;
2008         }
2009 
2010 
2011         if (wback)
2012         {
2013             context.type = EmulateInstruction::eContextAdjustStackPointer;
2014             context.SetImmediateSigned (addr - sp);
2015             if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr))
2016                 return false;
2017         }
2018     }
2019     return true;
2020 }
2021 
2022 // Vector Push stores multiple extension registers to the stack.
2023 // It also updates SP to point to the start of the stored data.
2024 bool
2025 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding)
2026 {
2027 #if 0
2028     // ARM pseudo code...
2029     if (ConditionPassed())
2030     {
2031         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2032         address = SP - imm32;
2033         SP = SP - imm32;
2034         if single_regs then
2035             for r = 0 to regs-1
2036                 MemA[address,4] = S[d+r]; address = address+4;
2037         else
2038             for r = 0 to regs-1
2039                 // Store as two word-aligned words in the correct order for current endianness.
2040                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
2041                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
2042                 address = address+8;
2043     }
2044 #endif
2045 
2046     bool success = false;
2047     bool conditional = false;
2048     if (ConditionPassed(opcode, &conditional))
2049     {
2050         const uint32_t addr_byte_size = GetAddressByteSize();
2051         const addr_t sp = ReadCoreReg (SP_REG, &success);
2052         if (!success)
2053             return false;
2054         bool single_regs;
2055         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2056         uint32_t imm32; // stack offset
2057         uint32_t regs;  // number of registers
2058         switch (encoding) {
2059         case eEncodingT1:
2060         case eEncodingA1:
2061             single_regs = false;
2062             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2063             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2064             // If UInt(imm8) is odd, see "FSTMX".
2065             regs = Bits32(opcode, 7, 0) / 2;
2066             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2067             if (regs == 0 || regs > 16 || (d + regs) > 32)
2068                 return false;
2069             break;
2070         case eEncodingT2:
2071         case eEncodingA2:
2072             single_regs = true;
2073             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2074             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2075             regs = Bits32(opcode, 7, 0);
2076             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2077             if (regs == 0 || regs > 16 || (d + regs) > 32)
2078                 return false;
2079             break;
2080         default:
2081             return false;
2082         }
2083         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2084         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2085         addr_t sp_offset = imm32;
2086         addr_t addr = sp - sp_offset;
2087         uint32_t i;
2088 
2089         EmulateInstruction::Context context;
2090         if (conditional)
2091             context.type = EmulateInstruction::eContextRegisterStore;
2092         else
2093             context.type = EmulateInstruction::eContextPushRegisterOnStack;
2094         RegisterInfo dwarf_reg;
2095         RegisterInfo sp_reg;
2096         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2097         for (i=0; i<regs; ++i)
2098         {
2099             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2100             context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
2101             // uint64_t to accommodate 64-bit registers.
2102             uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success);
2103             if (!success)
2104                 return false;
2105             if (!MemAWrite (context, addr, reg_value, reg_byte_size))
2106                 return false;
2107             addr += reg_byte_size;
2108         }
2109 
2110         context.type = EmulateInstruction::eContextAdjustStackPointer;
2111         context.SetImmediateSigned (-sp_offset);
2112 
2113         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2114             return false;
2115     }
2116     return true;
2117 }
2118 
2119 // Vector Pop loads multiple extension registers from the stack.
2120 // It also updates SP to point just above the loaded data.
2121 bool
2122 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding)
2123 {
2124 #if 0
2125     // ARM pseudo code...
2126     if (ConditionPassed())
2127     {
2128         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2129         address = SP;
2130         SP = SP + imm32;
2131         if single_regs then
2132             for r = 0 to regs-1
2133                 S[d+r] = MemA[address,4]; address = address+4;
2134         else
2135             for r = 0 to regs-1
2136                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2137                 // Combine the word-aligned words in the correct order for current endianness.
2138                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2139     }
2140 #endif
2141 
2142     bool success = false;
2143     bool conditional = false;
2144     if (ConditionPassed(opcode, &conditional))
2145     {
2146         const uint32_t addr_byte_size = GetAddressByteSize();
2147         const addr_t sp = ReadCoreReg (SP_REG, &success);
2148         if (!success)
2149             return false;
2150         bool single_regs;
2151         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2152         uint32_t imm32; // stack offset
2153         uint32_t regs;  // number of registers
2154         switch (encoding) {
2155         case eEncodingT1:
2156         case eEncodingA1:
2157             single_regs = false;
2158             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2159             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2160             // If UInt(imm8) is odd, see "FLDMX".
2161             regs = Bits32(opcode, 7, 0) / 2;
2162             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2163             if (regs == 0 || regs > 16 || (d + regs) > 32)
2164                 return false;
2165             break;
2166         case eEncodingT2:
2167         case eEncodingA2:
2168             single_regs = true;
2169             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2170             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2171             regs = Bits32(opcode, 7, 0);
2172             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2173             if (regs == 0 || regs > 16 || (d + regs) > 32)
2174                 return false;
2175             break;
2176         default:
2177             return false;
2178         }
2179         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2180         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2181         addr_t sp_offset = imm32;
2182         addr_t addr = sp;
2183         uint32_t i;
2184         uint64_t data; // uint64_t to accommodate 64-bit registers.
2185 
2186         EmulateInstruction::Context context;
2187         if (conditional)
2188             context.type = EmulateInstruction::eContextRegisterLoad;
2189         else
2190             context.type = EmulateInstruction::eContextPopRegisterOffStack;
2191         RegisterInfo dwarf_reg;
2192         RegisterInfo sp_reg;
2193         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2194         for (i=0; i<regs; ++i)
2195         {
2196             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2197             context.SetRegisterPlusOffset (sp_reg, addr - sp);
2198             data = MemARead(context, addr, reg_byte_size, 0, &success);
2199             if (!success)
2200                 return false;
2201             if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2202                 return false;
2203             addr += reg_byte_size;
2204         }
2205 
2206         context.type = EmulateInstruction::eContextAdjustStackPointer;
2207         context.SetImmediateSigned (sp_offset);
2208 
2209         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2210             return false;
2211     }
2212     return true;
2213 }
2214 
2215 // SVC (previously SWI)
2216 bool
2217 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding)
2218 {
2219 #if 0
2220     // ARM pseudo code...
2221     if (ConditionPassed())
2222     {
2223         EncodingSpecificOperations();
2224         CallSupervisor();
2225     }
2226 #endif
2227 
2228     bool success = false;
2229 
2230     if (ConditionPassed(opcode))
2231     {
2232         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2233         addr_t lr; // next instruction address
2234         if (!success)
2235             return false;
2236         uint32_t imm32; // the immediate constant
2237         uint32_t mode;  // ARM or Thumb mode
2238         switch (encoding) {
2239         case eEncodingT1:
2240             lr = (pc + 2) | 1u; // return address
2241             imm32 = Bits32(opcode, 7, 0);
2242             mode = eModeThumb;
2243             break;
2244         case eEncodingA1:
2245             lr = pc + 4; // return address
2246             imm32 = Bits32(opcode, 23, 0);
2247             mode = eModeARM;
2248             break;
2249         default:
2250             return false;
2251         }
2252 
2253         EmulateInstruction::Context context;
2254         context.type = EmulateInstruction::eContextSupervisorCall;
2255         context.SetISAAndImmediate (mode, imm32);
2256         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
2257             return false;
2258     }
2259     return true;
2260 }
2261 
2262 // If Then makes up to four following instructions (the IT block) conditional.
2263 bool
2264 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding)
2265 {
2266 #if 0
2267     // ARM pseudo code...
2268     EncodingSpecificOperations();
2269     ITSTATE.IT<7:0> = firstcond:mask;
2270 #endif
2271 
2272     m_it_session.InitIT(Bits32(opcode, 7, 0));
2273     return true;
2274 }
2275 
2276 bool
2277 EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding)
2278 {
2279     // NOP, nothing to do...
2280     return true;
2281 }
2282 
2283 // Branch causes a branch to a target address.
2284 bool
2285 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding)
2286 {
2287 #if 0
2288     // ARM pseudo code...
2289     if (ConditionPassed())
2290     {
2291         EncodingSpecificOperations();
2292         BranchWritePC(PC + imm32);
2293     }
2294 #endif
2295 
2296     bool success = false;
2297 
2298     if (ConditionPassed(opcode))
2299     {
2300         EmulateInstruction::Context context;
2301         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2302         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2303         if (!success)
2304             return false;
2305         addr_t target; // target address
2306         int32_t imm32; // PC-relative offset
2307         switch (encoding) {
2308         case eEncodingT1:
2309             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2310             imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2311             target = pc + imm32;
2312             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2313             break;
2314         case eEncodingT2:
2315             imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0));
2316             target = pc + imm32;
2317             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2318             break;
2319         case eEncodingT3:
2320             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2321             {
2322             uint32_t S = Bit32(opcode, 26);
2323             uint32_t imm6 = Bits32(opcode, 21, 16);
2324             uint32_t J1 = Bit32(opcode, 13);
2325             uint32_t J2 = Bit32(opcode, 11);
2326             uint32_t imm11 = Bits32(opcode, 10, 0);
2327             uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2328             imm32 = llvm::SignExtend32<21>(imm21);
2329             target = pc + imm32;
2330             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2331             break;
2332             }
2333         case eEncodingT4:
2334             {
2335             uint32_t S = Bit32(opcode, 26);
2336             uint32_t imm10 = Bits32(opcode, 25, 16);
2337             uint32_t J1 = Bit32(opcode, 13);
2338             uint32_t J2 = Bit32(opcode, 11);
2339             uint32_t imm11 = Bits32(opcode, 10, 0);
2340             uint32_t I1 = !(J1 ^ S);
2341             uint32_t I2 = !(J2 ^ S);
2342             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2343             imm32 = llvm::SignExtend32<25>(imm25);
2344             target = pc + imm32;
2345             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2346             break;
2347             }
2348         case eEncodingA1:
2349             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2350             target = pc + imm32;
2351             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
2352             break;
2353         default:
2354             return false;
2355         }
2356         if (!BranchWritePC(context, target))
2357             return false;
2358     }
2359     return true;
2360 }
2361 
2362 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
2363 // zero and conditionally branch forward a constant value.  They do not affect the condition flags.
2364 // CBNZ, CBZ
2365 bool
2366 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding)
2367 {
2368 #if 0
2369     // ARM pseudo code...
2370     EncodingSpecificOperations();
2371     if nonzero ^ IsZero(R[n]) then
2372         BranchWritePC(PC + imm32);
2373 #endif
2374 
2375     bool success = false;
2376 
2377     // Read the register value from the operand register Rn.
2378     uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2379     if (!success)
2380         return false;
2381 
2382     EmulateInstruction::Context context;
2383     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2384     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2385     if (!success)
2386         return false;
2387 
2388     addr_t target;  // target address
2389     uint32_t imm32; // PC-relative offset to branch forward
2390     bool nonzero;
2391     switch (encoding) {
2392     case eEncodingT1:
2393         imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2394         nonzero = BitIsSet(opcode, 11);
2395         target = pc + imm32;
2396         context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2397         break;
2398     default:
2399         return false;
2400     }
2401     if (nonzero ^ (reg_val == 0))
2402         if (!BranchWritePC(context, target))
2403             return false;
2404 
2405     return true;
2406 }
2407 
2408 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
2409 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2410 // The branch length is twice the value of the byte returned from the table.
2411 //
2412 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
2413 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2414 // The branch length is twice the value of the halfword returned from the table.
2415 // TBB, TBH
2416 bool
2417 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding)
2418 {
2419 #if 0
2420     // ARM pseudo code...
2421     EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2422     if is_tbh then
2423         halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2424     else
2425         halfwords = UInt(MemU[R[n]+R[m], 1]);
2426     BranchWritePC(PC + 2*halfwords);
2427 #endif
2428 
2429     bool success = false;
2430 
2431     uint32_t Rn;     // the base register which contains the address of the table of branch lengths
2432     uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
2433     bool is_tbh;     // true if table branch halfword
2434     switch (encoding) {
2435     case eEncodingT1:
2436         Rn = Bits32(opcode, 19, 16);
2437         Rm = Bits32(opcode, 3, 0);
2438         is_tbh = BitIsSet(opcode, 4);
2439         if (Rn == 13 || BadReg(Rm))
2440             return false;
2441         if (InITBlock() && !LastInITBlock())
2442             return false;
2443         break;
2444     default:
2445         return false;
2446     }
2447 
2448     // Read the address of the table from the operand register Rn.
2449     // The PC can be used, in which case the table immediately follows this instruction.
2450     uint32_t base = ReadCoreReg(Rm, &success);
2451     if (!success)
2452         return false;
2453 
2454     // the table index
2455     uint32_t index = ReadCoreReg(Rm, &success);
2456     if (!success)
2457         return false;
2458 
2459     // the offsetted table address
2460     addr_t addr = base + (is_tbh ? index*2 : index);
2461 
2462     // PC-relative offset to branch forward
2463     EmulateInstruction::Context context;
2464     context.type = EmulateInstruction::eContextTableBranchReadMemory;
2465     uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2466     if (!success)
2467         return false;
2468 
2469     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2470     if (!success)
2471         return false;
2472 
2473     // target address
2474     addr_t target = pc + offset;
2475     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2476     context.SetISAAndImmediateSigned (eModeThumb, 4 + offset);
2477 
2478     if (!BranchWritePC(context, target))
2479         return false;
2480 
2481     return true;
2482 }
2483 
2484 // This instruction adds an immediate value to a register value, and writes the result to the destination register.
2485 // It can optionally update the condition flags based on the result.
2486 bool
2487 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding)
2488 {
2489 #if 0
2490     if ConditionPassed() then
2491         EncodingSpecificOperations();
2492         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2493         R[d] = result;
2494         if setflags then
2495             APSR.N = result<31>;
2496             APSR.Z = IsZeroBit(result);
2497             APSR.C = carry;
2498             APSR.V = overflow;
2499 #endif
2500 
2501     bool success = false;
2502 
2503     if (ConditionPassed(opcode))
2504     {
2505         uint32_t d;
2506         uint32_t n;
2507         bool setflags;
2508         uint32_t imm32;
2509         uint32_t carry_out;
2510 
2511         //EncodingSpecificOperations();
2512         switch (encoding)
2513         {
2514             case eEncodingT1:
2515                 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32);
2516                 d = Bits32 (opcode, 2, 0);
2517                 n = Bits32 (opcode, 5, 3);
2518                 setflags = !InITBlock();
2519                 imm32 = Bits32 (opcode, 8,6);
2520 
2521                 break;
2522 
2523             case eEncodingT2:
2524                 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32);
2525                 d = Bits32 (opcode, 10, 8);
2526                 n = Bits32 (opcode, 10, 8);
2527                 setflags = !InITBlock();
2528                 imm32 = Bits32 (opcode, 7, 0);
2529 
2530                 break;
2531 
2532             case eEncodingT3:
2533                 // if Rd == '1111' && S == '1' then SEE CMN (immediate);
2534                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2535                 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8);
2536                 d = Bits32 (opcode, 11, 8);
2537                 n = Bits32 (opcode, 19, 16);
2538                 setflags = BitIsSet (opcode, 20);
2539                 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out);
2540 
2541                 // if BadReg(d) || n == 15 then UNPREDICTABLE;
2542                 if (BadReg (d) || (n == 15))
2543                     return false;
2544 
2545                 break;
2546 
2547             case eEncodingT4:
2548             {
2549                 // if Rn == '1111' then SEE ADR;
2550                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2551                 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
2552                 d = Bits32 (opcode, 11, 8);
2553                 n = Bits32 (opcode, 19, 16);
2554                 setflags = false;
2555                 uint32_t i = Bit32 (opcode, 26);
2556                 uint32_t imm3 = Bits32 (opcode, 14, 12);
2557                 uint32_t imm8 = Bits32 (opcode, 7, 0);
2558                 imm32 = (i << 11) | (imm3 << 8) | imm8;
2559 
2560                 // if BadReg(d) then UNPREDICTABLE;
2561                 if (BadReg (d))
2562                     return false;
2563 
2564                 break;
2565             }
2566             default:
2567                 return false;
2568         }
2569 
2570         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2571         if (!success)
2572             return false;
2573 
2574         //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2575         AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
2576 
2577         RegisterInfo reg_n;
2578         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
2579 
2580         EmulateInstruction::Context context;
2581         context.type = eContextArithmetic;
2582         context.SetRegisterPlusOffset (reg_n, imm32);
2583 
2584         //R[d] = result;
2585         //if setflags then
2586             //APSR.N = result<31>;
2587             //APSR.Z = IsZeroBit(result);
2588             //APSR.C = carry;
2589             //APSR.V = overflow;
2590         if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
2591             return false;
2592 
2593     }
2594     return true;
2595 }
2596 
2597 // This instruction adds an immediate value to a register value, and writes the result to the destination
2598 // register.  It can optionally update the condition flags based on the result.
2599 bool
2600 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding)
2601 {
2602 #if 0
2603     // ARM pseudo code...
2604     if ConditionPassed() then
2605         EncodingSpecificOperations();
2606         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2607         if d == 15 then
2608             ALUWritePC(result); // setflags is always FALSE here
2609         else
2610             R[d] = result;
2611             if setflags then
2612                 APSR.N = result<31>;
2613                 APSR.Z = IsZeroBit(result);
2614                 APSR.C = carry;
2615                 APSR.V = overflow;
2616 #endif
2617 
2618     bool success = false;
2619 
2620     if (ConditionPassed(opcode))
2621     {
2622         uint32_t Rd, Rn;
2623         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
2624         bool setflags;
2625         switch (encoding)
2626         {
2627         case eEncodingA1:
2628             Rd = Bits32(opcode, 15, 12);
2629             Rn = Bits32(opcode, 19, 16);
2630             setflags = BitIsSet(opcode, 20);
2631             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2632             break;
2633         default:
2634             return false;
2635         }
2636 
2637         // Read the first operand.
2638         uint32_t val1 = ReadCoreReg(Rn, &success);
2639         if (!success)
2640             return false;
2641 
2642         AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
2643 
2644         EmulateInstruction::Context context;
2645         context.type = eContextArithmetic;
2646         RegisterInfo dwarf_reg;
2647         GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
2648         context.SetRegisterPlusOffset (dwarf_reg, imm32);
2649 
2650         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2651             return false;
2652     }
2653     return true;
2654 }
2655 
2656 // This instruction adds a register value and an optionally-shifted register value, and writes the result
2657 // to the destination register. It can optionally update the condition flags based on the result.
2658 bool
2659 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding)
2660 {
2661 #if 0
2662     // ARM pseudo code...
2663     if ConditionPassed() then
2664         EncodingSpecificOperations();
2665         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2666         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2667         if d == 15 then
2668             ALUWritePC(result); // setflags is always FALSE here
2669         else
2670             R[d] = result;
2671             if setflags then
2672                 APSR.N = result<31>;
2673                 APSR.Z = IsZeroBit(result);
2674                 APSR.C = carry;
2675                 APSR.V = overflow;
2676 #endif
2677 
2678     bool success = false;
2679 
2680     if (ConditionPassed(opcode))
2681     {
2682         uint32_t Rd, Rn, Rm;
2683         ARM_ShifterType shift_t;
2684         uint32_t shift_n; // the shift applied to the value read from Rm
2685         bool setflags;
2686         switch (encoding)
2687         {
2688         case eEncodingT1:
2689             Rd = Bits32(opcode, 2, 0);
2690             Rn = Bits32(opcode, 5, 3);
2691             Rm = Bits32(opcode, 8, 6);
2692             setflags = !InITBlock();
2693             shift_t = SRType_LSL;
2694             shift_n = 0;
2695             break;
2696         case eEncodingT2:
2697             Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2698             Rm = Bits32(opcode, 6, 3);
2699             setflags = false;
2700             shift_t = SRType_LSL;
2701             shift_n = 0;
2702             if (Rn == 15 && Rm == 15)
2703                 return false;
2704             if (Rd == 15 && InITBlock() && !LastInITBlock())
2705                 return false;
2706             break;
2707         case eEncodingA1:
2708             Rd = Bits32(opcode, 15, 12);
2709             Rn = Bits32(opcode, 19, 16);
2710             Rm = Bits32(opcode, 3, 0);
2711             setflags = BitIsSet(opcode, 20);
2712             shift_n = DecodeImmShiftARM(opcode, shift_t);
2713             break;
2714         default:
2715             return false;
2716         }
2717 
2718         // Read the first operand.
2719         uint32_t val1 = ReadCoreReg(Rn, &success);
2720         if (!success)
2721             return false;
2722 
2723         // Read the second operand.
2724         uint32_t val2 = ReadCoreReg(Rm, &success);
2725         if (!success)
2726             return false;
2727 
2728         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2729         if (!success)
2730             return false;
2731         AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2732 
2733         EmulateInstruction::Context context;
2734         context.type = eContextArithmetic;
2735         RegisterInfo op1_reg;
2736         RegisterInfo op2_reg;
2737         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
2738         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
2739         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
2740 
2741         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2742             return false;
2743     }
2744     return true;
2745 }
2746 
2747 // Compare Negative (immediate) adds a register value and an immediate value.
2748 // It updates the condition flags based on the result, and discards the result.
2749 bool
2750 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding)
2751 {
2752 #if 0
2753     // ARM pseudo code...
2754     if ConditionPassed() then
2755         EncodingSpecificOperations();
2756         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2757         APSR.N = result<31>;
2758         APSR.Z = IsZeroBit(result);
2759         APSR.C = carry;
2760         APSR.V = overflow;
2761 #endif
2762 
2763     bool success = false;
2764 
2765     uint32_t Rn; // the first operand
2766     uint32_t imm32; // the immediate value to be compared with
2767     switch (encoding) {
2768     case eEncodingT1:
2769         Rn = Bits32(opcode, 19, 16);
2770         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2771         if (Rn == 15)
2772             return false;
2773         break;
2774     case eEncodingA1:
2775         Rn = Bits32(opcode, 19, 16);
2776         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2777         break;
2778     default:
2779         return false;
2780     }
2781     // Read the register value from the operand register Rn.
2782     uint32_t reg_val = ReadCoreReg(Rn, &success);
2783     if (!success)
2784         return false;
2785 
2786     AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
2787 
2788     EmulateInstruction::Context context;
2789     context.type = EmulateInstruction::eContextImmediate;
2790     context.SetNoArgs ();
2791     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2792         return false;
2793 
2794     return true;
2795 }
2796 
2797 // Compare Negative (register) adds a register value and an optionally-shifted register value.
2798 // It updates the condition flags based on the result, and discards the result.
2799 bool
2800 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding)
2801 {
2802 #if 0
2803     // ARM pseudo code...
2804     if ConditionPassed() then
2805         EncodingSpecificOperations();
2806         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2807         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2808         APSR.N = result<31>;
2809         APSR.Z = IsZeroBit(result);
2810         APSR.C = carry;
2811         APSR.V = overflow;
2812 #endif
2813 
2814     bool success = false;
2815 
2816     uint32_t Rn; // the first operand
2817     uint32_t Rm; // the second operand
2818     ARM_ShifterType shift_t;
2819     uint32_t shift_n; // the shift applied to the value read from Rm
2820     switch (encoding) {
2821     case eEncodingT1:
2822         Rn = Bits32(opcode, 2, 0);
2823         Rm = Bits32(opcode, 5, 3);
2824         shift_t = SRType_LSL;
2825         shift_n = 0;
2826         break;
2827     case eEncodingT2:
2828         Rn = Bits32(opcode, 19, 16);
2829         Rm = Bits32(opcode, 3, 0);
2830         shift_n = DecodeImmShiftThumb(opcode, shift_t);
2831         // if n == 15 || BadReg(m) then UNPREDICTABLE;
2832         if (Rn == 15 || BadReg(Rm))
2833             return false;
2834         break;
2835     case eEncodingA1:
2836         Rn = Bits32(opcode, 19, 16);
2837         Rm = Bits32(opcode, 3, 0);
2838         shift_n = DecodeImmShiftARM(opcode, shift_t);
2839         break;
2840     default:
2841         return false;
2842     }
2843     // Read the register value from register Rn.
2844     uint32_t val1 = ReadCoreReg(Rn, &success);
2845     if (!success)
2846         return false;
2847 
2848     // Read the register value from register Rm.
2849     uint32_t val2 = ReadCoreReg(Rm, &success);
2850     if (!success)
2851         return false;
2852 
2853     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2854     if (!success)
2855         return false;
2856     AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2857 
2858     EmulateInstruction::Context context;
2859     context.type = EmulateInstruction::eContextImmediate;
2860     context.SetNoArgs();
2861     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2862         return false;
2863 
2864     return true;
2865 }
2866 
2867 // Compare (immediate) subtracts an immediate value from a register value.
2868 // It updates the condition flags based on the result, and discards the result.
2869 bool
2870 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding)
2871 {
2872 #if 0
2873     // ARM pseudo code...
2874     if ConditionPassed() then
2875         EncodingSpecificOperations();
2876         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2877         APSR.N = result<31>;
2878         APSR.Z = IsZeroBit(result);
2879         APSR.C = carry;
2880         APSR.V = overflow;
2881 #endif
2882 
2883     bool success = false;
2884 
2885     uint32_t Rn; // the first operand
2886     uint32_t imm32; // the immediate value to be compared with
2887     switch (encoding) {
2888     case eEncodingT1:
2889         Rn = Bits32(opcode, 10, 8);
2890         imm32 = Bits32(opcode, 7, 0);
2891         break;
2892     case eEncodingT2:
2893         Rn = Bits32(opcode, 19, 16);
2894         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2895         if (Rn == 15)
2896             return false;
2897         break;
2898     case eEncodingA1:
2899         Rn = Bits32(opcode, 19, 16);
2900         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2901         break;
2902     default:
2903         return false;
2904     }
2905     // Read the register value from the operand register Rn.
2906     uint32_t reg_val = ReadCoreReg(Rn, &success);
2907     if (!success)
2908         return false;
2909 
2910     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
2911 
2912     EmulateInstruction::Context context;
2913     context.type = EmulateInstruction::eContextImmediate;
2914     context.SetNoArgs ();
2915     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2916         return false;
2917 
2918     return true;
2919 }
2920 
2921 // Compare (register) subtracts an optionally-shifted register value from a register value.
2922 // It updates the condition flags based on the result, and discards the result.
2923 bool
2924 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding)
2925 {
2926 #if 0
2927     // ARM pseudo code...
2928     if ConditionPassed() then
2929         EncodingSpecificOperations();
2930         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2931         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2932         APSR.N = result<31>;
2933         APSR.Z = IsZeroBit(result);
2934         APSR.C = carry;
2935         APSR.V = overflow;
2936 #endif
2937 
2938     bool success = false;
2939 
2940     uint32_t Rn; // the first operand
2941     uint32_t Rm; // the second operand
2942     ARM_ShifterType shift_t;
2943     uint32_t shift_n; // the shift applied to the value read from Rm
2944     switch (encoding) {
2945     case eEncodingT1:
2946         Rn = Bits32(opcode, 2, 0);
2947         Rm = Bits32(opcode, 5, 3);
2948         shift_t = SRType_LSL;
2949         shift_n = 0;
2950         break;
2951     case eEncodingT2:
2952         Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2953         Rm = Bits32(opcode, 6, 3);
2954         shift_t = SRType_LSL;
2955         shift_n = 0;
2956         if (Rn < 8 && Rm < 8)
2957             return false;
2958         if (Rn == 15 || Rm == 15)
2959             return false;
2960         break;
2961     case eEncodingA1:
2962         Rn = Bits32(opcode, 19, 16);
2963         Rm = Bits32(opcode, 3, 0);
2964         shift_n = DecodeImmShiftARM(opcode, shift_t);
2965         break;
2966     default:
2967         return false;
2968     }
2969     // Read the register value from register Rn.
2970     uint32_t val1 = ReadCoreReg(Rn, &success);
2971     if (!success)
2972         return false;
2973 
2974     // Read the register value from register Rm.
2975     uint32_t val2 = ReadCoreReg(Rm, &success);
2976     if (!success)
2977         return false;
2978 
2979     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2980     if (!success)
2981         return false;
2982     AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
2983 
2984     EmulateInstruction::Context context;
2985     context.type = EmulateInstruction::eContextImmediate;
2986     context.SetNoArgs();
2987     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2988         return false;
2989 
2990     return true;
2991 }
2992 
2993 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
2994 // shifting in copies of its sign bit, and writes the result to the destination register.  It can
2995 // optionally update the condition flags based on the result.
2996 bool
2997 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding)
2998 {
2999 #if 0
3000     // ARM pseudo code...
3001     if ConditionPassed() then
3002         EncodingSpecificOperations();
3003         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3004         if d == 15 then         // Can only occur for ARM encoding
3005             ALUWritePC(result); // setflags is always FALSE here
3006         else
3007             R[d] = result;
3008             if setflags then
3009                 APSR.N = result<31>;
3010                 APSR.Z = IsZeroBit(result);
3011                 APSR.C = carry;
3012                 // APSR.V unchanged
3013 #endif
3014 
3015     return EmulateShiftImm (opcode, encoding, SRType_ASR);
3016 }
3017 
3018 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
3019 // shifting in copies of its sign bit, and writes the result to the destination register.
3020 // The variable number of bits is read from the bottom byte of a register. It can optionally update
3021 // the condition flags based on the result.
3022 bool
3023 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding)
3024 {
3025 #if 0
3026     // ARM pseudo code...
3027     if ConditionPassed() then
3028         EncodingSpecificOperations();
3029         shift_n = UInt(R[m]<7:0>);
3030         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3031         R[d] = result;
3032         if setflags then
3033             APSR.N = result<31>;
3034             APSR.Z = IsZeroBit(result);
3035             APSR.C = carry;
3036             // APSR.V unchanged
3037 #endif
3038 
3039     return EmulateShiftReg (opcode, encoding, SRType_ASR);
3040 }
3041 
3042 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
3043 // shifting in zeros, and writes the result to the destination register.  It can optionally
3044 // update the condition flags based on the result.
3045 bool
3046 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding)
3047 {
3048 #if 0
3049     // ARM pseudo code...
3050     if ConditionPassed() then
3051         EncodingSpecificOperations();
3052         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3053         if d == 15 then         // Can only occur for ARM encoding
3054             ALUWritePC(result); // setflags is always FALSE here
3055         else
3056             R[d] = result;
3057             if setflags then
3058                 APSR.N = result<31>;
3059                 APSR.Z = IsZeroBit(result);
3060                 APSR.C = carry;
3061                 // APSR.V unchanged
3062 #endif
3063 
3064     return EmulateShiftImm (opcode, encoding, SRType_LSL);
3065 }
3066 
3067 // Logical Shift Left (register) shifts a register value left by a variable number of bits,
3068 // shifting in zeros, and writes the result to the destination register.  The variable number
3069 // of bits is read from the bottom byte of a register. It can optionally update the condition
3070 // flags based on the result.
3071 bool
3072 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding)
3073 {
3074 #if 0
3075     // ARM pseudo code...
3076     if ConditionPassed() then
3077         EncodingSpecificOperations();
3078         shift_n = UInt(R[m]<7:0>);
3079         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3080         R[d] = result;
3081         if setflags then
3082             APSR.N = result<31>;
3083             APSR.Z = IsZeroBit(result);
3084             APSR.C = carry;
3085             // APSR.V unchanged
3086 #endif
3087 
3088     return EmulateShiftReg (opcode, encoding, SRType_LSL);
3089 }
3090 
3091 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
3092 // shifting in zeros, and writes the result to the destination register.  It can optionally
3093 // update the condition flags based on the result.
3094 bool
3095 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding)
3096 {
3097 #if 0
3098     // ARM pseudo code...
3099     if ConditionPassed() then
3100         EncodingSpecificOperations();
3101         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3102         if d == 15 then         // Can only occur for ARM encoding
3103             ALUWritePC(result); // setflags is always FALSE here
3104         else
3105             R[d] = result;
3106             if setflags then
3107                 APSR.N = result<31>;
3108                 APSR.Z = IsZeroBit(result);
3109                 APSR.C = carry;
3110                 // APSR.V unchanged
3111 #endif
3112 
3113     return EmulateShiftImm (opcode, encoding, SRType_LSR);
3114 }
3115 
3116 // Logical Shift Right (register) shifts a register value right by a variable number of bits,
3117 // shifting in zeros, and writes the result to the destination register.  The variable number
3118 // of bits is read from the bottom byte of a register. It can optionally update the condition
3119 // flags based on the result.
3120 bool
3121 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding)
3122 {
3123 #if 0
3124     // ARM pseudo code...
3125     if ConditionPassed() then
3126         EncodingSpecificOperations();
3127         shift_n = UInt(R[m]<7:0>);
3128         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3129         R[d] = result;
3130         if setflags then
3131             APSR.N = result<31>;
3132             APSR.Z = IsZeroBit(result);
3133             APSR.C = carry;
3134             // APSR.V unchanged
3135 #endif
3136 
3137     return EmulateShiftReg (opcode, encoding, SRType_LSR);
3138 }
3139 
3140 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
3141 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3142 // It can optionally update the condition flags based on the result.
3143 bool
3144 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding)
3145 {
3146 #if 0
3147     // ARM pseudo code...
3148     if ConditionPassed() then
3149         EncodingSpecificOperations();
3150         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3151         if d == 15 then         // Can only occur for ARM encoding
3152             ALUWritePC(result); // setflags is always FALSE here
3153         else
3154             R[d] = result;
3155             if setflags then
3156                 APSR.N = result<31>;
3157                 APSR.Z = IsZeroBit(result);
3158                 APSR.C = carry;
3159                 // APSR.V unchanged
3160 #endif
3161 
3162     return EmulateShiftImm (opcode, encoding, SRType_ROR);
3163 }
3164 
3165 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
3166 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3167 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
3168 // flags based on the result.
3169 bool
3170 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding)
3171 {
3172 #if 0
3173     // ARM pseudo code...
3174     if ConditionPassed() then
3175         EncodingSpecificOperations();
3176         shift_n = UInt(R[m]<7:0>);
3177         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3178         R[d] = result;
3179         if setflags then
3180             APSR.N = result<31>;
3181             APSR.Z = IsZeroBit(result);
3182             APSR.C = carry;
3183             // APSR.V unchanged
3184 #endif
3185 
3186     return EmulateShiftReg (opcode, encoding, SRType_ROR);
3187 }
3188 
3189 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
3190 // with the carry flag shifted into bit [31].
3191 //
3192 // RRX can optionally update the condition flags based on the result.
3193 // In that case, bit [0] is shifted into the carry flag.
3194 bool
3195 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding)
3196 {
3197 #if 0
3198     // ARM pseudo code...
3199     if ConditionPassed() then
3200         EncodingSpecificOperations();
3201         (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3202         if d == 15 then         // Can only occur for ARM encoding
3203             ALUWritePC(result); // setflags is always FALSE here
3204         else
3205             R[d] = result;
3206             if setflags then
3207                 APSR.N = result<31>;
3208                 APSR.Z = IsZeroBit(result);
3209                 APSR.C = carry;
3210                 // APSR.V unchanged
3211 #endif
3212 
3213     return EmulateShiftImm (opcode, encoding, SRType_RRX);
3214 }
3215 
3216 bool
3217 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3218 {
3219 //    assert(shift_type == SRType_ASR
3220 //           || shift_type == SRType_LSL
3221 //           || shift_type == SRType_LSR
3222 //           || shift_type == SRType_ROR
3223 //           || shift_type == SRType_RRX);
3224 
3225     bool success = false;
3226 
3227     if (ConditionPassed(opcode))
3228     {
3229         uint32_t Rd;    // the destination register
3230         uint32_t Rm;    // the first operand register
3231         uint32_t imm5;  // encoding for the shift amount
3232         uint32_t carry; // the carry bit after the shift operation
3233         bool setflags;
3234 
3235         // Special case handling!
3236         // A8.6.139 ROR (immediate) -- Encoding T1
3237         ARMEncoding use_encoding = encoding;
3238         if (shift_type == SRType_ROR && use_encoding == eEncodingT1)
3239         {
3240             // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
3241             // have the same decoding of bit fields as the other Thumb2 shift operations.
3242             use_encoding = eEncodingT2;
3243         }
3244 
3245         switch (use_encoding) {
3246         case eEncodingT1:
3247             // Due to the above special case handling!
3248             if (shift_type == SRType_ROR)
3249                 return false;
3250 
3251             Rd = Bits32(opcode, 2, 0);
3252             Rm = Bits32(opcode, 5, 3);
3253             setflags = !InITBlock();
3254             imm5 = Bits32(opcode, 10, 6);
3255             break;
3256         case eEncodingT2:
3257             // A8.6.141 RRX
3258             // There's no imm form of RRX instructions.
3259             if (shift_type == SRType_RRX)
3260                 return false;
3261 
3262             Rd = Bits32(opcode, 11, 8);
3263             Rm = Bits32(opcode, 3, 0);
3264             setflags = BitIsSet(opcode, 20);
3265             imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3266             if (BadReg(Rd) || BadReg(Rm))
3267                 return false;
3268             break;
3269         case eEncodingA1:
3270             Rd = Bits32(opcode, 15, 12);
3271             Rm = Bits32(opcode, 3, 0);
3272             setflags = BitIsSet(opcode, 20);
3273             imm5 = Bits32(opcode, 11, 7);
3274             break;
3275         default:
3276             return false;
3277         }
3278 
3279         // A8.6.139 ROR (immediate)
3280         if (shift_type == SRType_ROR && imm5 == 0)
3281             shift_type = SRType_RRX;
3282 
3283         // Get the first operand.
3284         uint32_t value = ReadCoreReg (Rm, &success);
3285         if (!success)
3286             return false;
3287 
3288         // Decode the shift amount if not RRX.
3289         uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3290 
3291         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3292         if (!success)
3293             return false;
3294 
3295         // The context specifies that an immediate is to be moved into Rd.
3296         EmulateInstruction::Context context;
3297         context.type = EmulateInstruction::eContextImmediate;
3298         context.SetNoArgs ();
3299 
3300         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3301             return false;
3302     }
3303     return true;
3304 }
3305 
3306 bool
3307 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3308 {
3309     // assert(shift_type == SRType_ASR
3310     //        || shift_type == SRType_LSL
3311     //        || shift_type == SRType_LSR
3312     //        || shift_type == SRType_ROR);
3313 
3314     bool success = false;
3315 
3316     if (ConditionPassed(opcode))
3317     {
3318         uint32_t Rd;    // the destination register
3319         uint32_t Rn;    // the first operand register
3320         uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
3321         uint32_t carry; // the carry bit after the shift operation
3322         bool setflags;
3323         switch (encoding) {
3324         case eEncodingT1:
3325             Rd = Bits32(opcode, 2, 0);
3326             Rn = Rd;
3327             Rm = Bits32(opcode, 5, 3);
3328             setflags = !InITBlock();
3329             break;
3330         case eEncodingT2:
3331             Rd = Bits32(opcode, 11, 8);
3332             Rn = Bits32(opcode, 19, 16);
3333             Rm = Bits32(opcode, 3, 0);
3334             setflags = BitIsSet(opcode, 20);
3335             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3336                 return false;
3337             break;
3338         case eEncodingA1:
3339             Rd = Bits32(opcode, 15, 12);
3340             Rn = Bits32(opcode, 3, 0);
3341             Rm = Bits32(opcode, 11, 8);
3342             setflags = BitIsSet(opcode, 20);
3343             if (Rd == 15 || Rn == 15 || Rm == 15)
3344                 return false;
3345             break;
3346         default:
3347             return false;
3348         }
3349 
3350         // Get the first operand.
3351         uint32_t value = ReadCoreReg (Rn, &success);
3352         if (!success)
3353             return false;
3354         // Get the Rm register content.
3355         uint32_t val = ReadCoreReg (Rm, &success);
3356         if (!success)
3357             return false;
3358 
3359         // Get the shift amount.
3360         uint32_t amt = Bits32(val, 7, 0);
3361 
3362         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3363         if (!success)
3364             return false;
3365 
3366         // The context specifies that an immediate is to be moved into Rd.
3367         EmulateInstruction::Context context;
3368         context.type = EmulateInstruction::eContextImmediate;
3369         context.SetNoArgs ();
3370 
3371         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3372             return false;
3373     }
3374     return true;
3375 }
3376 
3377 // LDM loads multiple registers from consecutive memory locations, using an
3378 // address from a base register.  Optionally the address just above the highest of those locations
3379 // can be written back to the base register.
3380 bool
3381 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding)
3382 {
3383 #if 0
3384     // ARM pseudo code...
3385     if ConditionPassed()
3386         EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3387         address = R[n];
3388 
3389         for i = 0 to 14
3390             if registers<i> == '1' then
3391                 R[i] = MemA[address, 4]; address = address + 4;
3392         if registers<15> == '1' then
3393             LoadWritePC (MemA[address, 4]);
3394 
3395         if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3396         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3397 
3398 #endif
3399 
3400     bool success = false;
3401     bool conditional = false;
3402     if (ConditionPassed(opcode, &conditional))
3403     {
3404         uint32_t n;
3405         uint32_t registers = 0;
3406         bool wback;
3407         const uint32_t addr_byte_size = GetAddressByteSize();
3408         switch (encoding)
3409         {
3410             case eEncodingT1:
3411                 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0');
3412                 n = Bits32 (opcode, 10, 8);
3413                 registers = Bits32 (opcode, 7, 0);
3414                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3415                 wback = BitIsClear (registers, n);
3416                 // if BitCount(registers) < 1 then UNPREDICTABLE;
3417                 if (BitCount(registers) < 1)
3418                     return false;
3419                 break;
3420             case eEncodingT2:
3421                 // if W == '1' && Rn == '1101' then SEE POP;
3422                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3423                 n = Bits32 (opcode, 19, 16);
3424                 registers = Bits32 (opcode, 15, 0);
3425                 registers = registers & 0xdfff; // Make sure bit 13 is zero.
3426                 wback = BitIsSet (opcode, 21);
3427 
3428                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3429                 if ((n == 15)
3430                     || (BitCount (registers) < 2)
3431                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3432                     return false;
3433 
3434                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3435                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3436                     return false;
3437 
3438                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3439                 if (wback
3440                     && BitIsSet (registers, n))
3441                     return false;
3442                 break;
3443 
3444             case eEncodingA1:
3445                 n = Bits32 (opcode, 19, 16);
3446                 registers = Bits32 (opcode, 15, 0);
3447                 wback = BitIsSet (opcode, 21);
3448                 if ((n == 15)
3449                     || (BitCount (registers) < 1))
3450                     return false;
3451                 break;
3452             default:
3453                 return false;
3454         }
3455 
3456         int32_t offset = 0;
3457         const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3458         if (!success)
3459             return false;
3460 
3461         EmulateInstruction::Context context;
3462         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3463         RegisterInfo dwarf_reg;
3464         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3465         context.SetRegisterPlusOffset (dwarf_reg, offset);
3466 
3467         for (int i = 0; i < 14; ++i)
3468         {
3469             if (BitIsSet (registers, i))
3470             {
3471                 context.type = EmulateInstruction::eContextRegisterPlusOffset;
3472                 context.SetRegisterPlusOffset (dwarf_reg, offset);
3473                 if (wback && (n == 13)) // Pop Instruction
3474                 {
3475                     if (conditional)
3476                         context.type = EmulateInstruction::eContextRegisterLoad;
3477                     else
3478                         context.type = EmulateInstruction::eContextPopRegisterOffStack;
3479                 }
3480 
3481                 // R[i] = MemA [address, 4]; address = address + 4;
3482                 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3483                 if (!success)
3484                     return false;
3485 
3486                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3487                     return false;
3488 
3489                 offset += addr_byte_size;
3490             }
3491         }
3492 
3493         if (BitIsSet (registers, 15))
3494         {
3495             //LoadWritePC (MemA [address, 4]);
3496             context.type = EmulateInstruction::eContextRegisterPlusOffset;
3497             context.SetRegisterPlusOffset (dwarf_reg, offset);
3498             uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3499             if (!success)
3500                 return false;
3501             // In ARMv5T and above, this is an interworking branch.
3502             if (!LoadWritePC(context, data))
3503                 return false;
3504         }
3505 
3506         if (wback && BitIsClear (registers, n))
3507         {
3508             // R[n] = R[n] + 4 * BitCount (registers)
3509             int32_t offset = addr_byte_size * BitCount (registers);
3510             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3511             context.SetRegisterPlusOffset (dwarf_reg, offset);
3512 
3513             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
3514                 return false;
3515         }
3516         if (wback && BitIsSet (registers, n))
3517             // R[n] bits(32) UNKNOWN;
3518             return WriteBits32Unknown (n);
3519     }
3520     return true;
3521 }
3522 
3523 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register.
3524 // The consecutive memory locations end at this address and the address just below the lowest of those locations
3525 // can optionally be written back to the base register.
3526 bool
3527 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding)
3528 {
3529 #if 0
3530     // ARM pseudo code...
3531     if ConditionPassed() then
3532         EncodingSpecificOperations();
3533         address = R[n] - 4*BitCount(registers) + 4;
3534 
3535         for i = 0 to 14
3536             if registers<i> == '1' then
3537                   R[i] = MemA[address,4]; address = address + 4;
3538 
3539         if registers<15> == '1' then
3540             LoadWritePC(MemA[address,4]);
3541 
3542         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3543         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3544 #endif
3545 
3546     bool success = false;
3547 
3548     if (ConditionPassed(opcode))
3549     {
3550         uint32_t n;
3551         uint32_t registers = 0;
3552         bool wback;
3553         const uint32_t addr_byte_size = GetAddressByteSize();
3554 
3555         // EncodingSpecificOperations();
3556         switch (encoding)
3557         {
3558             case eEncodingA1:
3559                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3560                 n = Bits32 (opcode, 19, 16);
3561                 registers = Bits32 (opcode, 15, 0);
3562                 wback = BitIsSet (opcode, 21);
3563 
3564                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3565                 if ((n == 15) || (BitCount (registers) < 1))
3566                     return false;
3567 
3568                 break;
3569 
3570             default:
3571                 return false;
3572         }
3573         // address = R[n] - 4*BitCount(registers) + 4;
3574 
3575         int32_t offset = 0;
3576         addr_t Rn = ReadCoreReg (n, &success);
3577 
3578         if (!success)
3579             return false;
3580 
3581         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size;
3582 
3583         EmulateInstruction::Context context;
3584         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3585         RegisterInfo dwarf_reg;
3586         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3587         context.SetRegisterPlusOffset (dwarf_reg, offset);
3588 
3589         // for i = 0 to 14
3590         for (int i = 0; i < 14; ++i)
3591         {
3592             // if registers<i> == '1' then
3593             if (BitIsSet (registers, i))
3594             {
3595                   // R[i] = MemA[address,4]; address = address + 4;
3596                   context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3597                   uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3598                   if (!success)
3599                       return false;
3600                   if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3601                       return false;
3602                   offset += addr_byte_size;
3603             }
3604         }
3605 
3606         // if registers<15> == '1' then
3607         //     LoadWritePC(MemA[address,4]);
3608         if (BitIsSet (registers, 15))
3609         {
3610             context.SetRegisterPlusOffset (dwarf_reg, offset);
3611             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3612             if (!success)
3613                 return false;
3614             // In ARMv5T and above, this is an interworking branch.
3615             if (!LoadWritePC(context, data))
3616                 return false;
3617         }
3618 
3619         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3620         if (wback && BitIsClear (registers, n))
3621         {
3622             if (!success)
3623                 return false;
3624 
3625             offset = (addr_byte_size * BitCount (registers)) * -1;
3626             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3627             context.SetImmediateSigned (offset);
3628             addr_t addr = Rn + offset;
3629             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3630                 return false;
3631         }
3632 
3633         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3634         if (wback && BitIsSet (registers, n))
3635             return WriteBits32Unknown (n);
3636     }
3637     return true;
3638 }
3639 
3640 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
3641 // consecutive memory locations end just below this address, and the address of the lowest of those locations can
3642 // be optionally written back to the base register.
3643 bool
3644 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding)
3645 {
3646 #if 0
3647     // ARM pseudo code...
3648     if ConditionPassed() then
3649         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3650         address = R[n] - 4*BitCount(registers);
3651 
3652         for i = 0 to 14
3653             if registers<i> == '1' then
3654                   R[i] = MemA[address,4]; address = address + 4;
3655         if registers<15> == '1' then
3656                   LoadWritePC(MemA[address,4]);
3657 
3658         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3659         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3660 #endif
3661 
3662     bool success = false;
3663 
3664     if (ConditionPassed(opcode))
3665     {
3666         uint32_t n;
3667         uint32_t registers = 0;
3668         bool wback;
3669         const uint32_t addr_byte_size = GetAddressByteSize();
3670         switch (encoding)
3671         {
3672             case eEncodingT1:
3673                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3674                 n = Bits32 (opcode, 19, 16);
3675                 registers = Bits32 (opcode, 15, 0);
3676                 registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
3677                 wback = BitIsSet (opcode, 21);
3678 
3679                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3680                 if ((n == 15)
3681                     || (BitCount (registers) < 2)
3682                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3683                     return false;
3684 
3685                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3686                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3687                     return false;
3688 
3689                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3690                 if (wback && BitIsSet (registers, n))
3691                     return false;
3692 
3693                 break;
3694 
3695             case eEncodingA1:
3696                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3697                 n = Bits32 (opcode, 19, 16);
3698                 registers = Bits32 (opcode, 15, 0);
3699                 wback = BitIsSet (opcode, 21);
3700 
3701                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3702                 if ((n == 15) || (BitCount (registers) < 1))
3703                     return false;
3704 
3705                 break;
3706 
3707             default:
3708                 return false;
3709         }
3710 
3711         // address = R[n] - 4*BitCount(registers);
3712 
3713         int32_t offset = 0;
3714         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3715 
3716         if (!success)
3717             return false;
3718 
3719         addr_t address = Rn - (addr_byte_size * BitCount (registers));
3720         EmulateInstruction::Context context;
3721         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3722         RegisterInfo dwarf_reg;
3723         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3724         context.SetRegisterPlusOffset (dwarf_reg, Rn - address);
3725 
3726         for (int i = 0; i < 14; ++i)
3727         {
3728             if (BitIsSet (registers, i))
3729             {
3730                 // R[i] = MemA[address,4]; address = address + 4;
3731                 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3732                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3733                 if (!success)
3734                     return false;
3735 
3736                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3737                     return false;
3738 
3739                 offset += addr_byte_size;
3740             }
3741         }
3742 
3743         // if registers<15> == '1' then
3744         //     LoadWritePC(MemA[address,4]);
3745         if (BitIsSet (registers, 15))
3746         {
3747             context.SetRegisterPlusOffset (dwarf_reg, offset);
3748             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3749             if (!success)
3750                 return false;
3751             // In ARMv5T and above, this is an interworking branch.
3752             if (!LoadWritePC(context, data))
3753                 return false;
3754         }
3755 
3756         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3757         if (wback && BitIsClear (registers, n))
3758         {
3759             if (!success)
3760                 return false;
3761 
3762             offset = (addr_byte_size * BitCount (registers)) * -1;
3763             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3764             context.SetImmediateSigned (offset);
3765             addr_t addr = Rn + offset;
3766             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3767                 return false;
3768         }
3769 
3770         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3771         if (wback && BitIsSet (registers, n))
3772             return WriteBits32Unknown (n);
3773     }
3774     return true;
3775 }
3776 
3777 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
3778 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can
3779 // optinoally be written back to the base register.
3780 bool
3781 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding)
3782 {
3783 #if 0
3784     if ConditionPassed() then
3785         EncodingSpecificOperations();
3786         address = R[n] + 4;
3787 
3788         for i = 0 to 14
3789             if registers<i> == '1' then
3790                   R[i] = MemA[address,4]; address = address + 4;
3791         if registers<15> == '1' then
3792             LoadWritePC(MemA[address,4]);
3793 
3794         if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3795         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3796 #endif
3797 
3798     bool success = false;
3799 
3800     if (ConditionPassed(opcode))
3801     {
3802         uint32_t n;
3803         uint32_t registers = 0;
3804         bool wback;
3805         const uint32_t addr_byte_size = GetAddressByteSize();
3806         switch (encoding)
3807         {
3808             case eEncodingA1:
3809                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3810                 n = Bits32 (opcode, 19, 16);
3811                 registers = Bits32 (opcode, 15, 0);
3812                 wback = BitIsSet (opcode, 21);
3813 
3814                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3815                 if ((n == 15) || (BitCount (registers) < 1))
3816                     return false;
3817 
3818                 break;
3819             default:
3820                 return false;
3821         }
3822         // address = R[n] + 4;
3823 
3824         int32_t offset = 0;
3825         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3826 
3827         if (!success)
3828             return false;
3829 
3830         addr_t address = Rn + addr_byte_size;
3831 
3832         EmulateInstruction::Context context;
3833         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3834         RegisterInfo dwarf_reg;
3835         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3836         context.SetRegisterPlusOffset (dwarf_reg, offset);
3837 
3838         for (int i = 0; i < 14; ++i)
3839         {
3840             if (BitIsSet (registers, i))
3841             {
3842                 // R[i] = MemA[address,4]; address = address + 4;
3843 
3844                 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size);
3845                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3846                 if (!success)
3847                     return false;
3848 
3849                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3850                     return false;
3851 
3852                 offset += addr_byte_size;
3853             }
3854         }
3855 
3856         // if registers<15> == '1' then
3857         //     LoadWritePC(MemA[address,4]);
3858         if (BitIsSet (registers, 15))
3859         {
3860             context.SetRegisterPlusOffset (dwarf_reg, offset);
3861             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3862             if (!success)
3863                 return false;
3864             // In ARMv5T and above, this is an interworking branch.
3865             if (!LoadWritePC(context, data))
3866                 return false;
3867         }
3868 
3869         // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3870         if (wback && BitIsClear (registers, n))
3871         {
3872             if (!success)
3873                 return false;
3874 
3875             offset = addr_byte_size * BitCount (registers);
3876             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3877             context.SetImmediateSigned (offset);
3878             addr_t addr = Rn + offset;
3879             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3880                 return false;
3881         }
3882 
3883         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3884         if (wback && BitIsSet (registers, n))
3885             return WriteBits32Unknown (n);
3886     }
3887     return true;
3888 }
3889 
3890 // Load Register (immediate) calculates an address from a base register value and
3891 // an immediate offset, loads a word from memory, and writes to a register.
3892 // LDR (immediate, Thumb)
3893 bool
3894 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding)
3895 {
3896 #if 0
3897     // ARM pseudo code...
3898     if (ConditionPassed())
3899     {
3900         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3901         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3902         address = if index then offset_addr else R[n];
3903         data = MemU[address,4];
3904         if wback then R[n] = offset_addr;
3905         if t == 15 then
3906             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3907         elsif UnalignedSupport() || address<1:0> = '00' then
3908             R[t] = data;
3909         else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3910     }
3911 #endif
3912 
3913     bool success = false;
3914 
3915     if (ConditionPassed(opcode))
3916     {
3917         uint32_t Rt; // the destination register
3918         uint32_t Rn; // the base register
3919         uint32_t imm32; // the immediate offset used to form the address
3920         addr_t offset_addr; // the offset address
3921         addr_t address; // the calculated address
3922         uint32_t data; // the literal data value from memory load
3923         bool add, index, wback;
3924         switch (encoding) {
3925             case eEncodingT1:
3926                 Rt = Bits32(opcode, 2, 0);
3927                 Rn = Bits32(opcode, 5, 3);
3928                 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3929                 // index = TRUE; add = TRUE; wback = FALSE
3930                 add = true;
3931                 index = true;
3932                 wback = false;
3933 
3934                 break;
3935 
3936             case eEncodingT2:
3937                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
3938                 Rt = Bits32 (opcode, 10, 8);
3939                 Rn = 13;
3940                 imm32 = Bits32 (opcode, 7, 0) << 2;
3941 
3942                 // index = TRUE; add = TRUE; wback = FALSE;
3943                 index = true;
3944                 add = true;
3945                 wback = false;
3946 
3947                 break;
3948 
3949             case eEncodingT3:
3950                 // if Rn == '1111' then SEE LDR (literal);
3951                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
3952                 Rt = Bits32 (opcode, 15, 12);
3953                 Rn = Bits32 (opcode, 19, 16);
3954                 imm32 = Bits32 (opcode, 11, 0);
3955 
3956                 // index = TRUE; add = TRUE; wback = FALSE;
3957                 index = true;
3958                 add = true;
3959                 wback = false;
3960 
3961                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3962                 if ((Rt == 15) && InITBlock() && !LastInITBlock())
3963                     return false;
3964 
3965                 break;
3966 
3967             case eEncodingT4:
3968                 // if Rn == '1111' then SEE LDR (literal);
3969                 // if P == '1' && U == '1' && W == '0' then SEE LDRT;
3970                 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
3971                 // if P == '0' && W == '0' then UNDEFINED;
3972                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
3973                     return false;
3974 
3975                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
3976                 Rt = Bits32 (opcode, 15, 12);
3977                 Rn = Bits32 (opcode, 19, 16);
3978                 imm32 = Bits32 (opcode, 7, 0);
3979 
3980                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
3981                 index = BitIsSet (opcode, 10);
3982                 add = BitIsSet (opcode, 9);
3983                 wback = BitIsSet (opcode, 8);
3984 
3985                 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
3986                 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock()))
3987                     return false;
3988 
3989                 break;
3990 
3991             default:
3992                 return false;
3993         }
3994         uint32_t base = ReadCoreReg (Rn, &success);
3995         if (!success)
3996             return false;
3997         if (add)
3998             offset_addr = base + imm32;
3999         else
4000             offset_addr = base - imm32;
4001 
4002         address = (index ? offset_addr : base);
4003 
4004         RegisterInfo base_reg;
4005         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
4006         if (wback)
4007         {
4008             EmulateInstruction::Context ctx;
4009             ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
4010             ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
4011 
4012             if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
4013                 return false;
4014         }
4015 
4016         // Prepare to write to the Rt register.
4017         EmulateInstruction::Context context;
4018         context.type = EmulateInstruction::eContextRegisterLoad;
4019         context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
4020 
4021         // Read memory from the address.
4022         data = MemURead(context, address, 4, 0, &success);
4023         if (!success)
4024             return false;
4025 
4026         if (Rt == 15)
4027         {
4028             if (Bits32(address, 1, 0) == 0)
4029             {
4030                 if (!LoadWritePC(context, data))
4031                     return false;
4032             }
4033             else
4034                 return false;
4035         }
4036         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
4037         {
4038             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
4039                 return false;
4040         }
4041         else
4042             WriteBits32Unknown (Rt);
4043     }
4044     return true;
4045 }
4046 
4047 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
4048 // from a base register.  The consecutive memory locations start at this address, and the address just above the last
4049 // of those locations can optionally be written back to the base register.
4050 bool
4051 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding)
4052 {
4053 #if 0
4054     if ConditionPassed() then
4055         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4056         address = R[n];
4057 
4058         for i = 0 to 14
4059             if registers<i> == '1' then
4060                 if i == n && wback && i != LowestSetBit(registers) then
4061                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4062                 else
4063                     MemA[address,4] = R[i];
4064                 address = address + 4;
4065 
4066         if registers<15> == '1' then // Only possible for encoding A1
4067             MemA[address,4] = PCStoreValue();
4068         if wback then R[n] = R[n] + 4*BitCount(registers);
4069 #endif
4070 
4071     bool success = false;
4072 
4073     if (ConditionPassed(opcode))
4074     {
4075         uint32_t n;
4076         uint32_t registers = 0;
4077         bool wback;
4078         const uint32_t addr_byte_size = GetAddressByteSize();
4079 
4080         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4081         switch (encoding)
4082         {
4083             case eEncodingT1:
4084                 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4085                 n = Bits32 (opcode, 10, 8);
4086                 registers = Bits32 (opcode, 7, 0);
4087                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
4088                 wback = true;
4089 
4090                 // if BitCount(registers) < 1 then UNPREDICTABLE;
4091                 if (BitCount (registers) < 1)
4092                     return false;
4093 
4094                 break;
4095 
4096             case eEncodingT2:
4097                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4098                 n = Bits32 (opcode, 19, 16);
4099                 registers = Bits32 (opcode, 15, 0);
4100                 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4101                 wback = BitIsSet (opcode, 21);
4102 
4103                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4104                 if ((n == 15) || (BitCount (registers) < 2))
4105                     return false;
4106 
4107                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4108                 if (wback && BitIsSet (registers, n))
4109                     return false;
4110 
4111                 break;
4112 
4113             case eEncodingA1:
4114                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4115                 n = Bits32 (opcode, 19, 16);
4116                 registers = Bits32 (opcode, 15, 0);
4117                 wback = BitIsSet (opcode, 21);
4118 
4119                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4120                 if ((n == 15) || (BitCount (registers) < 1))
4121                     return false;
4122 
4123                 break;
4124 
4125             default:
4126                 return false;
4127         }
4128 
4129         // address = R[n];
4130         int32_t offset = 0;
4131         const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4132         if (!success)
4133             return false;
4134 
4135         EmulateInstruction::Context context;
4136         context.type = EmulateInstruction::eContextRegisterStore;
4137         RegisterInfo base_reg;
4138         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4139 
4140         // for i = 0 to 14
4141         uint32_t lowest_set_bit = 14;
4142         for (uint32_t i = 0; i < 14; ++i)
4143         {
4144             // if registers<i> == '1' then
4145             if (BitIsSet (registers, i))
4146             {
4147                   if (i < lowest_set_bit)
4148                       lowest_set_bit = i;
4149                   // if i == n && wback && i != LowestSetBit(registers) then
4150                   if ((i == n) && wback && (i != lowest_set_bit))
4151                       // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4152                       WriteBits32UnknownToMemory (address + offset);
4153                   else
4154                   {
4155                      // MemA[address,4] = R[i];
4156                       uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4157                       if (!success)
4158                           return false;
4159 
4160                       RegisterInfo data_reg;
4161                       GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4162                       context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4163                       if (!MemAWrite (context, address + offset, data, addr_byte_size))
4164                           return false;
4165                   }
4166 
4167                   // address = address + 4;
4168                   offset += addr_byte_size;
4169             }
4170         }
4171 
4172         // if registers<15> == '1' then // Only possible for encoding A1
4173         //     MemA[address,4] = PCStoreValue();
4174         if (BitIsSet (registers, 15))
4175         {
4176             RegisterInfo pc_reg;
4177             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4178             context.SetRegisterPlusOffset (pc_reg, 8);
4179             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4180             if (!success)
4181                 return false;
4182 
4183             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4184                 return false;
4185         }
4186 
4187         // if wback then R[n] = R[n] + 4*BitCount(registers);
4188         if (wback)
4189         {
4190             offset = addr_byte_size * BitCount (registers);
4191             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4192             context.SetImmediateSigned (offset);
4193             addr_t data = address + offset;
4194             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4195                 return false;
4196         }
4197     }
4198     return true;
4199 }
4200 
4201 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
4202 // from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
4203 // of those locations can optionally be written back to the base register.
4204 bool
4205 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding)
4206 {
4207 #if 0
4208     if ConditionPassed() then
4209         EncodingSpecificOperations();
4210         address = R[n] - 4*BitCount(registers) + 4;
4211 
4212         for i = 0 to 14
4213             if registers<i> == '1' then
4214                 if i == n && wback && i != LowestSetBit(registers) then
4215                     MemA[address,4] = bits(32) UNKNOWN;
4216                 else
4217                     MemA[address,4] = R[i];
4218                 address = address + 4;
4219 
4220         if registers<15> == '1' then
4221             MemA[address,4] = PCStoreValue();
4222 
4223         if wback then R[n] = R[n] - 4*BitCount(registers);
4224 #endif
4225 
4226     bool success = false;
4227 
4228     if (ConditionPassed(opcode))
4229     {
4230         uint32_t n;
4231         uint32_t registers = 0;
4232         bool wback;
4233         const uint32_t addr_byte_size = GetAddressByteSize();
4234 
4235         // EncodingSpecificOperations();
4236         switch (encoding)
4237         {
4238             case eEncodingA1:
4239                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4240                 n = Bits32 (opcode, 19, 16);
4241                 registers = Bits32 (opcode, 15, 0);
4242                 wback = BitIsSet (opcode, 21);
4243 
4244                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4245                 if ((n == 15) || (BitCount (registers) < 1))
4246                     return false;
4247                 break;
4248             default:
4249                 return false;
4250         }
4251 
4252         // address = R[n] - 4*BitCount(registers) + 4;
4253         int32_t offset = 0;
4254         addr_t Rn = ReadCoreReg (n, &success);
4255         if (!success)
4256             return false;
4257 
4258         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4;
4259 
4260         EmulateInstruction::Context context;
4261         context.type = EmulateInstruction::eContextRegisterStore;
4262         RegisterInfo base_reg;
4263         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4264 
4265         // for i = 0 to 14
4266         uint32_t lowest_bit_set = 14;
4267         for (uint32_t i = 0; i < 14; ++i)
4268         {
4269             // if registers<i> == '1' then
4270             if (BitIsSet (registers, i))
4271             {
4272                 if (i < lowest_bit_set)
4273                     lowest_bit_set = i;
4274                 //if i == n && wback && i != LowestSetBit(registers) then
4275                 if ((i == n) && wback && (i != lowest_bit_set))
4276                     // MemA[address,4] = bits(32) UNKNOWN;
4277                     WriteBits32UnknownToMemory (address + offset);
4278                 else
4279                 {
4280                     // MemA[address,4] = R[i];
4281                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4282                     if (!success)
4283                         return false;
4284 
4285                     RegisterInfo data_reg;
4286                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4287                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4288                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4289                         return false;
4290                 }
4291 
4292                 // address = address + 4;
4293                 offset += addr_byte_size;
4294             }
4295         }
4296 
4297         // if registers<15> == '1' then
4298         //    MemA[address,4] = PCStoreValue();
4299         if (BitIsSet (registers, 15))
4300         {
4301             RegisterInfo pc_reg;
4302             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4303             context.SetRegisterPlusOffset (pc_reg, 8);
4304             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4305             if (!success)
4306                 return false;
4307 
4308             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4309                 return false;
4310         }
4311 
4312         // if wback then R[n] = R[n] - 4*BitCount(registers);
4313         if (wback)
4314         {
4315             offset = (addr_byte_size * BitCount (registers)) * -1;
4316             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4317             context.SetImmediateSigned (offset);
4318             addr_t data = Rn + offset;
4319             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4320                 return false;
4321         }
4322     }
4323     return true;
4324 }
4325 
4326 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
4327 // from a base register.  The consecutive memory locations end just below this address, and the address of the first of
4328 // those locations can optionally be written back to the base register.
4329 bool
4330 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding)
4331 {
4332 #if 0
4333     if ConditionPassed() then
4334         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4335         address = R[n] - 4*BitCount(registers);
4336 
4337         for i = 0 to 14
4338             if registers<i> == '1' then
4339                 if i == n && wback && i != LowestSetBit(registers) then
4340                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4341                 else
4342                     MemA[address,4] = R[i];
4343                 address = address + 4;
4344 
4345         if registers<15> == '1' then // Only possible for encoding A1
4346             MemA[address,4] = PCStoreValue();
4347 
4348         if wback then R[n] = R[n] - 4*BitCount(registers);
4349 #endif
4350 
4351 
4352     bool success = false;
4353 
4354     if (ConditionPassed(opcode))
4355     {
4356         uint32_t n;
4357         uint32_t registers = 0;
4358         bool wback;
4359         const uint32_t addr_byte_size = GetAddressByteSize();
4360 
4361         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4362         switch (encoding)
4363         {
4364             case eEncodingT1:
4365                 // if W == '1' && Rn == '1101' then SEE PUSH;
4366                 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
4367                 {
4368                     // See PUSH
4369                 }
4370                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4371                 n = Bits32 (opcode, 19, 16);
4372                 registers = Bits32 (opcode, 15, 0);
4373                 registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
4374                 wback = BitIsSet (opcode, 21);
4375                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4376                 if ((n == 15) || BitCount (registers) < 2)
4377                     return false;
4378                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4379                 if (wback && BitIsSet (registers, n))
4380                     return false;
4381                 break;
4382 
4383             case eEncodingA1:
4384                 // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH;
4385                 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
4386                 {
4387                     // See Push
4388                 }
4389                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4390                 n = Bits32 (opcode, 19, 16);
4391                 registers = Bits32 (opcode, 15, 0);
4392                 wback = BitIsSet (opcode, 21);
4393                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4394                 if ((n == 15) || BitCount (registers) < 1)
4395                     return false;
4396                 break;
4397 
4398             default:
4399                 return false;
4400         }
4401 
4402         // address = R[n] - 4*BitCount(registers);
4403 
4404         int32_t offset = 0;
4405         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4406         if (!success)
4407         return false;
4408 
4409         addr_t address = Rn - (addr_byte_size * BitCount (registers));
4410 
4411         EmulateInstruction::Context context;
4412         context.type = EmulateInstruction::eContextRegisterStore;
4413         RegisterInfo base_reg;
4414         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4415 
4416         // for i = 0 to 14
4417         uint32_t lowest_set_bit = 14;
4418         for (uint32_t i = 0; i < 14; ++i)
4419         {
4420             // if registers<i> == '1' then
4421             if (BitIsSet (registers, i))
4422             {
4423                 if (i < lowest_set_bit)
4424                     lowest_set_bit = i;
4425                 // if i == n && wback && i != LowestSetBit(registers) then
4426                 if ((i == n) && wback && (i != lowest_set_bit))
4427                     // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4428                     WriteBits32UnknownToMemory (address + offset);
4429                 else
4430                 {
4431                     // MemA[address,4] = R[i];
4432                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4433                     if (!success)
4434                         return false;
4435 
4436                     RegisterInfo data_reg;
4437                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4438                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4439                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4440                         return false;
4441                 }
4442 
4443                 // address = address + 4;
4444                 offset += addr_byte_size;
4445             }
4446         }
4447 
4448         // if registers<15> == '1' then // Only possible for encoding A1
4449         //     MemA[address,4] = PCStoreValue();
4450         if (BitIsSet (registers, 15))
4451         {
4452             RegisterInfo pc_reg;
4453             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4454             context.SetRegisterPlusOffset (pc_reg, 8);
4455             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4456             if (!success)
4457                 return false;
4458 
4459             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4460                 return false;
4461         }
4462 
4463         // if wback then R[n] = R[n] - 4*BitCount(registers);
4464         if (wback)
4465         {
4466             offset = (addr_byte_size * BitCount (registers)) * -1;
4467             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4468             context.SetImmediateSigned (offset);
4469             addr_t data = Rn + offset;
4470             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4471                 return false;
4472         }
4473     }
4474     return true;
4475 }
4476 
4477 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
4478 // from a base register.  The consecutive memory locations start just above this address, and the address of the last
4479 // of those locations can optionally be written back to the base register.
4480 bool
4481 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding)
4482 {
4483 #if 0
4484     if ConditionPassed() then
4485         EncodingSpecificOperations();
4486         address = R[n] + 4;
4487 
4488         for i = 0 to 14
4489             if registers<i> == '1' then
4490                 if i == n && wback && i != LowestSetBit(registers) then
4491                     MemA[address,4] = bits(32) UNKNOWN;
4492                 else
4493                     MemA[address,4] = R[i];
4494                 address = address + 4;
4495 
4496         if registers<15> == '1' then
4497             MemA[address,4] = PCStoreValue();
4498 
4499         if wback then R[n] = R[n] + 4*BitCount(registers);
4500 #endif
4501 
4502     bool success = false;
4503 
4504     if (ConditionPassed(opcode))
4505     {
4506         uint32_t n;
4507         uint32_t registers = 0;
4508         bool wback;
4509         const uint32_t addr_byte_size = GetAddressByteSize();
4510 
4511         // EncodingSpecificOperations();
4512         switch (encoding)
4513         {
4514             case eEncodingA1:
4515                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4516                 n = Bits32 (opcode, 19, 16);
4517                 registers = Bits32 (opcode, 15, 0);
4518                 wback = BitIsSet (opcode, 21);
4519 
4520                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4521                 if ((n == 15) && (BitCount (registers) < 1))
4522                     return false;
4523                 break;
4524             default:
4525                 return false;
4526         }
4527         // address = R[n] + 4;
4528 
4529         int32_t offset = 0;
4530         addr_t Rn = ReadCoreReg (n, &success);
4531         if (!success)
4532             return false;
4533 
4534         addr_t address = Rn + addr_byte_size;
4535 
4536         EmulateInstruction::Context context;
4537         context.type = EmulateInstruction::eContextRegisterStore;
4538         RegisterInfo base_reg;
4539         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4540 
4541         uint32_t lowest_set_bit = 14;
4542         // for i = 0 to 14
4543         for (uint32_t i = 0; i < 14; ++i)
4544         {
4545             // if registers<i> == '1' then
4546             if (BitIsSet (registers, i))
4547             {
4548                 if (i < lowest_set_bit)
4549                     lowest_set_bit = i;
4550                 // if i == n && wback && i != LowestSetBit(registers) then
4551                 if ((i == n) && wback && (i != lowest_set_bit))
4552                     // MemA[address,4] = bits(32) UNKNOWN;
4553                     WriteBits32UnknownToMemory (address + offset);
4554                 // else
4555                 else
4556                 {
4557                     // MemA[address,4] = R[i];
4558                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4559                     if (!success)
4560                         return false;
4561 
4562                     RegisterInfo data_reg;
4563                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4564                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size);
4565                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4566                         return false;
4567                 }
4568 
4569                 // address = address + 4;
4570                 offset += addr_byte_size;
4571             }
4572         }
4573 
4574         // if registers<15> == '1' then
4575             // MemA[address,4] = PCStoreValue();
4576         if (BitIsSet (registers, 15))
4577         {
4578             RegisterInfo pc_reg;
4579             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4580             context.SetRegisterPlusOffset (pc_reg, 8);
4581             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4582             if (!success)
4583             return false;
4584 
4585             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4586                 return false;
4587         }
4588 
4589         // if wback then R[n] = R[n] + 4*BitCount(registers);
4590         if (wback)
4591         {
4592             offset = addr_byte_size * BitCount (registers);
4593             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4594             context.SetImmediateSigned (offset);
4595             addr_t data = Rn + offset;
4596             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4597                 return false;
4598         }
4599     }
4600     return true;
4601 }
4602 
4603 // STR (store immediate) calculates an address from a base register value and an immediate offset, and stores a word
4604 // from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
4605 bool
4606 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding)
4607 {
4608 #if 0
4609     if ConditionPassed() then
4610         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4611         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4612         address = if index then offset_addr else R[n];
4613         if UnalignedSupport() || address<1:0> == '00' then
4614             MemU[address,4] = R[t];
4615         else // Can only occur before ARMv7
4616             MemU[address,4] = bits(32) UNKNOWN;
4617         if wback then R[n] = offset_addr;
4618 #endif
4619 
4620     bool success = false;
4621 
4622     if (ConditionPassed(opcode))
4623     {
4624         const uint32_t addr_byte_size = GetAddressByteSize();
4625 
4626         uint32_t t;
4627         uint32_t n;
4628         uint32_t imm32;
4629         bool index;
4630         bool add;
4631         bool wback;
4632         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4633         switch (encoding)
4634         {
4635             case eEncodingT1:
4636                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
4637                 t = Bits32 (opcode, 2, 0);
4638                 n = Bits32 (opcode, 5, 3);
4639                 imm32 = Bits32 (opcode, 10, 6) << 2;
4640 
4641                 // index = TRUE; add = TRUE; wback = FALSE;
4642                 index = true;
4643                 add = false;
4644                 wback = false;
4645                 break;
4646 
4647             case eEncodingT2:
4648                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4649                 t = Bits32 (opcode, 10, 8);
4650                 n = 13;
4651                 imm32 = Bits32 (opcode, 7, 0) << 2;
4652 
4653                 // index = TRUE; add = TRUE; wback = FALSE;
4654                 index = true;
4655                 add = true;
4656                 wback = false;
4657                 break;
4658 
4659             case eEncodingT3:
4660                 // if Rn == '1111' then UNDEFINED;
4661                 if (Bits32 (opcode, 19, 16) == 15)
4662                     return false;
4663 
4664                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4665                 t = Bits32 (opcode, 15, 12);
4666                 n = Bits32 (opcode, 19, 16);
4667                 imm32 = Bits32 (opcode, 11, 0);
4668 
4669                 // index = TRUE; add = TRUE; wback = FALSE;
4670                 index = true;
4671                 add = true;
4672                 wback = false;
4673 
4674                 // if t == 15 then UNPREDICTABLE;
4675                 if (t == 15)
4676                     return false;
4677                 break;
4678 
4679             case eEncodingT4:
4680                 // if P == '1' && U == '1' && W == '0' then SEE STRT;
4681                 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH;
4682                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4683                 if ((Bits32 (opcode, 19, 16) == 15)
4684                       || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
4685                     return false;
4686 
4687                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4688                 t = Bits32 (opcode, 15, 12);
4689                 n = Bits32 (opcode, 19, 16);
4690                 imm32 = Bits32 (opcode, 7, 0);
4691 
4692                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4693                 index = BitIsSet (opcode, 10);
4694                 add = BitIsSet (opcode, 9);
4695                 wback = BitIsSet (opcode, 8);
4696 
4697                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
4698                 if ((t == 15) || (wback && (n == t)))
4699                     return false;
4700                 break;
4701 
4702             default:
4703                 return false;
4704         }
4705 
4706         addr_t offset_addr;
4707         addr_t address;
4708 
4709         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4710         uint32_t base_address = ReadCoreReg (n, &success);
4711         if (!success)
4712             return false;
4713 
4714         if (add)
4715             offset_addr = base_address + imm32;
4716         else
4717             offset_addr = base_address - imm32;
4718 
4719         // address = if index then offset_addr else R[n];
4720         if (index)
4721             address = offset_addr;
4722         else
4723             address = base_address;
4724 
4725         EmulateInstruction::Context context;
4726         context.type = eContextRegisterStore;
4727         RegisterInfo base_reg;
4728         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4729 
4730         // if UnalignedSupport() || address<1:0> == '00' then
4731         if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
4732         {
4733             // MemU[address,4] = R[t];
4734             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4735             if (!success)
4736                 return false;
4737 
4738             RegisterInfo data_reg;
4739             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4740             int32_t offset = address - base_address;
4741             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4742             if (!MemUWrite (context, address, data, addr_byte_size))
4743                 return false;
4744         }
4745         else
4746         {
4747             // MemU[address,4] = bits(32) UNKNOWN;
4748             WriteBits32UnknownToMemory (address);
4749         }
4750 
4751         // if wback then R[n] = offset_addr;
4752         if (wback)
4753         {
4754             context.type = eContextRegisterLoad;
4755             context.SetAddress (offset_addr);
4756             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4757                 return false;
4758         }
4759     }
4760     return true;
4761 }
4762 
4763 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a
4764 // word from a register to memory.   The offset register value can optionally be shifted.
4765 bool
4766 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding)
4767 {
4768 #if 0
4769     if ConditionPassed() then
4770         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4771         offset = Shift(R[m], shift_t, shift_n, APSR.C);
4772         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4773         address = if index then offset_addr else R[n];
4774         if t == 15 then // Only possible for encoding A1
4775             data = PCStoreValue();
4776         else
4777             data = R[t];
4778         if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4779             MemU[address,4] = data;
4780         else // Can only occur before ARMv7
4781             MemU[address,4] = bits(32) UNKNOWN;
4782         if wback then R[n] = offset_addr;
4783 #endif
4784 
4785     bool success = false;
4786 
4787     if (ConditionPassed(opcode))
4788     {
4789         const uint32_t addr_byte_size = GetAddressByteSize();
4790 
4791         uint32_t t;
4792         uint32_t n;
4793         uint32_t m;
4794         ARM_ShifterType shift_t;
4795         uint32_t shift_n;
4796         bool index;
4797         bool add;
4798         bool wback;
4799 
4800         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4801         switch (encoding)
4802         {
4803             case eEncodingT1:
4804                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4805                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4806                 t = Bits32 (opcode, 2, 0);
4807                 n = Bits32 (opcode, 5, 3);
4808                 m = Bits32 (opcode, 8, 6);
4809 
4810                 // index = TRUE; add = TRUE; wback = FALSE;
4811                 index = true;
4812                 add = true;
4813                 wback = false;
4814 
4815                 // (shift_t, shift_n) = (SRType_LSL, 0);
4816                 shift_t = SRType_LSL;
4817                 shift_n = 0;
4818                 break;
4819 
4820             case eEncodingT2:
4821                 // if Rn == '1111' then UNDEFINED;
4822                 if (Bits32 (opcode, 19, 16) == 15)
4823                     return false;
4824 
4825                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4826                 t = Bits32 (opcode, 15, 12);
4827                 n = Bits32 (opcode, 19, 16);
4828                 m = Bits32 (opcode, 3, 0);
4829 
4830                 // index = TRUE; add = TRUE; wback = FALSE;
4831                 index = true;
4832                 add = true;
4833                 wback = false;
4834 
4835                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4836                 shift_t = SRType_LSL;
4837                 shift_n = Bits32 (opcode, 5, 4);
4838 
4839                 // if t == 15 || BadReg(m) then UNPREDICTABLE;
4840                 if ((t == 15) || (BadReg (m)))
4841                     return false;
4842                 break;
4843 
4844             case eEncodingA1:
4845             {
4846                 // if P == '0' && W == '1' then SEE STRT;
4847                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4848                 t = Bits32 (opcode, 15, 12);
4849                 n = Bits32 (opcode, 19, 16);
4850                 m = Bits32 (opcode, 3, 0);
4851 
4852                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
4853                 index = BitIsSet (opcode, 24);
4854                 add = BitIsSet (opcode, 23);
4855                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
4856 
4857                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
4858                 uint32_t typ = Bits32 (opcode, 6, 5);
4859                 uint32_t imm5 = Bits32 (opcode, 11, 7);
4860                 shift_n = DecodeImmShift(typ, imm5, shift_t);
4861 
4862                 // if m == 15 then UNPREDICTABLE;
4863                 if (m == 15)
4864                     return false;
4865 
4866                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
4867                 if (wback && ((n == 15) || (n == t)))
4868                     return false;
4869 
4870                 break;
4871             }
4872             default:
4873                 return false;
4874         }
4875 
4876         addr_t offset_addr;
4877         addr_t address;
4878         int32_t offset = 0;
4879 
4880         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4881         if (!success)
4882             return false;
4883 
4884         uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
4885         if (!success)
4886             return false;
4887 
4888         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4889         offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success);
4890         if (!success)
4891             return false;
4892 
4893         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4894         if (add)
4895             offset_addr = base_address + offset;
4896         else
4897             offset_addr = base_address - offset;
4898 
4899         // address = if index then offset_addr else R[n];
4900         if (index)
4901             address = offset_addr;
4902         else
4903             address = base_address;
4904 
4905         uint32_t data;
4906         // if t == 15 then // Only possible for encoding A1
4907         if (t == 15)
4908             // data = PCStoreValue();
4909             data = ReadCoreReg (PC_REG, &success);
4910         else
4911             // data = R[t];
4912             data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4913 
4914         if (!success)
4915             return false;
4916 
4917         EmulateInstruction::Context context;
4918         context.type = eContextRegisterStore;
4919 
4920         // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4921         if (UnalignedSupport ()
4922             || (BitIsClear (address, 1) && BitIsClear (address, 0))
4923             || CurrentInstrSet() == eModeARM)
4924         {
4925             // MemU[address,4] = data;
4926 
4927             RegisterInfo base_reg;
4928             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 +  n, base_reg);
4929 
4930             RegisterInfo data_reg;
4931             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4932 
4933             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4934             if (!MemUWrite (context, address, data, addr_byte_size))
4935                 return false;
4936 
4937         }
4938         else
4939             // MemU[address,4] = bits(32) UNKNOWN;
4940             WriteBits32UnknownToMemory (address);
4941 
4942         // if wback then R[n] = offset_addr;
4943         if (wback)
4944         {
4945             context.type = eContextRegisterLoad;
4946             context.SetAddress (offset_addr);
4947             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4948                 return false;
4949         }
4950 
4951     }
4952     return true;
4953 }
4954 
4955 bool
4956 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding)
4957 {
4958 #if 0
4959     if ConditionPassed() then
4960         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4961         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4962         address = if index then offset_addr else R[n];
4963         MemU[address,1] = R[t]<7:0>;
4964         if wback then R[n] = offset_addr;
4965 #endif
4966 
4967 
4968     bool success = false;
4969 
4970     if (ConditionPassed(opcode))
4971     {
4972         uint32_t t;
4973         uint32_t n;
4974         uint32_t imm32;
4975         bool index;
4976         bool add;
4977         bool wback;
4978         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4979         switch (encoding)
4980         {
4981             case eEncodingT1:
4982                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
4983                 t = Bits32 (opcode, 2, 0);
4984                 n = Bits32 (opcode, 5, 3);
4985                 imm32 = Bits32 (opcode, 10, 6);
4986 
4987                 // index = TRUE; add = TRUE; wback = FALSE;
4988                 index = true;
4989                 add = true;
4990                 wback = false;
4991                 break;
4992 
4993             case eEncodingT2:
4994                 // if Rn == '1111' then UNDEFINED;
4995                 if (Bits32 (opcode, 19, 16) == 15)
4996                     return false;
4997 
4998                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4999                 t = Bits32 (opcode, 15, 12);
5000                 n = Bits32 (opcode, 19, 16);
5001                 imm32 = Bits32 (opcode, 11, 0);
5002 
5003                 // index = TRUE; add = TRUE; wback = FALSE;
5004                 index = true;
5005                 add = true;
5006                 wback = false;
5007 
5008                 // if BadReg(t) then UNPREDICTABLE;
5009                 if (BadReg (t))
5010                     return false;
5011                 break;
5012 
5013             case eEncodingT3:
5014                 // if P == '1' && U == '1' && W == '0' then SEE STRBT;
5015                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5016                 if (Bits32 (opcode, 19, 16) == 15)
5017                     return false;
5018 
5019                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5020                 t = Bits32 (opcode, 15, 12);
5021                 n = Bits32 (opcode, 19, 16);
5022                 imm32 = Bits32 (opcode, 7, 0);
5023 
5024                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5025                 index = BitIsSet (opcode, 10);
5026                 add = BitIsSet (opcode, 9);
5027                 wback = BitIsSet (opcode, 8);
5028 
5029                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
5030                 if ((BadReg (t)) || (wback && (n == t)))
5031                     return false;
5032                 break;
5033 
5034             default:
5035                 return false;
5036         }
5037 
5038         addr_t offset_addr;
5039         addr_t address;
5040         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5041         if (!success)
5042             return false;
5043 
5044         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5045         if (add)
5046             offset_addr = base_address + imm32;
5047         else
5048             offset_addr = base_address - imm32;
5049 
5050         // address = if index then offset_addr else R[n];
5051         if (index)
5052             address = offset_addr;
5053         else
5054             address = base_address;
5055 
5056         // MemU[address,1] = R[t]<7:0>
5057         RegisterInfo base_reg;
5058         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5059 
5060         RegisterInfo data_reg;
5061         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5062 
5063         EmulateInstruction::Context context;
5064         context.type = eContextRegisterStore;
5065         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
5066 
5067         uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5068         if (!success)
5069             return false;
5070 
5071         data = Bits32 (data, 7, 0);
5072 
5073         if (!MemUWrite (context, address, data, 1))
5074             return false;
5075 
5076         // if wback then R[n] = offset_addr;
5077         if (wback)
5078         {
5079             context.type = eContextRegisterLoad;
5080             context.SetAddress (offset_addr);
5081             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5082                 return false;
5083         }
5084 
5085     }
5086 
5087     return true;
5088 }
5089 
5090 // STRH (register) calculates an address from a base register value and an offset register value, and stores a
5091 // halfword from a register to memory.  The offset register value can be shifted left by 0, 1, 2, or 3 bits.
5092 bool
5093 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding)
5094 {
5095 #if 0
5096     if ConditionPassed() then
5097         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5098         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5099         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5100         address = if index then offset_addr else R[n];
5101         if UnalignedSupport() || address<0> == '0' then
5102             MemU[address,2] = R[t]<15:0>;
5103         else // Can only occur before ARMv7
5104             MemU[address,2] = bits(16) UNKNOWN;
5105         if wback then R[n] = offset_addr;
5106 #endif
5107 
5108     bool success = false;
5109 
5110     if (ConditionPassed(opcode))
5111     {
5112         uint32_t t;
5113         uint32_t n;
5114         uint32_t m;
5115         bool index;
5116         bool add;
5117         bool wback;
5118         ARM_ShifterType shift_t;
5119         uint32_t shift_n;
5120 
5121         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5122         switch (encoding)
5123         {
5124             case eEncodingT1:
5125                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5126                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5127                 t = Bits32 (opcode, 2, 0);
5128                 n = Bits32 (opcode, 5, 3);
5129                 m = Bits32 (opcode, 8, 6);
5130 
5131                 // index = TRUE; add = TRUE; wback = FALSE;
5132                 index = true;
5133                 add = true;
5134                 wback = false;
5135 
5136                 // (shift_t, shift_n) = (SRType_LSL, 0);
5137                 shift_t = SRType_LSL;
5138                 shift_n = 0;
5139 
5140                 break;
5141 
5142             case eEncodingT2:
5143                 // if Rn == '1111' then UNDEFINED;
5144                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5145                 t = Bits32 (opcode, 15, 12);
5146                 n = Bits32 (opcode, 19, 16);
5147                 m = Bits32 (opcode, 3, 0);
5148                 if (n == 15)
5149                     return false;
5150 
5151                 // index = TRUE; add = TRUE; wback = FALSE;
5152                 index = true;
5153                 add = true;
5154                 wback = false;
5155 
5156                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5157                 shift_t = SRType_LSL;
5158                 shift_n = Bits32 (opcode, 5, 4);
5159 
5160                 // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5161                 if (BadReg (t) || BadReg (m))
5162                     return false;
5163 
5164                 break;
5165 
5166             case eEncodingA1:
5167                 // if P == '0' && W == '1' then SEE STRHT;
5168                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5169                 t = Bits32 (opcode, 15, 12);
5170                 n = Bits32 (opcode, 19, 16);
5171                 m = Bits32 (opcode, 3, 0);
5172 
5173                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5174                 index = BitIsSet (opcode, 24);
5175                 add = BitIsSet (opcode, 23);
5176                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5177 
5178                 // (shift_t, shift_n) = (SRType_LSL, 0);
5179                 shift_t = SRType_LSL;
5180                 shift_n = 0;
5181 
5182                 // if t == 15 || m == 15 then UNPREDICTABLE;
5183                 if ((t == 15) || (m == 15))
5184                     return false;
5185 
5186                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5187                 if (wback && ((n == 15) || (n == t)))
5188                     return false;
5189 
5190                 break;
5191 
5192             default:
5193                 return false;
5194         }
5195 
5196         uint32_t Rm = ReadCoreReg (m, &success);
5197         if (!success)
5198             return false;
5199 
5200         uint32_t Rn = ReadCoreReg (n, &success);
5201         if (!success)
5202             return false;
5203 
5204         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5205         uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
5206         if (!success)
5207             return false;
5208 
5209         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5210         addr_t offset_addr;
5211         if (add)
5212             offset_addr = Rn + offset;
5213         else
5214             offset_addr = Rn - offset;
5215 
5216         // address = if index then offset_addr else R[n];
5217         addr_t address;
5218         if (index)
5219             address = offset_addr;
5220         else
5221             address = Rn;
5222 
5223         EmulateInstruction::Context context;
5224         context.type = eContextRegisterStore;
5225         RegisterInfo base_reg;
5226         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5227         RegisterInfo offset_reg;
5228         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5229 
5230         // if UnalignedSupport() || address<0> == '0' then
5231         if (UnalignedSupport() || BitIsClear (address, 0))
5232         {
5233             // MemU[address,2] = R[t]<15:0>;
5234             uint32_t Rt = ReadCoreReg (t, &success);
5235             if (!success)
5236                 return false;
5237 
5238             EmulateInstruction::Context context;
5239             context.type = eContextRegisterStore;
5240             RegisterInfo base_reg;
5241             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5242             RegisterInfo offset_reg;
5243             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5244             RegisterInfo data_reg;
5245             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5246             context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
5247 
5248             if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2))
5249                 return false;
5250         }
5251         else // Can only occur before ARMv7
5252         {
5253             // MemU[address,2] = bits(16) UNKNOWN;
5254         }
5255 
5256         // if wback then R[n] = offset_addr;
5257         if (wback)
5258         {
5259             context.type = eContextAdjustBaseRegister;
5260             context.SetAddress (offset_addr);
5261             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5262                 return false;
5263         }
5264     }
5265 
5266     return true;
5267 }
5268 
5269 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value,
5270 // and writes the result to the destination register.  It can optionally update the condition flags
5271 // based on the result.
5272 bool
5273 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding)
5274 {
5275 #if 0
5276     // ARM pseudo code...
5277     if ConditionPassed() then
5278         EncodingSpecificOperations();
5279         (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5280         if d == 15 then         // Can only occur for ARM encoding
5281             ALUWritePC(result); // setflags is always FALSE here
5282         else
5283             R[d] = result;
5284             if setflags then
5285                 APSR.N = result<31>;
5286                 APSR.Z = IsZeroBit(result);
5287                 APSR.C = carry;
5288                 APSR.V = overflow;
5289 #endif
5290 
5291     bool success = false;
5292 
5293     if (ConditionPassed(opcode))
5294     {
5295         uint32_t Rd, Rn;
5296         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
5297         bool setflags;
5298         switch (encoding)
5299         {
5300         case eEncodingT1:
5301             Rd = Bits32(opcode, 11, 8);
5302             Rn = Bits32(opcode, 19, 16);
5303             setflags = BitIsSet(opcode, 20);
5304             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5305             if (BadReg(Rd) || BadReg(Rn))
5306                 return false;
5307             break;
5308         case eEncodingA1:
5309             Rd = Bits32(opcode, 15, 12);
5310             Rn = Bits32(opcode, 19, 16);
5311             setflags = BitIsSet(opcode, 20);
5312             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5313 
5314             if (Rd == 15 && setflags)
5315                 return EmulateSUBSPcLrEtc (opcode, encoding);
5316             break;
5317         default:
5318             return false;
5319         }
5320 
5321         // Read the first operand.
5322         int32_t val1 = ReadCoreReg(Rn, &success);
5323         if (!success)
5324             return false;
5325 
5326         AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5327 
5328         EmulateInstruction::Context context;
5329         context.type = EmulateInstruction::eContextImmediate;
5330         context.SetNoArgs ();
5331 
5332         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5333             return false;
5334     }
5335     return true;
5336 }
5337 
5338 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted
5339 // register value, and writes the result to the destination register.  It can optionally update the
5340 // condition flags based on the result.
5341 bool
5342 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding)
5343 {
5344 #if 0
5345     // ARM pseudo code...
5346     if ConditionPassed() then
5347         EncodingSpecificOperations();
5348         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5349         (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5350         if d == 15 then         // Can only occur for ARM encoding
5351             ALUWritePC(result); // setflags is always FALSE here
5352         else
5353             R[d] = result;
5354             if setflags then
5355                 APSR.N = result<31>;
5356                 APSR.Z = IsZeroBit(result);
5357                 APSR.C = carry;
5358                 APSR.V = overflow;
5359 #endif
5360 
5361     bool success = false;
5362 
5363     if (ConditionPassed(opcode))
5364     {
5365         uint32_t Rd, Rn, Rm;
5366         ARM_ShifterType shift_t;
5367         uint32_t shift_n; // the shift applied to the value read from Rm
5368         bool setflags;
5369         switch (encoding)
5370         {
5371         case eEncodingT1:
5372             Rd = Rn = Bits32(opcode, 2, 0);
5373             Rm = Bits32(opcode, 5, 3);
5374             setflags = !InITBlock();
5375             shift_t = SRType_LSL;
5376             shift_n = 0;
5377             break;
5378         case eEncodingT2:
5379             Rd = Bits32(opcode, 11, 8);
5380             Rn = Bits32(opcode, 19, 16);
5381             Rm = Bits32(opcode, 3, 0);
5382             setflags = BitIsSet(opcode, 20);
5383             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5384             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5385                 return false;
5386             break;
5387         case eEncodingA1:
5388             Rd = Bits32(opcode, 15, 12);
5389             Rn = Bits32(opcode, 19, 16);
5390             Rm = Bits32(opcode, 3, 0);
5391             setflags = BitIsSet(opcode, 20);
5392             shift_n = DecodeImmShiftARM(opcode, shift_t);
5393 
5394             if (Rd == 15 && setflags)
5395                 return EmulateSUBSPcLrEtc (opcode, encoding);
5396             break;
5397         default:
5398             return false;
5399         }
5400 
5401         // Read the first operand.
5402         int32_t val1 = ReadCoreReg(Rn, &success);
5403         if (!success)
5404             return false;
5405 
5406         // Read the second operand.
5407         int32_t val2 = ReadCoreReg(Rm, &success);
5408         if (!success)
5409             return false;
5410 
5411         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5412         if (!success)
5413             return false;
5414         AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5415 
5416         EmulateInstruction::Context context;
5417         context.type = EmulateInstruction::eContextImmediate;
5418         context.SetNoArgs ();
5419 
5420         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5421             return false;
5422     }
5423     return true;
5424 }
5425 
5426 // This instruction adds an immediate value to the PC value to form a PC-relative address,
5427 // and writes the result to the destination register.
5428 bool
5429 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding)
5430 {
5431 #if 0
5432     // ARM pseudo code...
5433     if ConditionPassed() then
5434         EncodingSpecificOperations();
5435         result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5436         if d == 15 then         // Can only occur for ARM encodings
5437             ALUWritePC(result);
5438         else
5439             R[d] = result;
5440 #endif
5441 
5442     bool success = false;
5443 
5444     if (ConditionPassed(opcode))
5445     {
5446         uint32_t Rd;
5447         uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5448         bool add;
5449         switch (encoding)
5450         {
5451         case eEncodingT1:
5452             Rd = Bits32(opcode, 10, 8);
5453             imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5454             add = true;
5455             break;
5456         case eEncodingT2:
5457         case eEncodingT3:
5458             Rd = Bits32(opcode, 11, 8);
5459             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5460             add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5461             if (BadReg(Rd))
5462                 return false;
5463             break;
5464         case eEncodingA1:
5465         case eEncodingA2:
5466             Rd = Bits32(opcode, 15, 12);
5467             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5468             add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5469             break;
5470         default:
5471             return false;
5472         }
5473 
5474         // Read the PC value.
5475         uint32_t pc = ReadCoreReg(PC_REG, &success);
5476         if (!success)
5477             return false;
5478 
5479         uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5480 
5481         EmulateInstruction::Context context;
5482         context.type = EmulateInstruction::eContextImmediate;
5483         context.SetNoArgs ();
5484 
5485         if (!WriteCoreReg(context, result, Rd))
5486             return false;
5487     }
5488     return true;
5489 }
5490 
5491 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result
5492 // to the destination register.  It can optionally update the condition flags based on the result.
5493 bool
5494 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding)
5495 {
5496 #if 0
5497     // ARM pseudo code...
5498     if ConditionPassed() then
5499         EncodingSpecificOperations();
5500         result = R[n] AND imm32;
5501         if d == 15 then         // Can only occur for ARM encoding
5502             ALUWritePC(result); // setflags is always FALSE here
5503         else
5504             R[d] = result;
5505             if setflags then
5506                 APSR.N = result<31>;
5507                 APSR.Z = IsZeroBit(result);
5508                 APSR.C = carry;
5509                 // APSR.V unchanged
5510 #endif
5511 
5512     bool success = false;
5513 
5514     if (ConditionPassed(opcode))
5515     {
5516         uint32_t Rd, Rn;
5517         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
5518         bool setflags;
5519         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5520         switch (encoding)
5521         {
5522         case eEncodingT1:
5523             Rd = Bits32(opcode, 11, 8);
5524             Rn = Bits32(opcode, 19, 16);
5525             setflags = BitIsSet(opcode, 20);
5526             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5527             // if Rd == '1111' && S == '1' then SEE TST (immediate);
5528             if (Rd == 15 && setflags)
5529                 return EmulateTSTImm(opcode, eEncodingT1);
5530             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
5531                 return false;
5532             break;
5533         case eEncodingA1:
5534             Rd = Bits32(opcode, 15, 12);
5535             Rn = Bits32(opcode, 19, 16);
5536             setflags = BitIsSet(opcode, 20);
5537             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5538 
5539             if (Rd == 15 && setflags)
5540                 return EmulateSUBSPcLrEtc (opcode, encoding);
5541             break;
5542         default:
5543             return false;
5544         }
5545 
5546         // Read the first operand.
5547         uint32_t val1 = ReadCoreReg(Rn, &success);
5548         if (!success)
5549             return false;
5550 
5551         uint32_t result = val1 & imm32;
5552 
5553         EmulateInstruction::Context context;
5554         context.type = EmulateInstruction::eContextImmediate;
5555         context.SetNoArgs ();
5556 
5557         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5558             return false;
5559     }
5560     return true;
5561 }
5562 
5563 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value,
5564 // and writes the result to the destination register.  It can optionally update the condition flags
5565 // based on the result.
5566 bool
5567 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding)
5568 {
5569 #if 0
5570     // ARM pseudo code...
5571     if ConditionPassed() then
5572         EncodingSpecificOperations();
5573         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5574         result = R[n] AND shifted;
5575         if d == 15 then         // Can only occur for ARM encoding
5576             ALUWritePC(result); // setflags is always FALSE here
5577         else
5578             R[d] = result;
5579             if setflags then
5580                 APSR.N = result<31>;
5581                 APSR.Z = IsZeroBit(result);
5582                 APSR.C = carry;
5583                 // APSR.V unchanged
5584 #endif
5585 
5586     bool success = false;
5587 
5588     if (ConditionPassed(opcode))
5589     {
5590         uint32_t Rd, Rn, Rm;
5591         ARM_ShifterType shift_t;
5592         uint32_t shift_n; // the shift applied to the value read from Rm
5593         bool setflags;
5594         uint32_t carry;
5595         switch (encoding)
5596         {
5597         case eEncodingT1:
5598             Rd = Rn = Bits32(opcode, 2, 0);
5599             Rm = Bits32(opcode, 5, 3);
5600             setflags = !InITBlock();
5601             shift_t = SRType_LSL;
5602             shift_n = 0;
5603             break;
5604         case eEncodingT2:
5605             Rd = Bits32(opcode, 11, 8);
5606             Rn = Bits32(opcode, 19, 16);
5607             Rm = Bits32(opcode, 3, 0);
5608             setflags = BitIsSet(opcode, 20);
5609             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5610             // if Rd == '1111' && S == '1' then SEE TST (register);
5611             if (Rd == 15 && setflags)
5612                 return EmulateTSTReg(opcode, eEncodingT2);
5613             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
5614                 return false;
5615             break;
5616         case eEncodingA1:
5617             Rd = Bits32(opcode, 15, 12);
5618             Rn = Bits32(opcode, 19, 16);
5619             Rm = Bits32(opcode, 3, 0);
5620             setflags = BitIsSet(opcode, 20);
5621             shift_n = DecodeImmShiftARM(opcode, shift_t);
5622 
5623             if (Rd == 15 && setflags)
5624                 return EmulateSUBSPcLrEtc (opcode, encoding);
5625             break;
5626         default:
5627             return false;
5628         }
5629 
5630         // Read the first operand.
5631         uint32_t val1 = ReadCoreReg(Rn, &success);
5632         if (!success)
5633             return false;
5634 
5635         // Read the second operand.
5636         uint32_t val2 = ReadCoreReg(Rm, &success);
5637         if (!success)
5638             return false;
5639 
5640         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5641         if (!success)
5642             return false;
5643         uint32_t result = val1 & shifted;
5644 
5645         EmulateInstruction::Context context;
5646         context.type = EmulateInstruction::eContextImmediate;
5647         context.SetNoArgs ();
5648 
5649         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5650             return false;
5651     }
5652     return true;
5653 }
5654 
5655 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an
5656 // immediate value, and writes the result to the destination register.  It can optionally update the
5657 // condition flags based on the result.
5658 bool
5659 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding)
5660 {
5661 #if 0
5662     // ARM pseudo code...
5663     if ConditionPassed() then
5664         EncodingSpecificOperations();
5665         result = R[n] AND NOT(imm32);
5666         if d == 15 then         // Can only occur for ARM encoding
5667             ALUWritePC(result); // setflags is always FALSE here
5668         else
5669             R[d] = result;
5670             if setflags then
5671                 APSR.N = result<31>;
5672                 APSR.Z = IsZeroBit(result);
5673                 APSR.C = carry;
5674                 // APSR.V unchanged
5675 #endif
5676 
5677     bool success = false;
5678 
5679     if (ConditionPassed(opcode))
5680     {
5681         uint32_t Rd, Rn;
5682         uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn
5683         bool setflags;
5684         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5685         switch (encoding)
5686         {
5687         case eEncodingT1:
5688             Rd = Bits32(opcode, 11, 8);
5689             Rn = Bits32(opcode, 19, 16);
5690             setflags = BitIsSet(opcode, 20);
5691             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5692             if (BadReg(Rd) || BadReg(Rn))
5693                 return false;
5694             break;
5695         case eEncodingA1:
5696             Rd = Bits32(opcode, 15, 12);
5697             Rn = Bits32(opcode, 19, 16);
5698             setflags = BitIsSet(opcode, 20);
5699             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5700 
5701             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5702             if (Rd == 15 && setflags)
5703                 return EmulateSUBSPcLrEtc (opcode, encoding);
5704             break;
5705         default:
5706             return false;
5707         }
5708 
5709         // Read the first operand.
5710         uint32_t val1 = ReadCoreReg(Rn, &success);
5711         if (!success)
5712             return false;
5713 
5714         uint32_t result = val1 & ~imm32;
5715 
5716         EmulateInstruction::Context context;
5717         context.type = EmulateInstruction::eContextImmediate;
5718         context.SetNoArgs ();
5719 
5720         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5721             return false;
5722     }
5723     return true;
5724 }
5725 
5726 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an
5727 // optionally-shifted register value, and writes the result to the destination register.
5728 // It can optionally update the condition flags based on the result.
5729 bool
5730 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding)
5731 {
5732 #if 0
5733     // ARM pseudo code...
5734     if ConditionPassed() then
5735         EncodingSpecificOperations();
5736         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5737         result = R[n] AND NOT(shifted);
5738         if d == 15 then         // Can only occur for ARM encoding
5739             ALUWritePC(result); // setflags is always FALSE here
5740         else
5741             R[d] = result;
5742             if setflags then
5743                 APSR.N = result<31>;
5744                 APSR.Z = IsZeroBit(result);
5745                 APSR.C = carry;
5746                 // APSR.V unchanged
5747 #endif
5748 
5749     bool success = false;
5750 
5751     if (ConditionPassed(opcode))
5752     {
5753         uint32_t Rd, Rn, Rm;
5754         ARM_ShifterType shift_t;
5755         uint32_t shift_n; // the shift applied to the value read from Rm
5756         bool setflags;
5757         uint32_t carry;
5758         switch (encoding)
5759         {
5760         case eEncodingT1:
5761             Rd = Rn = Bits32(opcode, 2, 0);
5762             Rm = Bits32(opcode, 5, 3);
5763             setflags = !InITBlock();
5764             shift_t = SRType_LSL;
5765             shift_n = 0;
5766             break;
5767         case eEncodingT2:
5768             Rd = Bits32(opcode, 11, 8);
5769             Rn = Bits32(opcode, 19, 16);
5770             Rm = Bits32(opcode, 3, 0);
5771             setflags = BitIsSet(opcode, 20);
5772             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5773             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5774                 return false;
5775             break;
5776         case eEncodingA1:
5777             Rd = Bits32(opcode, 15, 12);
5778             Rn = Bits32(opcode, 19, 16);
5779             Rm = Bits32(opcode, 3, 0);
5780             setflags = BitIsSet(opcode, 20);
5781             shift_n = DecodeImmShiftARM(opcode, shift_t);
5782 
5783             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5784             if (Rd == 15 && setflags)
5785                 return EmulateSUBSPcLrEtc (opcode, encoding);
5786             break;
5787         default:
5788             return false;
5789         }
5790 
5791         // Read the first operand.
5792         uint32_t val1 = ReadCoreReg(Rn, &success);
5793         if (!success)
5794             return false;
5795 
5796         // Read the second operand.
5797         uint32_t val2 = ReadCoreReg(Rm, &success);
5798         if (!success)
5799             return false;
5800 
5801         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5802         if (!success)
5803             return false;
5804         uint32_t result = val1 & ~shifted;
5805 
5806         EmulateInstruction::Context context;
5807         context.type = EmulateInstruction::eContextImmediate;
5808         context.SetNoArgs ();
5809 
5810         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5811             return false;
5812     }
5813     return true;
5814 }
5815 
5816 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
5817 // from memory, and writes it to a register.  It can use offset, post-indexed, or pre-indexed addressing.
5818 bool
5819 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding)
5820 {
5821 #if 0
5822     if ConditionPassed() then
5823         EncodingSpecificOperations();
5824         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5825         address = if index then offset_addr else R[n];
5826         data = MemU[address,4];
5827         if wback then R[n] = offset_addr;
5828         if t == 15 then
5829             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5830         elsif UnalignedSupport() || address<1:0> = '00' then
5831             R[t] = data;
5832         else // Can only apply before ARMv7
5833             R[t] = ROR(data, 8*UInt(address<1:0>));
5834 #endif
5835 
5836     bool success = false;
5837 
5838     if (ConditionPassed(opcode))
5839     {
5840         const uint32_t addr_byte_size = GetAddressByteSize();
5841 
5842         uint32_t t;
5843         uint32_t n;
5844         uint32_t imm32;
5845         bool index;
5846         bool add;
5847         bool wback;
5848 
5849         switch (encoding)
5850         {
5851             case eEncodingA1:
5852                 // if Rn == '1111' then SEE LDR (literal);
5853                 // if P == '0' && W == '1' then SEE LDRT;
5854                 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP;
5855                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5856                 t = Bits32 (opcode, 15, 12);
5857                 n = Bits32 (opcode, 19, 16);
5858                 imm32 = Bits32 (opcode, 11, 0);
5859 
5860                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5861                 index = BitIsSet (opcode, 24);
5862                 add = BitIsSet (opcode, 23);
5863                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5864 
5865                 // if wback && n == t then UNPREDICTABLE;
5866                 if (wback && (n == t))
5867                     return false;
5868 
5869                 break;
5870 
5871             default:
5872                 return false;
5873         }
5874 
5875         addr_t address;
5876         addr_t offset_addr;
5877         addr_t base_address = ReadCoreReg (n, &success);
5878         if (!success)
5879             return false;
5880 
5881         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5882         if (add)
5883             offset_addr = base_address + imm32;
5884         else
5885             offset_addr = base_address - imm32;
5886 
5887         // address = if index then offset_addr else R[n];
5888         if (index)
5889             address = offset_addr;
5890         else
5891             address = base_address;
5892 
5893         // data = MemU[address,4];
5894 
5895         RegisterInfo base_reg;
5896         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5897 
5898         EmulateInstruction::Context context;
5899         context.type = eContextRegisterLoad;
5900         context.SetRegisterPlusOffset (base_reg, address - base_address);
5901 
5902         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5903         if (!success)
5904             return false;
5905 
5906         // if wback then R[n] = offset_addr;
5907         if (wback)
5908         {
5909             context.type = eContextAdjustBaseRegister;
5910             context.SetAddress (offset_addr);
5911             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5912                 return false;
5913         }
5914 
5915         // if t == 15 then
5916         if (t == 15)
5917         {
5918             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5919             if (BitIsClear (address, 1) && BitIsClear (address, 0))
5920             {
5921                 // LoadWritePC (data);
5922                 context.type = eContextRegisterLoad;
5923                 context.SetRegisterPlusOffset (base_reg, address - base_address);
5924                 LoadWritePC (context, data);
5925             }
5926             else
5927                   return false;
5928         }
5929         // elsif UnalignedSupport() || address<1:0> = '00' then
5930         else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5931         {
5932             // R[t] = data;
5933             context.type = eContextRegisterLoad;
5934             context.SetRegisterPlusOffset (base_reg, address - base_address);
5935             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5936                 return false;
5937         }
5938         // else // Can only apply before ARMv7
5939         else
5940         {
5941             // R[t] = ROR(data, 8*UInt(address<1:0>));
5942             data = ROR (data, Bits32 (address, 1, 0), &success);
5943             if (!success)
5944                 return false;
5945             context.type = eContextRegisterLoad;
5946             context.SetImmediate (data);
5947             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5948                 return false;
5949         }
5950 
5951     }
5952     return true;
5953 }
5954 
5955 // LDR (register) calculates an address from a base register value and an offset register value, loads a word
5956 // from memory, and writes it to a register.  The offset register value can optionally be shifted.
5957 bool
5958 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding)
5959 {
5960 #if 0
5961     if ConditionPassed() then
5962         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5963         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5964         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5965         address = if index then offset_addr else R[n];
5966         data = MemU[address,4];
5967         if wback then R[n] = offset_addr;
5968         if t == 15 then
5969             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5970         elsif UnalignedSupport() || address<1:0> = '00' then
5971             R[t] = data;
5972         else // Can only apply before ARMv7
5973             if CurrentInstrSet() == InstrSet_ARM then
5974                 R[t] = ROR(data, 8*UInt(address<1:0>));
5975             else
5976                 R[t] = bits(32) UNKNOWN;
5977 #endif
5978 
5979     bool success = false;
5980 
5981     if (ConditionPassed(opcode))
5982     {
5983         const uint32_t addr_byte_size = GetAddressByteSize();
5984 
5985         uint32_t t;
5986         uint32_t n;
5987         uint32_t m;
5988         bool index;
5989         bool add;
5990         bool wback;
5991         ARM_ShifterType shift_t;
5992         uint32_t shift_n;
5993 
5994         switch (encoding)
5995         {
5996             case eEncodingT1:
5997                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5998                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5999                 t = Bits32 (opcode, 2, 0);
6000                 n = Bits32 (opcode, 5, 3);
6001                 m = Bits32 (opcode, 8, 6);
6002 
6003                 // index = TRUE; add = TRUE; wback = FALSE;
6004                 index = true;
6005                 add = true;
6006                 wback = false;
6007 
6008                 // (shift_t, shift_n) = (SRType_LSL, 0);
6009                 shift_t = SRType_LSL;
6010                 shift_n = 0;
6011 
6012                 break;
6013 
6014             case eEncodingT2:
6015                 // if Rn == '1111' then SEE LDR (literal);
6016                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6017                 t = Bits32 (opcode, 15, 12);
6018                 n = Bits32 (opcode, 19, 16);
6019                 m = Bits32 (opcode, 3, 0);
6020 
6021                 // index = TRUE; add = TRUE; wback = FALSE;
6022                 index = true;
6023                 add = true;
6024                 wback = false;
6025 
6026                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6027                 shift_t = SRType_LSL;
6028                 shift_n = Bits32 (opcode, 5, 4);
6029 
6030                 // if BadReg(m) then UNPREDICTABLE;
6031                 if (BadReg (m))
6032                     return false;
6033 
6034                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
6035                 if ((t == 15) && InITBlock() && !LastInITBlock())
6036                     return false;
6037 
6038                 break;
6039 
6040             case eEncodingA1:
6041             {
6042                 // if P == '0' && W == '1' then SEE LDRT;
6043                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6044                 t = Bits32 (opcode, 15, 12);
6045                 n = Bits32 (opcode, 19, 16);
6046                 m = Bits32 (opcode, 3, 0);
6047 
6048                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6049                 index = BitIsSet (opcode, 24);
6050                 add = BitIsSet (opcode, 23);
6051                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6052 
6053                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6054                 uint32_t type = Bits32 (opcode, 6, 5);
6055                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6056                 shift_n = DecodeImmShift (type, imm5, shift_t);
6057 
6058                 // if m == 15 then UNPREDICTABLE;
6059                 if (m == 15)
6060                     return false;
6061 
6062                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6063                 if (wback && ((n == 15) || (n == t)))
6064                     return false;
6065             }
6066                 break;
6067 
6068 
6069             default:
6070                 return false;
6071         }
6072 
6073         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6074         if (!success)
6075             return false;
6076 
6077         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6078         if (!success)
6079             return false;
6080 
6081         addr_t offset_addr;
6082         addr_t address;
6083 
6084         // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an application level alias for the CPSR".
6085         addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success);
6086         if (!success)
6087             return false;
6088 
6089         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6090         if (add)
6091             offset_addr = Rn + offset;
6092         else
6093             offset_addr = Rn - offset;
6094 
6095         // address = if index then offset_addr else R[n];
6096             if (index)
6097                 address = offset_addr;
6098             else
6099                 address = Rn;
6100 
6101         // data = MemU[address,4];
6102         RegisterInfo base_reg;
6103         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6104 
6105         EmulateInstruction::Context context;
6106         context.type = eContextRegisterLoad;
6107         context.SetRegisterPlusOffset (base_reg, address - Rn);
6108 
6109         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
6110         if (!success)
6111             return false;
6112 
6113         // if wback then R[n] = offset_addr;
6114         if (wback)
6115         {
6116             context.type = eContextAdjustBaseRegister;
6117             context.SetAddress (offset_addr);
6118             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6119                 return false;
6120         }
6121 
6122         // if t == 15 then
6123         if (t == 15)
6124         {
6125             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6126             if (BitIsClear (address, 1) && BitIsClear (address, 0))
6127             {
6128                 context.type = eContextRegisterLoad;
6129                 context.SetRegisterPlusOffset (base_reg, address - Rn);
6130                 LoadWritePC (context, data);
6131             }
6132             else
6133                 return false;
6134         }
6135         // elsif UnalignedSupport() || address<1:0> = '00' then
6136         else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
6137         {
6138             // R[t] = data;
6139             context.type = eContextRegisterLoad;
6140             context.SetRegisterPlusOffset (base_reg, address - Rn);
6141             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6142                 return false;
6143         }
6144         else // Can only apply before ARMv7
6145         {
6146             // if CurrentInstrSet() == InstrSet_ARM then
6147             if (CurrentInstrSet () == eModeARM)
6148             {
6149                 // R[t] = ROR(data, 8*UInt(address<1:0>));
6150                 data = ROR (data, Bits32 (address, 1, 0), &success);
6151                 if (!success)
6152                     return false;
6153                 context.type = eContextRegisterLoad;
6154                 context.SetImmediate (data);
6155                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6156                     return false;
6157             }
6158             else
6159             {
6160                 // R[t] = bits(32) UNKNOWN;
6161                 WriteBits32Unknown (t);
6162             }
6163         }
6164     }
6165     return true;
6166 }
6167 
6168 // LDRB (immediate, Thumb)
6169 bool
6170 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6171 {
6172 #if 0
6173     if ConditionPassed() then
6174         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6175         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6176         address = if index then offset_addr else R[n];
6177         R[t] = ZeroExtend(MemU[address,1], 32);
6178         if wback then R[n] = offset_addr;
6179 #endif
6180 
6181     bool success = false;
6182 
6183     if (ConditionPassed(opcode))
6184     {
6185         uint32_t t;
6186         uint32_t n;
6187         uint32_t imm32;
6188         bool index;
6189         bool add;
6190         bool wback;
6191 
6192         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6193         switch (encoding)
6194         {
6195             case eEncodingT1:
6196                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6197                 t = Bits32 (opcode, 2, 0);
6198                 n = Bits32 (opcode, 5, 3);
6199                 imm32 = Bits32 (opcode, 10, 6);
6200 
6201                 // index = TRUE; add = TRUE; wback = FALSE;
6202                 index = true;
6203                 add = true;
6204                 wback= false;
6205 
6206                 break;
6207 
6208             case eEncodingT2:
6209                 // if Rt == '1111' then SEE PLD;
6210                 // if Rn == '1111' then SEE LDRB (literal);
6211                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6212                 t = Bits32 (opcode, 15, 12);
6213                 n = Bits32 (opcode, 19, 16);
6214                 imm32 = Bits32 (opcode, 11, 0);
6215 
6216                 // index = TRUE; add = TRUE; wback = FALSE;
6217                 index = true;
6218                 add = true;
6219                 wback = false;
6220 
6221                 // if t == 13 then UNPREDICTABLE;
6222                 if (t == 13)
6223                     return false;
6224 
6225                 break;
6226 
6227             case eEncodingT3:
6228                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6229                 // if Rn == '1111' then SEE LDRB (literal);
6230                 // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6231                 // if P == '0' && W == '0' then UNDEFINED;
6232                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6233                     return false;
6234 
6235                   // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6236                 t = Bits32 (opcode, 15, 12);
6237                 n = Bits32 (opcode, 19, 16);
6238                 imm32 = Bits32 (opcode, 7, 0);
6239 
6240                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6241                 index = BitIsSet (opcode, 10);
6242                 add = BitIsSet (opcode, 9);
6243                 wback = BitIsSet (opcode, 8);
6244 
6245                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6246                 if (BadReg (t) || (wback && (n == t)))
6247                     return false;
6248 
6249                 break;
6250 
6251             default:
6252                 return false;
6253         }
6254 
6255         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6256         if (!success)
6257             return false;
6258 
6259         addr_t address;
6260         addr_t offset_addr;
6261 
6262         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6263         if (add)
6264             offset_addr = Rn + imm32;
6265         else
6266             offset_addr = Rn - imm32;
6267 
6268         // address = if index then offset_addr else R[n];
6269         if (index)
6270             address = offset_addr;
6271         else
6272             address = Rn;
6273 
6274         // R[t] = ZeroExtend(MemU[address,1], 32);
6275         RegisterInfo base_reg;
6276         RegisterInfo data_reg;
6277         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6278         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6279 
6280         EmulateInstruction::Context context;
6281         context.type = eContextRegisterLoad;
6282         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
6283 
6284         uint64_t data = MemURead (context, address, 1, 0, &success);
6285         if (!success)
6286             return false;
6287 
6288         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6289             return false;
6290 
6291         // if wback then R[n] = offset_addr;
6292         if (wback)
6293         {
6294             context.type = eContextAdjustBaseRegister;
6295             context.SetAddress (offset_addr);
6296             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6297                 return false;
6298         }
6299     }
6300     return true;
6301 }
6302 
6303 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6304 // zero-extends it to form a 32-bit word and writes it to a register.
6305 bool
6306 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6307 {
6308 #if 0
6309     if ConditionPassed() then
6310         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6311         base = Align(PC,4);
6312         address = if add then (base + imm32) else (base - imm32);
6313         R[t] = ZeroExtend(MemU[address,1], 32);
6314 #endif
6315 
6316     bool success = false;
6317 
6318     if (ConditionPassed(opcode))
6319     {
6320         uint32_t t;
6321         uint32_t imm32;
6322         bool add;
6323         switch (encoding)
6324         {
6325             case eEncodingT1:
6326                 // if Rt == '1111' then SEE PLD;
6327                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6328                 t = Bits32 (opcode, 15, 12);
6329                 imm32 = Bits32 (opcode, 11, 0);
6330                 add = BitIsSet (opcode, 23);
6331 
6332                 // if t == 13 then UNPREDICTABLE;
6333                 if (t == 13)
6334                     return false;
6335 
6336                 break;
6337 
6338             case eEncodingA1:
6339                 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6340                 t = Bits32 (opcode, 15, 12);
6341                 imm32 = Bits32 (opcode, 11, 0);
6342                 add = BitIsSet (opcode, 23);
6343 
6344                 // if t == 15 then UNPREDICTABLE;
6345                 if (t == 15)
6346                     return false;
6347                 break;
6348 
6349             default:
6350                 return false;
6351         }
6352 
6353         // base = Align(PC,4);
6354         uint32_t pc_val = ReadCoreReg (PC_REG, &success);
6355         if (!success)
6356             return false;
6357 
6358         uint32_t base = AlignPC (pc_val);
6359 
6360         addr_t address;
6361         // address = if add then (base + imm32) else (base - imm32);
6362         if (add)
6363             address = base + imm32;
6364         else
6365             address = base - imm32;
6366 
6367         // R[t] = ZeroExtend(MemU[address,1], 32);
6368         EmulateInstruction::Context context;
6369         context.type = eContextRelativeBranchImmediate;
6370         context.SetImmediate (address - base);
6371 
6372         uint64_t data = MemURead (context, address, 1, 0, &success);
6373         if (!success)
6374             return false;
6375 
6376         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6377             return false;
6378     }
6379     return true;
6380 }
6381 
6382 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from
6383 // memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6384 // optionally be shifted.
6385 bool
6386 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding)
6387 {
6388 #if 0
6389     if ConditionPassed() then
6390         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6391         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6392         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6393         address = if index then offset_addr else R[n];
6394         R[t] = ZeroExtend(MemU[address,1],32);
6395         if wback then R[n] = offset_addr;
6396 #endif
6397 
6398     bool success = false;
6399 
6400     if (ConditionPassed(opcode))
6401     {
6402         uint32_t t;
6403         uint32_t n;
6404         uint32_t m;
6405         bool index;
6406         bool add;
6407         bool wback;
6408         ARM_ShifterType shift_t;
6409         uint32_t shift_n;
6410 
6411         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6412         switch (encoding)
6413         {
6414             case eEncodingT1:
6415                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6416                 t = Bits32 (opcode, 2, 0);
6417                 n = Bits32 (opcode, 5, 3);
6418                 m = Bits32 (opcode, 8, 6);
6419 
6420                 // index = TRUE; add = TRUE; wback = FALSE;
6421                 index = true;
6422                 add = true;
6423                 wback = false;
6424 
6425                 // (shift_t, shift_n) = (SRType_LSL, 0);
6426                 shift_t = SRType_LSL;
6427                 shift_n = 0;
6428                 break;
6429 
6430             case eEncodingT2:
6431                 // if Rt == '1111' then SEE PLD;
6432                 // if Rn == '1111' then SEE LDRB (literal);
6433                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6434                 t = Bits32 (opcode, 15, 12);
6435                 n = Bits32 (opcode, 19, 16);
6436                 m = Bits32 (opcode, 3, 0);
6437 
6438                 // index = TRUE; add = TRUE; wback = FALSE;
6439                 index = true;
6440                 add = true;
6441                 wback = false;
6442 
6443                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6444                 shift_t = SRType_LSL;
6445                 shift_n = Bits32 (opcode, 5, 4);
6446 
6447                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6448                 if ((t == 13) || BadReg (m))
6449                     return false;
6450                 break;
6451 
6452             case eEncodingA1:
6453             {
6454                 // if P == '0' && W == '1' then SEE LDRBT;
6455                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6456                 t = Bits32 (opcode, 15, 12);
6457                 n = Bits32 (opcode, 19, 16);
6458                 m = Bits32 (opcode, 3, 0);
6459 
6460                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6461                 index = BitIsSet (opcode, 24);
6462                 add = BitIsSet (opcode, 23);
6463                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6464 
6465                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6466                 uint32_t type = Bits32 (opcode, 6, 5);
6467                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6468                 shift_n = DecodeImmShift (type, imm5, shift_t);
6469 
6470                 // if t == 15 || m == 15 then UNPREDICTABLE;
6471                 if ((t == 15) || (m == 15))
6472                     return false;
6473 
6474                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6475                 if (wback && ((n == 15) || (n == t)))
6476                     return false;
6477             }
6478                 break;
6479 
6480             default:
6481                 return false;
6482         }
6483 
6484         addr_t offset_addr;
6485         addr_t address;
6486 
6487         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6488         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6489         if (!success)
6490             return false;
6491 
6492         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6493         if (!success)
6494             return false;
6495 
6496         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6497         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6498         if (!success)
6499             return false;
6500 
6501         if (add)
6502             offset_addr = Rn + offset;
6503         else
6504             offset_addr = Rn - offset;
6505 
6506         // address = if index then offset_addr else R[n];
6507         if (index)
6508             address = offset_addr;
6509         else
6510             address = Rn;
6511 
6512         // R[t] = ZeroExtend(MemU[address,1],32);
6513         RegisterInfo base_reg;
6514         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6515 
6516         EmulateInstruction::Context context;
6517         context.type = eContextRegisterLoad;
6518         context.SetRegisterPlusOffset (base_reg, address - Rn);
6519 
6520         uint64_t data = MemURead (context, address, 1, 0, &success);
6521         if (!success)
6522             return false;
6523 
6524         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6525             return false;
6526 
6527         // if wback then R[n] = offset_addr;
6528         if (wback)
6529         {
6530             context.type = eContextAdjustBaseRegister;
6531             context.SetAddress (offset_addr);
6532             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6533                 return false;
6534         }
6535     }
6536     return true;
6537 }
6538 
6539 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a
6540 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register.  It can use offset,
6541 // post-indexed, or pre-indexed addressing.
6542 bool
6543 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding)
6544 {
6545 #if 0
6546     if ConditionPassed() then
6547         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6548         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6549         address = if index then offset_addr else R[n];
6550         data = MemU[address,2];
6551         if wback then R[n] = offset_addr;
6552         if UnalignedSupport() || address<0> = '0' then
6553             R[t] = ZeroExtend(data, 32);
6554         else // Can only apply before ARMv7
6555             R[t] = bits(32) UNKNOWN;
6556 #endif
6557 
6558 
6559     bool success = false;
6560 
6561     if (ConditionPassed(opcode))
6562     {
6563         uint32_t t;
6564         uint32_t n;
6565         uint32_t imm32;
6566         bool index;
6567         bool add;
6568         bool wback;
6569 
6570         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6571         switch (encoding)
6572         {
6573             case eEncodingT1:
6574                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
6575                 t = Bits32 (opcode, 2, 0);
6576                 n = Bits32 (opcode, 5, 3);
6577                 imm32 = Bits32 (opcode, 10, 6) << 1;
6578 
6579                 // index = TRUE; add = TRUE; wback = FALSE;
6580                 index = true;
6581                 add = true;
6582                 wback = false;
6583 
6584                 break;
6585 
6586             case eEncodingT2:
6587                 // if Rt == '1111' then SEE "Unallocated memory hints";
6588                 // if Rn == '1111' then SEE LDRH (literal);
6589                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6590                 t = Bits32 (opcode, 15, 12);
6591                 n = Bits32 (opcode, 19, 16);
6592                 imm32 = Bits32 (opcode, 11, 0);
6593 
6594                 // index = TRUE; add = TRUE; wback = FALSE;
6595                 index = true;
6596                 add = true;
6597                 wback = false;
6598 
6599                 // if t == 13 then UNPREDICTABLE;
6600                 if (t == 13)
6601                     return false;
6602                 break;
6603 
6604             case eEncodingT3:
6605                 // if Rn == '1111' then SEE LDRH (literal);
6606                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
6607                 // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
6608                 // if P == '0' && W == '0' then UNDEFINED;
6609                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6610                     return false;
6611 
6612                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6613                 t = Bits32 (opcode, 15, 12);
6614                 n = Bits32 (opcode, 19, 16);
6615                 imm32 = Bits32 (opcode, 7, 0);
6616 
6617                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6618                 index = BitIsSet (opcode, 10);
6619                 add = BitIsSet (opcode, 9);
6620                 wback = BitIsSet (opcode, 8);
6621 
6622                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6623                 if (BadReg (t) || (wback && (n == t)))
6624                     return false;
6625                 break;
6626 
6627             default:
6628                 return false;
6629         }
6630 
6631         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6632         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6633         if (!success)
6634             return false;
6635 
6636         addr_t offset_addr;
6637         addr_t address;
6638 
6639         if (add)
6640             offset_addr = Rn + imm32;
6641         else
6642             offset_addr = Rn - imm32;
6643 
6644         // address = if index then offset_addr else R[n];
6645         if (index)
6646             address = offset_addr;
6647         else
6648             address = Rn;
6649 
6650         // data = MemU[address,2];
6651         RegisterInfo base_reg;
6652         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6653 
6654         EmulateInstruction::Context context;
6655         context.type = eContextRegisterLoad;
6656         context.SetRegisterPlusOffset (base_reg, address - Rn);
6657 
6658         uint64_t data = MemURead (context, address, 2, 0, &success);
6659         if (!success)
6660             return false;
6661 
6662         // if wback then R[n] = offset_addr;
6663         if (wback)
6664         {
6665             context.type = eContextAdjustBaseRegister;
6666             context.SetAddress (offset_addr);
6667             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6668                 return false;
6669         }
6670 
6671         // if UnalignedSupport() || address<0> = '0' then
6672         if (UnalignedSupport () || BitIsClear (address, 0))
6673         {
6674             // R[t] = ZeroExtend(data, 32);
6675             context.type = eContextRegisterLoad;
6676             context.SetRegisterPlusOffset (base_reg, address - Rn);
6677             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6678                 return false;
6679         }
6680         else // Can only apply before ARMv7
6681         {
6682             // R[t] = bits(32) UNKNOWN;
6683             WriteBits32Unknown (t);
6684         }
6685     }
6686     return true;
6687 }
6688 
6689 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory,
6690 // zero-extends it to form a 32-bit word, and writes it to a register.
6691 bool
6692 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding)
6693 {
6694 #if 0
6695     if ConditionPassed() then
6696         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6697         base = Align(PC,4);
6698         address = if add then (base + imm32) else (base - imm32);
6699         data = MemU[address,2];
6700         if UnalignedSupport() || address<0> = '0' then
6701             R[t] = ZeroExtend(data, 32);
6702         else // Can only apply before ARMv7
6703             R[t] = bits(32) UNKNOWN;
6704 #endif
6705 
6706     bool success = false;
6707 
6708     if (ConditionPassed(opcode))
6709     {
6710         uint32_t t;
6711         uint32_t imm32;
6712         bool add;
6713 
6714         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6715         switch (encoding)
6716         {
6717             case eEncodingT1:
6718                 // if Rt == '1111' then SEE "Unallocated memory hints";
6719                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6720                 t = Bits32 (opcode, 15, 12);
6721                 imm32 = Bits32 (opcode, 11, 0);
6722                 add = BitIsSet (opcode, 23);
6723 
6724                 // if t == 13 then UNPREDICTABLE;
6725                 if (t == 13)
6726                     return false;
6727 
6728                 break;
6729 
6730             case eEncodingA1:
6731             {
6732                 uint32_t imm4H = Bits32 (opcode, 11, 8);
6733                 uint32_t imm4L = Bits32 (opcode, 3, 0);
6734 
6735                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6736                 t = Bits32 (opcode, 15, 12);
6737                 imm32 = (imm4H << 4) | imm4L;
6738                 add = BitIsSet (opcode, 23);
6739 
6740                 // if t == 15 then UNPREDICTABLE;
6741                 if (t == 15)
6742                     return false;
6743                 break;
6744             }
6745 
6746             default:
6747                 return false;
6748         }
6749 
6750         // base = Align(PC,4);
6751         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6752         if (!success)
6753             return false;
6754 
6755         addr_t base = AlignPC (pc_value);
6756         addr_t address;
6757 
6758         // address = if add then (base + imm32) else (base - imm32);
6759         if (add)
6760             address = base + imm32;
6761         else
6762             address = base - imm32;
6763 
6764         // data = MemU[address,2];
6765         RegisterInfo base_reg;
6766         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
6767 
6768         EmulateInstruction::Context context;
6769         context.type = eContextRegisterLoad;
6770         context.SetRegisterPlusOffset (base_reg, address - base);
6771 
6772         uint64_t data = MemURead (context, address, 2, 0, &success);
6773         if (!success)
6774             return false;
6775 
6776 
6777         // if UnalignedSupport() || address<0> = '0' then
6778         if (UnalignedSupport () || BitIsClear (address, 0))
6779         {
6780             // R[t] = ZeroExtend(data, 32);
6781             context.type = eContextRegisterLoad;
6782             context.SetRegisterPlusOffset (base_reg, address - base);
6783             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6784                 return false;
6785 
6786         }
6787         else // Can only apply before ARMv7
6788         {
6789             // R[t] = bits(32) UNKNOWN;
6790             WriteBits32Unknown (t);
6791         }
6792     }
6793     return true;
6794 }
6795 
6796 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword
6797 // from memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6798 // be shifted left by 0, 1, 2, or 3 bits.
6799 bool
6800 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding)
6801 {
6802 #if 0
6803     if ConditionPassed() then
6804         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6805         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6806         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6807         address = if index then offset_addr else R[n];
6808         data = MemU[address,2];
6809         if wback then R[n] = offset_addr;
6810         if UnalignedSupport() || address<0> = '0' then
6811             R[t] = ZeroExtend(data, 32);
6812         else // Can only apply before ARMv7
6813             R[t] = bits(32) UNKNOWN;
6814 #endif
6815 
6816     bool success = false;
6817 
6818     if (ConditionPassed(opcode))
6819     {
6820         uint32_t t;
6821         uint32_t n;
6822         uint32_t m;
6823         bool index;
6824         bool add;
6825         bool wback;
6826         ARM_ShifterType shift_t;
6827         uint32_t shift_n;
6828 
6829         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6830         switch (encoding)
6831         {
6832             case eEncodingT1:
6833                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6834                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6835                 t = Bits32 (opcode, 2, 0);
6836                 n = Bits32 (opcode, 5, 3);
6837                 m = Bits32 (opcode, 8, 6);
6838 
6839                 // index = TRUE; add = TRUE; wback = FALSE;
6840                 index = true;
6841                 add = true;
6842                 wback = false;
6843 
6844                 // (shift_t, shift_n) = (SRType_LSL, 0);
6845                 shift_t = SRType_LSL;
6846                 shift_n = 0;
6847 
6848                 break;
6849 
6850             case eEncodingT2:
6851                 // if Rn == '1111' then SEE LDRH (literal);
6852                 // if Rt == '1111' then SEE "Unallocated memory hints";
6853                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6854                 t = Bits32 (opcode, 15, 12);
6855                 n = Bits32 (opcode, 19, 16);
6856                 m = Bits32 (opcode, 3, 0);
6857 
6858                 // index = TRUE; add = TRUE; wback = FALSE;
6859                 index = true;
6860                 add = true;
6861                 wback = false;
6862 
6863                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6864                 shift_t = SRType_LSL;
6865                 shift_n = Bits32 (opcode, 5, 4);
6866 
6867                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6868                 if ((t == 13) || BadReg (m))
6869                     return false;
6870                 break;
6871 
6872             case eEncodingA1:
6873                 // if P == '0' && W == '1' then SEE LDRHT;
6874                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6875                 t = Bits32 (opcode, 15, 12);
6876                 n = Bits32 (opcode, 19, 16);
6877                 m = Bits32 (opcode, 3, 0);
6878 
6879                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6880                 index = BitIsSet (opcode, 24);
6881                 add = BitIsSet (opcode, 23);
6882                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6883 
6884                 // (shift_t, shift_n) = (SRType_LSL, 0);
6885                 shift_t = SRType_LSL;
6886                 shift_n = 0;
6887 
6888                 // if t == 15 || m == 15 then UNPREDICTABLE;
6889                 if ((t == 15) || (m == 15))
6890                     return false;
6891 
6892                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6893                 if (wback && ((n == 15) || (n == t)))
6894                     return false;
6895 
6896                 break;
6897 
6898             default:
6899                 return false;
6900         }
6901 
6902         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6903 
6904         uint64_t Rm  = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6905         if (!success)
6906             return false;
6907 
6908         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6909         if (!success)
6910             return false;
6911 
6912         addr_t offset_addr;
6913         addr_t address;
6914 
6915         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6916         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6917         if (!success)
6918             return false;
6919 
6920         if (add)
6921             offset_addr = Rn + offset;
6922         else
6923             offset_addr = Rn - offset;
6924 
6925         // address = if index then offset_addr else R[n];
6926         if (index)
6927             address = offset_addr;
6928         else
6929             address = Rn;
6930 
6931         // data = MemU[address,2];
6932         RegisterInfo base_reg;
6933         RegisterInfo offset_reg;
6934         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6935         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
6936 
6937         EmulateInstruction::Context context;
6938         context.type = eContextRegisterLoad;
6939         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6940         uint64_t data = MemURead (context, address, 2, 0, &success);
6941         if (!success)
6942             return false;
6943 
6944         // if wback then R[n] = offset_addr;
6945         if (wback)
6946         {
6947             context.type = eContextAdjustBaseRegister;
6948             context.SetAddress (offset_addr);
6949             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6950                 return false;
6951         }
6952 
6953         // if UnalignedSupport() || address<0> = '0' then
6954         if (UnalignedSupport() || BitIsClear (address, 0))
6955         {
6956             // R[t] = ZeroExtend(data, 32);
6957             context.type = eContextRegisterLoad;
6958             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6959             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6960                 return false;
6961         }
6962         else // Can only apply before ARMv7
6963         {
6964             // R[t] = bits(32) UNKNOWN;
6965             WriteBits32Unknown (t);
6966         }
6967     }
6968     return true;
6969 }
6970 
6971 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from
6972 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed,
6973 // or pre-indexed addressing.
6974 bool
6975 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6976 {
6977 #if 0
6978     if ConditionPassed() then
6979         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6980         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6981         address = if index then offset_addr else R[n];
6982         R[t] = SignExtend(MemU[address,1], 32);
6983         if wback then R[n] = offset_addr;
6984 #endif
6985 
6986     bool success = false;
6987 
6988     if (ConditionPassed(opcode))
6989     {
6990         uint32_t t;
6991         uint32_t n;
6992         uint32_t imm32;
6993         bool index;
6994         bool add;
6995         bool wback;
6996 
6997         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6998         switch (encoding)
6999         {
7000             case eEncodingT1:
7001                 // if Rt == '1111' then SEE PLI;
7002                 // if Rn == '1111' then SEE LDRSB (literal);
7003                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7004                 t = Bits32 (opcode, 15, 12);
7005                 n = Bits32 (opcode, 19, 16);
7006                 imm32 = Bits32 (opcode, 11, 0);
7007 
7008                 // index = TRUE; add = TRUE; wback = FALSE;
7009                 index = true;
7010                 add = true;
7011                 wback = false;
7012 
7013                 // if t == 13 then UNPREDICTABLE;
7014                 if (t == 13)
7015                     return false;
7016 
7017                 break;
7018 
7019             case eEncodingT2:
7020                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
7021                 // if Rn == '1111' then SEE LDRSB (literal);
7022                 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
7023                 // if P == '0' && W == '0' then UNDEFINED;
7024                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7025                     return false;
7026 
7027                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7028                 t = Bits32 (opcode, 15, 12);
7029                 n = Bits32 (opcode, 19, 16);
7030                 imm32 = Bits32 (opcode, 7, 0);
7031 
7032                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7033                 index = BitIsSet (opcode, 10);
7034                 add = BitIsSet (opcode, 9);
7035                 wback = BitIsSet (opcode, 8);
7036 
7037                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7038                   if (((t == 13) || ((t == 15)
7039                                      && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8))))
7040                       || (wback && (n == t)))
7041                     return false;
7042 
7043                 break;
7044 
7045             case eEncodingA1:
7046             {
7047                 // if Rn == '1111' then SEE LDRSB (literal);
7048                 // if P == '0' && W == '1' then SEE LDRSBT;
7049                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7050                 t = Bits32 (opcode, 15, 12);
7051                 n = Bits32 (opcode, 19, 16);
7052 
7053                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7054                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7055                 imm32 = (imm4H << 4) | imm4L;
7056 
7057                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7058                 index = BitIsSet (opcode, 24);
7059                 add = BitIsSet (opcode, 23);
7060                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
7061 
7062                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7063                 if ((t == 15) || (wback && (n == t)))
7064                     return false;
7065 
7066                 break;
7067             }
7068 
7069             default:
7070                 return false;
7071         }
7072 
7073         uint64_t Rn = ReadCoreReg (n, &success);
7074         if (!success)
7075             return false;
7076 
7077         addr_t offset_addr;
7078         addr_t address;
7079 
7080         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7081         if (add)
7082             offset_addr = Rn + imm32;
7083         else
7084             offset_addr = Rn - imm32;
7085 
7086         // address = if index then offset_addr else R[n];
7087         if (index)
7088             address = offset_addr;
7089         else
7090             address = Rn;
7091 
7092         // R[t] = SignExtend(MemU[address,1], 32);
7093         RegisterInfo base_reg;
7094         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7095 
7096         EmulateInstruction::Context context;
7097         context.type = eContextRegisterLoad;
7098         context.SetRegisterPlusOffset (base_reg, address - Rn);
7099 
7100         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7101         if (!success)
7102             return false;
7103 
7104         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7105         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7106             return false;
7107 
7108         // if wback then R[n] = offset_addr;
7109         if (wback)
7110         {
7111             context.type = eContextAdjustBaseRegister;
7112             context.SetAddress (offset_addr);
7113             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7114                 return false;
7115         }
7116     }
7117 
7118     return true;
7119 }
7120 
7121 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
7122 // sign-extends it to form a 32-bit word, and writes tit to a register.
7123 bool
7124 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding)
7125 {
7126 #if 0
7127     if ConditionPassed() then
7128         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7129         base = Align(PC,4);
7130         address = if add then (base + imm32) else (base - imm32);
7131         R[t] = SignExtend(MemU[address,1], 32);
7132 #endif
7133 
7134     bool success = false;
7135 
7136     if (ConditionPassed(opcode))
7137     {
7138         uint32_t t;
7139         uint32_t imm32;
7140         bool add;
7141 
7142         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7143         switch (encoding)
7144         {
7145             case eEncodingT1:
7146                 // if Rt == '1111' then SEE PLI;
7147                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7148                 t = Bits32 (opcode, 15, 12);
7149                 imm32 = Bits32 (opcode, 11, 0);
7150                 add = BitIsSet (opcode, 23);
7151 
7152                 // if t == 13 then UNPREDICTABLE;
7153                 if (t == 13)
7154                     return false;
7155 
7156                 break;
7157 
7158             case eEncodingA1:
7159             {
7160                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7161                 t = Bits32 (opcode, 15, 12);
7162                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7163                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7164                 imm32 = (imm4H << 4) | imm4L;
7165                 add = BitIsSet (opcode, 23);
7166 
7167                 // if t == 15 then UNPREDICTABLE;
7168                 if (t == 15)
7169                     return false;
7170 
7171                 break;
7172             }
7173 
7174             default:
7175                 return false;
7176         }
7177 
7178         // base = Align(PC,4);
7179         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7180         if (!success)
7181             return false;
7182         uint64_t base = AlignPC (pc_value);
7183 
7184         // address = if add then (base + imm32) else (base - imm32);
7185         addr_t address;
7186         if (add)
7187             address = base + imm32;
7188         else
7189             address = base - imm32;
7190 
7191         // R[t] = SignExtend(MemU[address,1], 32);
7192         RegisterInfo base_reg;
7193         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7194 
7195         EmulateInstruction::Context context;
7196         context.type = eContextRegisterLoad;
7197         context.SetRegisterPlusOffset (base_reg, address - base);
7198 
7199         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7200         if (!success)
7201             return false;
7202 
7203         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7204         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7205             return false;
7206     }
7207     return true;
7208 }
7209 
7210 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from
7211 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7212 // shifted left by 0, 1, 2, or 3 bits.
7213 bool
7214 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding)
7215 {
7216 #if 0
7217     if ConditionPassed() then
7218         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7219         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7220         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7221         address = if index then offset_addr else R[n];
7222         R[t] = SignExtend(MemU[address,1], 32);
7223         if wback then R[n] = offset_addr;
7224 #endif
7225 
7226     bool success = false;
7227 
7228     if (ConditionPassed(opcode))
7229     {
7230         uint32_t t;
7231         uint32_t n;
7232         uint32_t m;
7233         bool index;
7234         bool add;
7235         bool wback;
7236         ARM_ShifterType shift_t;
7237         uint32_t shift_n;
7238 
7239         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7240         switch (encoding)
7241         {
7242             case eEncodingT1:
7243                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7244                 t = Bits32 (opcode, 2, 0);
7245                 n = Bits32 (opcode, 5, 3);
7246                 m = Bits32 (opcode, 8, 6);
7247 
7248                 // index = TRUE; add = TRUE; wback = FALSE;
7249                 index = true;
7250                 add = true;
7251                 wback = false;
7252 
7253                 // (shift_t, shift_n) = (SRType_LSL, 0);
7254                 shift_t = SRType_LSL;
7255                 shift_n = 0;
7256 
7257                 break;
7258 
7259             case eEncodingT2:
7260                 // if Rt == '1111' then SEE PLI;
7261                 // if Rn == '1111' then SEE LDRSB (literal);
7262                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7263                 t = Bits32 (opcode, 15, 12);
7264                 n = Bits32 (opcode, 19, 16);
7265                 m = Bits32 (opcode, 3, 0);
7266 
7267                 // index = TRUE; add = TRUE; wback = FALSE;
7268                 index = true;
7269                 add = true;
7270                 wback = false;
7271 
7272                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7273                 shift_t = SRType_LSL;
7274                 shift_n = Bits32 (opcode, 5, 4);
7275 
7276                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7277                 if ((t == 13) || BadReg (m))
7278                     return false;
7279                 break;
7280 
7281             case eEncodingA1:
7282                 // if P == '0' && W == '1' then SEE LDRSBT;
7283                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7284                 t = Bits32 (opcode, 15, 12);
7285                 n = Bits32 (opcode, 19, 16);
7286                 m = Bits32 (opcode, 3, 0);
7287 
7288                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7289                 index = BitIsSet (opcode, 24);
7290                 add = BitIsSet (opcode, 23);
7291                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7292 
7293                 // (shift_t, shift_n) = (SRType_LSL, 0);
7294                 shift_t = SRType_LSL;
7295                 shift_n = 0;
7296 
7297                 // if t == 15 || m == 15 then UNPREDICTABLE;
7298                 if ((t == 15) || (m == 15))
7299                     return false;
7300 
7301                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7302                 if (wback && ((n == 15) || (n == t)))
7303                     return false;
7304                 break;
7305 
7306             default:
7307                 return false;
7308         }
7309 
7310         uint64_t Rm =  ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7311         if (!success)
7312             return false;
7313 
7314         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7315         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7316         if (!success)
7317             return false;
7318 
7319         addr_t offset_addr;
7320         addr_t address;
7321 
7322         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7323         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7324         if (!success)
7325             return false;
7326 
7327         if (add)
7328             offset_addr = Rn + offset;
7329         else
7330             offset_addr = Rn - offset;
7331 
7332         // address = if index then offset_addr else R[n];
7333         if (index)
7334             address = offset_addr;
7335         else
7336             address = Rn;
7337 
7338         // R[t] = SignExtend(MemU[address,1], 32);
7339         RegisterInfo base_reg;
7340         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7341         RegisterInfo offset_reg;
7342         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7343 
7344         EmulateInstruction::Context context;
7345         context.type = eContextRegisterLoad;
7346         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7347 
7348         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7349         if (!success)
7350             return false;
7351 
7352         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7353         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7354             return false;
7355 
7356         // if wback then R[n] = offset_addr;
7357         if (wback)
7358         {
7359             context.type = eContextAdjustBaseRegister;
7360             context.SetAddress (offset_addr);
7361             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7362                 return false;
7363         }
7364     }
7365     return true;
7366 }
7367 
7368 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from
7369 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed, or
7370 // pre-indexed addressing.
7371 bool
7372 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding)
7373 {
7374 #if 0
7375     if ConditionPassed() then
7376         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7377         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7378         address = if index then offset_addr else R[n];
7379         data = MemU[address,2];
7380         if wback then R[n] = offset_addr;
7381         if UnalignedSupport() || address<0> = '0' then
7382             R[t] = SignExtend(data, 32);
7383         else // Can only apply before ARMv7
7384             R[t] = bits(32) UNKNOWN;
7385 #endif
7386 
7387     bool success = false;
7388 
7389     if (ConditionPassed(opcode))
7390     {
7391         uint32_t t;
7392         uint32_t n;
7393         uint32_t imm32;
7394         bool index;
7395         bool add;
7396         bool wback;
7397 
7398         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7399         switch (encoding)
7400         {
7401             case eEncodingT1:
7402                 // if Rn == '1111' then SEE LDRSH (literal);
7403                 // if Rt == '1111' then SEE "Unallocated memory hints";
7404                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7405                 t = Bits32 (opcode, 15, 12);
7406                 n = Bits32 (opcode, 19, 16);
7407                 imm32 = Bits32 (opcode, 11, 0);
7408 
7409                 // index = TRUE; add = TRUE; wback = FALSE;
7410                 index = true;
7411                 add = true;
7412                 wback = false;
7413 
7414                 // if t == 13 then UNPREDICTABLE;
7415                 if (t == 13)
7416                     return false;
7417 
7418                 break;
7419 
7420             case eEncodingT2:
7421                 // if Rn == '1111' then SEE LDRSH (literal);
7422                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
7423                 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7424                 // if P == '0' && W == '0' then UNDEFINED;
7425                   if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7426                   return false;
7427 
7428                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7429                 t = Bits32 (opcode, 15, 12);
7430                 n = Bits32 (opcode, 19, 16);
7431                 imm32 = Bits32 (opcode, 7, 0);
7432 
7433                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7434                 index = BitIsSet (opcode, 10);
7435                 add = BitIsSet (opcode, 9);
7436                 wback = BitIsSet (opcode, 8);
7437 
7438                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7439                 if (BadReg (t) || (wback && (n == t)))
7440                     return false;
7441 
7442                 break;
7443 
7444             case eEncodingA1:
7445             {
7446                 // if Rn == '1111' then SEE LDRSH (literal);
7447                 // if P == '0' && W == '1' then SEE LDRSHT;
7448                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7449                 t = Bits32 (opcode, 15, 12);
7450                 n = Bits32 (opcode, 19, 16);
7451                 uint32_t imm4H = Bits32 (opcode, 11,8);
7452                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7453                 imm32 = (imm4H << 4) | imm4L;
7454 
7455                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7456                 index = BitIsSet (opcode, 24);
7457                 add = BitIsSet (opcode, 23);
7458                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7459 
7460                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7461                 if ((t == 15) || (wback && (n == t)))
7462                     return false;
7463 
7464                 break;
7465             }
7466 
7467             default:
7468                 return false;
7469         }
7470 
7471         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7472         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7473         if (!success)
7474             return false;
7475 
7476         addr_t offset_addr;
7477         if (add)
7478             offset_addr = Rn + imm32;
7479         else
7480             offset_addr = Rn - imm32;
7481 
7482         // address = if index then offset_addr else R[n];
7483         addr_t address;
7484         if (index)
7485             address = offset_addr;
7486         else
7487             address = Rn;
7488 
7489         // data = MemU[address,2];
7490         RegisterInfo base_reg;
7491         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7492 
7493         EmulateInstruction::Context context;
7494         context.type = eContextRegisterLoad;
7495         context.SetRegisterPlusOffset (base_reg, address - Rn);
7496 
7497         uint64_t data = MemURead (context, address, 2, 0, &success);
7498         if (!success)
7499             return false;
7500 
7501         // if wback then R[n] = offset_addr;
7502         if (wback)
7503         {
7504             context.type = eContextAdjustBaseRegister;
7505             context.SetAddress (offset_addr);
7506             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7507                 return false;
7508         }
7509 
7510         // if UnalignedSupport() || address<0> = '0' then
7511         if (UnalignedSupport() || BitIsClear (address, 0))
7512         {
7513             // R[t] = SignExtend(data, 32);
7514             int64_t signed_data = llvm::SignExtend64<16>(data);
7515             context.type = eContextRegisterLoad;
7516             context.SetRegisterPlusOffset (base_reg, address - Rn);
7517             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7518                 return false;
7519         }
7520         else // Can only apply before ARMv7
7521         {
7522             // R[t] = bits(32) UNKNOWN;
7523             WriteBits32Unknown (t);
7524         }
7525     }
7526     return true;
7527 }
7528 
7529 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory,
7530 // sign-extends it to from a 32-bit word, and writes it to a register.
7531 bool
7532 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding)
7533 {
7534 #if 0
7535     if ConditionPassed() then
7536         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7537         base = Align(PC,4);
7538         address = if add then (base + imm32) else (base - imm32);
7539         data = MemU[address,2];
7540         if UnalignedSupport() || address<0> = '0' then
7541             R[t] = SignExtend(data, 32);
7542         else // Can only apply before ARMv7
7543             R[t] = bits(32) UNKNOWN;
7544 #endif
7545 
7546     bool success = false;
7547 
7548     if (ConditionPassed(opcode))
7549     {
7550         uint32_t t;
7551         uint32_t imm32;
7552         bool add;
7553 
7554         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7555         switch (encoding)
7556         {
7557             case eEncodingT1:
7558                 // if Rt == '1111' then SEE "Unallocated memory hints";
7559                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7560                 t = Bits32  (opcode, 15, 12);
7561                 imm32 = Bits32 (opcode, 11, 0);
7562                 add = BitIsSet (opcode, 23);
7563 
7564                 // if t == 13 then UNPREDICTABLE;
7565                 if (t == 13)
7566                     return false;
7567 
7568                 break;
7569 
7570             case eEncodingA1:
7571             {
7572                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7573                 t = Bits32 (opcode, 15, 12);
7574                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7575                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7576                 imm32 = (imm4H << 4) | imm4L;
7577                 add = BitIsSet (opcode, 23);
7578 
7579                 // if t == 15 then UNPREDICTABLE;
7580                 if (t == 15)
7581                     return false;
7582 
7583                 break;
7584             }
7585             default:
7586                 return false;
7587         }
7588 
7589         // base = Align(PC,4);
7590         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7591         if (!success)
7592             return false;
7593 
7594         uint64_t base = AlignPC (pc_value);
7595 
7596         addr_t address;
7597         // address = if add then (base + imm32) else (base - imm32);
7598         if (add)
7599             address = base + imm32;
7600         else
7601             address = base - imm32;
7602 
7603         // data = MemU[address,2];
7604         RegisterInfo base_reg;
7605         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7606 
7607         EmulateInstruction::Context context;
7608         context.type = eContextRegisterLoad;
7609         context.SetRegisterPlusOffset (base_reg, imm32);
7610 
7611         uint64_t data = MemURead (context, address, 2, 0, &success);
7612         if (!success)
7613             return false;
7614 
7615         // if UnalignedSupport() || address<0> = '0' then
7616         if (UnalignedSupport() || BitIsClear (address, 0))
7617         {
7618             // R[t] = SignExtend(data, 32);
7619             int64_t signed_data = llvm::SignExtend64<16>(data);
7620             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7621                 return false;
7622         }
7623         else // Can only apply before ARMv7
7624         {
7625             // R[t] = bits(32) UNKNOWN;
7626             WriteBits32Unknown (t);
7627         }
7628     }
7629     return true;
7630 }
7631 
7632 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword
7633 // from memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7634 // shifted left by 0, 1, 2, or 3 bits.
7635 bool
7636 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding)
7637 {
7638 #if 0
7639     if ConditionPassed() then
7640         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7641         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7642         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7643         address = if index then offset_addr else R[n];
7644         data = MemU[address,2];
7645         if wback then R[n] = offset_addr;
7646         if UnalignedSupport() || address<0> = '0' then
7647             R[t] = SignExtend(data, 32);
7648         else // Can only apply before ARMv7
7649             R[t] = bits(32) UNKNOWN;
7650 #endif
7651 
7652     bool success = false;
7653 
7654     if (ConditionPassed(opcode))
7655     {
7656         uint32_t t;
7657         uint32_t n;
7658         uint32_t m;
7659         bool index;
7660         bool add;
7661         bool wback;
7662         ARM_ShifterType shift_t;
7663         uint32_t shift_n;
7664 
7665         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7666         switch (encoding)
7667         {
7668             case eEncodingT1:
7669                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
7670                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7671                 t = Bits32 (opcode, 2, 0);
7672                 n = Bits32 (opcode, 5, 3);
7673                 m = Bits32 (opcode, 8, 6);
7674 
7675                 // index = TRUE; add = TRUE; wback = FALSE;
7676                 index = true;
7677                 add = true;
7678                 wback = false;
7679 
7680                 // (shift_t, shift_n) = (SRType_LSL, 0);
7681                 shift_t = SRType_LSL;
7682                 shift_n = 0;
7683 
7684                 break;
7685 
7686             case eEncodingT2:
7687                 // if Rn == '1111' then SEE LDRSH (literal);
7688                 // if Rt == '1111' then SEE "Unallocated memory hints";
7689                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7690                 t = Bits32 (opcode, 15, 12);
7691                 n = Bits32 (opcode, 19, 16);
7692                 m = Bits32 (opcode, 3, 0);
7693 
7694                 // index = TRUE; add = TRUE; wback = FALSE;
7695                 index = true;
7696                 add = true;
7697                 wback = false;
7698 
7699                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7700                 shift_t = SRType_LSL;
7701                 shift_n = Bits32 (opcode, 5, 4);
7702 
7703                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7704                 if ((t == 13) || BadReg (m))
7705                     return false;
7706 
7707                 break;
7708 
7709             case eEncodingA1:
7710                 // if P == '0' && W == '1' then SEE LDRSHT;
7711                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7712                 t = Bits32 (opcode, 15, 12);
7713                 n = Bits32 (opcode, 19, 16);
7714                 m = Bits32 (opcode, 3, 0);
7715 
7716                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7717                 index = BitIsSet (opcode, 24);
7718                 add = BitIsSet (opcode, 23);
7719                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7720 
7721                 // (shift_t, shift_n) = (SRType_LSL, 0);
7722                 shift_t = SRType_LSL;
7723                 shift_n = 0;
7724 
7725                 // if t == 15 || m == 15 then UNPREDICTABLE;
7726                 if ((t == 15) || (m == 15))
7727                     return false;
7728 
7729                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7730                 if (wback && ((n == 15) || (n == t)))
7731                     return false;
7732 
7733                 break;
7734 
7735             default:
7736                 return false;
7737         }
7738 
7739         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7740         if (!success)
7741             return false;
7742 
7743         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7744         if (!success)
7745             return false;
7746 
7747         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7748         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7749         if (!success)
7750             return false;
7751 
7752         addr_t offset_addr;
7753         addr_t address;
7754 
7755         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7756         if (add)
7757             offset_addr = Rn + offset;
7758         else
7759             offset_addr = Rn - offset;
7760 
7761         // address = if index then offset_addr else R[n];
7762         if (index)
7763             address = offset_addr;
7764         else
7765             address = Rn;
7766 
7767         // data = MemU[address,2];
7768         RegisterInfo base_reg;
7769         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7770 
7771         RegisterInfo offset_reg;
7772         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7773 
7774         EmulateInstruction::Context context;
7775         context.type = eContextRegisterLoad;
7776         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7777 
7778         uint64_t data = MemURead (context, address, 2, 0, &success);
7779         if (!success)
7780             return false;
7781 
7782         // if wback then R[n] = offset_addr;
7783         if (wback)
7784         {
7785             context.type = eContextAdjustBaseRegister;
7786             context.SetAddress (offset_addr);
7787             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7788                 return false;
7789         }
7790 
7791         // if UnalignedSupport() || address<0> = '0' then
7792         if (UnalignedSupport() || BitIsClear (address, 0))
7793         {
7794             // R[t] = SignExtend(data, 32);
7795             context.type = eContextRegisterLoad;
7796             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7797 
7798             int64_t signed_data = llvm::SignExtend64<16>(data);
7799             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7800                 return false;
7801         }
7802         else // Can only apply before ARMv7
7803         {
7804             // R[t] = bits(32) UNKNOWN;
7805             WriteBits32Unknown (t);
7806         }
7807     }
7808     return true;
7809 }
7810 
7811 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7812 // register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7813 bool
7814 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding)
7815 {
7816 #if 0
7817     if ConditionPassed() then
7818         EncodingSpecificOperations();
7819         rotated = ROR(R[m], rotation);
7820         R[d] = SignExtend(rotated<7:0>, 32);
7821 #endif
7822 
7823     bool success = false;
7824 
7825     if (ConditionPassed(opcode))
7826     {
7827         uint32_t d;
7828         uint32_t m;
7829         uint32_t rotation;
7830 
7831         // EncodingSpecificOperations();
7832         switch (encoding)
7833         {
7834             case eEncodingT1:
7835                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7836                 d = Bits32 (opcode, 2, 0);
7837                 m = Bits32 (opcode, 5, 3);
7838                 rotation = 0;
7839 
7840                 break;
7841 
7842             case eEncodingT2:
7843                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7844                 d = Bits32 (opcode, 11, 8);
7845                 m = Bits32 (opcode, 3, 0);
7846                 rotation = Bits32 (opcode, 5, 4) << 3;
7847 
7848                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7849                 if (BadReg (d) || BadReg (m))
7850                     return false;
7851 
7852                 break;
7853 
7854             case eEncodingA1:
7855                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7856                 d = Bits32 (opcode, 15, 12);
7857                 m = Bits32 (opcode, 3, 0);
7858                 rotation = Bits32 (opcode, 11, 10) << 3;
7859 
7860                 // if d == 15 || m == 15 then UNPREDICTABLE;
7861                 if ((d == 15) || (m == 15))
7862                     return false;
7863 
7864                 break;
7865 
7866             default:
7867                 return false;
7868         }
7869 
7870         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7871         if (!success)
7872             return false;
7873 
7874         // rotated = ROR(R[m], rotation);
7875         uint64_t rotated = ROR (Rm, rotation, &success);
7876         if (!success)
7877             return false;
7878 
7879         // R[d] = SignExtend(rotated<7:0>, 32);
7880         int64_t data = llvm::SignExtend64<8>(rotated);
7881 
7882         RegisterInfo source_reg;
7883         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7884 
7885         EmulateInstruction::Context context;
7886         context.type = eContextRegisterLoad;
7887         context.SetRegister (source_reg);
7888 
7889         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7890             return false;
7891     }
7892     return true;
7893 }
7894 
7895 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7896 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7897 bool
7898 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding)
7899 {
7900 #if 0
7901     if ConditionPassed() then
7902         EncodingSpecificOperations();
7903         rotated = ROR(R[m], rotation);
7904         R[d] = SignExtend(rotated<15:0>, 32);
7905 #endif
7906 
7907     bool success = false;
7908 
7909     if (ConditionPassed(opcode))
7910     {
7911         uint32_t d;
7912         uint32_t m;
7913         uint32_t rotation;
7914 
7915         // EncodingSpecificOperations();
7916         switch (encoding)
7917         {
7918             case eEncodingT1:
7919                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7920                 d = Bits32 (opcode, 2, 0);
7921                 m = Bits32 (opcode, 5, 3);
7922                 rotation = 0;
7923 
7924                 break;
7925 
7926             case eEncodingT2:
7927                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7928                 d = Bits32 (opcode, 11, 8);
7929                 m = Bits32 (opcode, 3, 0);
7930                 rotation = Bits32 (opcode, 5, 4) << 3;
7931 
7932                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7933                 if (BadReg (d) || BadReg (m))
7934                     return false;
7935 
7936                 break;
7937 
7938             case eEncodingA1:
7939                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7940                 d = Bits32 (opcode, 15, 12);
7941                 m = Bits32 (opcode, 3, 0);
7942                 rotation = Bits32 (opcode, 11, 10) << 3;
7943 
7944                 // if d == 15 || m == 15 then UNPREDICTABLE;
7945                 if ((d == 15) || (m == 15))
7946                     return false;
7947 
7948                 break;
7949 
7950             default:
7951                 return false;
7952         }
7953 
7954         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7955         if (!success)
7956             return false;
7957 
7958         // rotated = ROR(R[m], rotation);
7959         uint64_t rotated = ROR (Rm, rotation, &success);
7960         if (!success)
7961             return false;
7962 
7963         // R[d] = SignExtend(rotated<15:0>, 32);
7964         RegisterInfo source_reg;
7965         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7966 
7967         EmulateInstruction::Context context;
7968         context.type = eContextRegisterLoad;
7969         context.SetRegister (source_reg);
7970 
7971         int64_t data = llvm::SignExtend64<16> (rotated);
7972         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7973             return false;
7974     }
7975 
7976     return true;
7977 }
7978 
7979 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination
7980 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7981 bool
7982 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding)
7983 {
7984 #if 0
7985     if ConditionPassed() then
7986         EncodingSpecificOperations();
7987         rotated = ROR(R[m], rotation);
7988         R[d] = ZeroExtend(rotated<7:0>, 32);
7989 #endif
7990 
7991     bool success = false;
7992 
7993     if (ConditionPassed(opcode))
7994     {
7995         uint32_t d;
7996         uint32_t m;
7997         uint32_t rotation;
7998 
7999         // EncodingSpecificOperations();
8000         switch (encoding)
8001         {
8002             case eEncodingT1:
8003                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8004                 d = Bits32 (opcode, 2, 0);
8005                 m = Bits32 (opcode, 5, 3);
8006                 rotation = 0;
8007 
8008                 break;
8009 
8010             case eEncodingT2:
8011                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8012                 d = Bits32 (opcode, 11, 8);
8013                 m = Bits32 (opcode, 3, 0);
8014                   rotation = Bits32 (opcode, 5, 4) << 3;
8015 
8016                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8017                 if (BadReg (d) || BadReg (m))
8018                   return false;
8019 
8020                 break;
8021 
8022             case eEncodingA1:
8023                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8024                 d = Bits32 (opcode, 15, 12);
8025                 m = Bits32 (opcode, 3, 0);
8026                 rotation = Bits32 (opcode, 11, 10) << 3;
8027 
8028                 // if d == 15 || m == 15 then UNPREDICTABLE;
8029                 if ((d == 15) || (m == 15))
8030                     return false;
8031 
8032                 break;
8033 
8034             default:
8035                 return false;
8036         }
8037 
8038         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8039         if (!success)
8040             return false;
8041 
8042         // rotated = ROR(R[m], rotation);
8043         uint64_t rotated = ROR (Rm, rotation, &success);
8044         if (!success)
8045             return false;
8046 
8047         // R[d] = ZeroExtend(rotated<7:0>, 32);
8048         RegisterInfo source_reg;
8049         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8050 
8051         EmulateInstruction::Context context;
8052         context.type = eContextRegisterLoad;
8053         context.SetRegister (source_reg);
8054 
8055         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0)))
8056             return false;
8057     }
8058     return true;
8059 }
8060 
8061 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination
8062 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
8063 bool
8064 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding)
8065 {
8066 #if 0
8067     if ConditionPassed() then
8068         EncodingSpecificOperations();
8069         rotated = ROR(R[m], rotation);
8070         R[d] = ZeroExtend(rotated<15:0>, 32);
8071 #endif
8072 
8073     bool success = false;
8074 
8075     if (ConditionPassed(opcode))
8076     {
8077         uint32_t d;
8078         uint32_t m;
8079         uint32_t rotation;
8080 
8081         switch (encoding)
8082         {
8083             case eEncodingT1:
8084                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8085                 d = Bits32 (opcode, 2, 0);
8086                 m = Bits32 (opcode, 5, 3);
8087                 rotation = 0;
8088 
8089                 break;
8090 
8091             case eEncodingT2:
8092                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8093                 d = Bits32 (opcode, 11, 8);
8094                 m = Bits32 (opcode, 3, 0);
8095                 rotation = Bits32 (opcode, 5, 4) << 3;
8096 
8097                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8098                 if (BadReg (d) || BadReg (m))
8099                   return false;
8100 
8101                 break;
8102 
8103             case eEncodingA1:
8104                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8105                 d = Bits32 (opcode, 15, 12);
8106                 m = Bits32 (opcode, 3, 0);
8107                 rotation = Bits32 (opcode, 11, 10) << 3;
8108 
8109                 // if d == 15 || m == 15 then UNPREDICTABLE;
8110                 if ((d == 15) || (m == 15))
8111                     return false;
8112 
8113                 break;
8114 
8115             default:
8116                 return false;
8117         }
8118 
8119         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8120         if (!success)
8121             return false;
8122 
8123         // rotated = ROR(R[m], rotation);
8124         uint64_t rotated = ROR (Rm, rotation, &success);
8125         if (!success)
8126             return false;
8127 
8128         // R[d] = ZeroExtend(rotated<15:0>, 32);
8129         RegisterInfo source_reg;
8130         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8131 
8132         EmulateInstruction::Context context;
8133         context.type = eContextRegisterLoad;
8134         context.SetRegister (source_reg);
8135 
8136         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0)))
8137             return false;
8138     }
8139     return true;
8140 }
8141 
8142 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following
8143 // word respectively.
8144 bool
8145 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding)
8146 {
8147 #if 0
8148     if ConditionPassed() then
8149         EncodingSpecificOperations();
8150         if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8151             UNPREDICTABLE;
8152         else
8153             address = if increment then R[n] else R[n]-8;
8154             if wordhigher then address = address+4;
8155             CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8156             BranchWritePC(MemA[address,4]);
8157             if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8158 #endif
8159 
8160     bool success = false;
8161 
8162     if (ConditionPassed(opcode))
8163     {
8164         uint32_t n;
8165         bool wback;
8166         bool increment;
8167         bool wordhigher;
8168 
8169         // EncodingSpecificOperations();
8170         switch (encoding)
8171         {
8172             case eEncodingT1:
8173                 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE;
8174                 n = Bits32 (opcode, 19, 16);
8175                 wback = BitIsSet (opcode, 21);
8176                 increment = false;
8177                 wordhigher = false;
8178 
8179                 // if n == 15 then UNPREDICTABLE;
8180                 if (n == 15)
8181                     return false;
8182 
8183                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8184                 if (InITBlock() && !LastInITBlock())
8185                     return false;
8186 
8187                 break;
8188 
8189             case eEncodingT2:
8190                 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8191                 n = Bits32 (opcode, 19, 16);
8192                 wback = BitIsSet (opcode, 21);
8193                 increment = true;
8194                 wordhigher = false;
8195 
8196                 // if n == 15 then UNPREDICTABLE;
8197                 if (n == 15)
8198                     return false;
8199 
8200                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8201                 if (InITBlock() && !LastInITBlock())
8202                     return false;
8203 
8204                 break;
8205 
8206             case eEncodingA1:
8207                 // n = UInt(Rn);
8208                 n = Bits32 (opcode, 19, 16);
8209 
8210                 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8211                 wback = BitIsSet (opcode, 21);
8212                 increment = BitIsSet (opcode, 23);
8213                 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23));
8214 
8215                 // if n == 15 then UNPREDICTABLE;
8216                 if (n == 15)
8217                     return false;
8218 
8219                 break;
8220 
8221             default:
8222                 return false;
8223         }
8224 
8225         // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8226         if (!CurrentModeIsPrivileged ())
8227             // UNPREDICTABLE;
8228             return false;
8229         else
8230         {
8231             uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8232             if (!success)
8233                 return false;
8234 
8235             addr_t address;
8236             // address = if increment then R[n] else R[n]-8;
8237             if (increment)
8238                 address = Rn;
8239             else
8240                 address = Rn - 8;
8241 
8242             // if wordhigher then address = address+4;
8243             if (wordhigher)
8244                 address = address + 4;
8245 
8246             // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8247             RegisterInfo base_reg;
8248             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8249 
8250             EmulateInstruction::Context context;
8251             context.type = eContextReturnFromException;
8252             context.SetRegisterPlusOffset (base_reg, address - Rn);
8253 
8254             uint64_t data = MemARead (context, address + 4, 4, 0, &success);
8255             if (!success)
8256                 return false;
8257 
8258             CPSRWriteByInstr (data, 15, true);
8259 
8260             // BranchWritePC(MemA[address,4]);
8261             uint64_t data2 = MemARead (context, address, 4, 0, &success);
8262             if (!success)
8263                 return false;
8264 
8265             BranchWritePC (context, data2);
8266 
8267             // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8268             if (wback)
8269             {
8270                 context.type = eContextAdjustBaseRegister;
8271                 if (increment)
8272                 {
8273                     context.SetOffset (8);
8274                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8))
8275                         return false;
8276                 }
8277                 else
8278                 {
8279                     context.SetOffset (-8);
8280                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8))
8281                         return false;
8282                 }
8283             } // if wback
8284         }
8285     } // if ConditionPassed()
8286     return true;
8287 }
8288 
8289 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
8290 // and writes the result to the destination register.  It can optionally update the condition flags based on
8291 // the result.
8292 bool
8293 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding)
8294 {
8295 #if 0
8296     // ARM pseudo code...
8297     if ConditionPassed() then
8298         EncodingSpecificOperations();
8299         result = R[n] EOR imm32;
8300         if d == 15 then         // Can only occur for ARM encoding
8301             ALUWritePC(result); // setflags is always FALSE here
8302         else
8303             R[d] = result;
8304             if setflags then
8305                 APSR.N = result<31>;
8306                 APSR.Z = IsZeroBit(result);
8307                 APSR.C = carry;
8308                 // APSR.V unchanged
8309 #endif
8310 
8311     bool success = false;
8312 
8313     if (ConditionPassed(opcode))
8314     {
8315         uint32_t Rd, Rn;
8316         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8317         bool setflags;
8318         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8319         switch (encoding)
8320         {
8321         case eEncodingT1:
8322             Rd = Bits32(opcode, 11, 8);
8323             Rn = Bits32(opcode, 19, 16);
8324             setflags = BitIsSet(opcode, 20);
8325             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8326             // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8327             if (Rd == 15 && setflags)
8328                 return EmulateTEQImm (opcode, eEncodingT1);
8329             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8330                 return false;
8331             break;
8332         case eEncodingA1:
8333             Rd = Bits32(opcode, 15, 12);
8334             Rn = Bits32(opcode, 19, 16);
8335             setflags = BitIsSet(opcode, 20);
8336             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8337 
8338             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8339             if (Rd == 15 && setflags)
8340                 return EmulateSUBSPcLrEtc (opcode, encoding);
8341             break;
8342         default:
8343             return false;
8344         }
8345 
8346         // Read the first operand.
8347         uint32_t val1 = ReadCoreReg(Rn, &success);
8348         if (!success)
8349             return false;
8350 
8351         uint32_t result = val1 ^ imm32;
8352 
8353         EmulateInstruction::Context context;
8354         context.type = EmulateInstruction::eContextImmediate;
8355         context.SetNoArgs ();
8356 
8357         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8358             return false;
8359     }
8360     return true;
8361 }
8362 
8363 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an
8364 // optionally-shifted register value, and writes the result to the destination register.
8365 // It can optionally update the condition flags based on the result.
8366 bool
8367 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding)
8368 {
8369 #if 0
8370     // ARM pseudo code...
8371     if ConditionPassed() then
8372         EncodingSpecificOperations();
8373         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8374         result = R[n] EOR shifted;
8375         if d == 15 then         // Can only occur for ARM encoding
8376             ALUWritePC(result); // setflags is always FALSE here
8377         else
8378             R[d] = result;
8379             if setflags then
8380                 APSR.N = result<31>;
8381                 APSR.Z = IsZeroBit(result);
8382                 APSR.C = carry;
8383                 // APSR.V unchanged
8384 #endif
8385 
8386     bool success = false;
8387 
8388     if (ConditionPassed(opcode))
8389     {
8390         uint32_t Rd, Rn, Rm;
8391         ARM_ShifterType shift_t;
8392         uint32_t shift_n; // the shift applied to the value read from Rm
8393         bool setflags;
8394         uint32_t carry;
8395         switch (encoding)
8396         {
8397         case eEncodingT1:
8398             Rd = Rn = Bits32(opcode, 2, 0);
8399             Rm = Bits32(opcode, 5, 3);
8400             setflags = !InITBlock();
8401             shift_t = SRType_LSL;
8402             shift_n = 0;
8403             break;
8404         case eEncodingT2:
8405             Rd = Bits32(opcode, 11, 8);
8406             Rn = Bits32(opcode, 19, 16);
8407             Rm = Bits32(opcode, 3, 0);
8408             setflags = BitIsSet(opcode, 20);
8409             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8410             // if Rd == '1111' && S == '1' then SEE TEQ (register);
8411             if (Rd == 15 && setflags)
8412                 return EmulateTEQReg (opcode, eEncodingT1);
8413             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8414                 return false;
8415             break;
8416         case eEncodingA1:
8417             Rd = Bits32(opcode, 15, 12);
8418             Rn = Bits32(opcode, 19, 16);
8419             Rm = Bits32(opcode, 3, 0);
8420             setflags = BitIsSet(opcode, 20);
8421             shift_n = DecodeImmShiftARM(opcode, shift_t);
8422 
8423             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8424             if (Rd == 15 && setflags)
8425                 return EmulateSUBSPcLrEtc (opcode, encoding);
8426             break;
8427         default:
8428             return false;
8429         }
8430 
8431         // Read the first operand.
8432         uint32_t val1 = ReadCoreReg(Rn, &success);
8433         if (!success)
8434             return false;
8435 
8436         // Read the second operand.
8437         uint32_t val2 = ReadCoreReg(Rm, &success);
8438         if (!success)
8439             return false;
8440 
8441         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8442         if (!success)
8443             return false;
8444         uint32_t result = val1 ^ shifted;
8445 
8446         EmulateInstruction::Context context;
8447         context.type = EmulateInstruction::eContextImmediate;
8448         context.SetNoArgs ();
8449 
8450         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8451             return false;
8452     }
8453     return true;
8454 }
8455 
8456 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and
8457 // writes the result to the destination register.  It can optionally update the condition flags based
8458 // on the result.
8459 bool
8460 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding)
8461 {
8462 #if 0
8463     // ARM pseudo code...
8464     if ConditionPassed() then
8465         EncodingSpecificOperations();
8466         result = R[n] OR imm32;
8467         if d == 15 then         // Can only occur for ARM encoding
8468             ALUWritePC(result); // setflags is always FALSE here
8469         else
8470             R[d] = result;
8471             if setflags then
8472                 APSR.N = result<31>;
8473                 APSR.Z = IsZeroBit(result);
8474                 APSR.C = carry;
8475                 // APSR.V unchanged
8476 #endif
8477 
8478     bool success = false;
8479 
8480     if (ConditionPassed(opcode))
8481     {
8482         uint32_t Rd, Rn;
8483         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8484         bool setflags;
8485         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8486         switch (encoding)
8487         {
8488         case eEncodingT1:
8489             Rd = Bits32(opcode, 11, 8);
8490             Rn = Bits32(opcode, 19, 16);
8491             setflags = BitIsSet(opcode, 20);
8492             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8493             // if Rn == '1111' then SEE MOV (immediate);
8494             if (Rn == 15)
8495                 return EmulateMOVRdImm (opcode, eEncodingT2);
8496             if (BadReg(Rd) || Rn == 13)
8497                 return false;
8498             break;
8499         case eEncodingA1:
8500             Rd = Bits32(opcode, 15, 12);
8501             Rn = Bits32(opcode, 19, 16);
8502             setflags = BitIsSet(opcode, 20);
8503             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8504 
8505             if (Rd == 15 && setflags)
8506                 return EmulateSUBSPcLrEtc (opcode, encoding);
8507             break;
8508         default:
8509             return false;
8510         }
8511 
8512         // Read the first operand.
8513         uint32_t val1 = ReadCoreReg(Rn, &success);
8514         if (!success)
8515             return false;
8516 
8517         uint32_t result = val1 | imm32;
8518 
8519         EmulateInstruction::Context context;
8520         context.type = EmulateInstruction::eContextImmediate;
8521         context.SetNoArgs ();
8522 
8523         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8524             return false;
8525     }
8526     return true;
8527 }
8528 
8529 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register
8530 // value, and writes the result to the destination register.  It can optionally update the condition flags based
8531 // on the result.
8532 bool
8533 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding)
8534 {
8535 #if 0
8536     // ARM pseudo code...
8537     if ConditionPassed() then
8538         EncodingSpecificOperations();
8539         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8540         result = R[n] OR shifted;
8541         if d == 15 then         // Can only occur for ARM encoding
8542             ALUWritePC(result); // setflags is always FALSE here
8543         else
8544             R[d] = result;
8545             if setflags then
8546                 APSR.N = result<31>;
8547                 APSR.Z = IsZeroBit(result);
8548                 APSR.C = carry;
8549                 // APSR.V unchanged
8550 #endif
8551 
8552     bool success = false;
8553 
8554     if (ConditionPassed(opcode))
8555     {
8556         uint32_t Rd, Rn, Rm;
8557         ARM_ShifterType shift_t;
8558         uint32_t shift_n; // the shift applied to the value read from Rm
8559         bool setflags;
8560         uint32_t carry;
8561         switch (encoding)
8562         {
8563         case eEncodingT1:
8564             Rd = Rn = Bits32(opcode, 2, 0);
8565             Rm = Bits32(opcode, 5, 3);
8566             setflags = !InITBlock();
8567             shift_t = SRType_LSL;
8568             shift_n = 0;
8569             break;
8570         case eEncodingT2:
8571             Rd = Bits32(opcode, 11, 8);
8572             Rn = Bits32(opcode, 19, 16);
8573             Rm = Bits32(opcode, 3, 0);
8574             setflags = BitIsSet(opcode, 20);
8575             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8576             // if Rn == '1111' then SEE MOV (register);
8577             if (Rn == 15)
8578                 return EmulateMOVRdRm (opcode, eEncodingT3);
8579             if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
8580                 return false;
8581             break;
8582         case eEncodingA1:
8583             Rd = Bits32(opcode, 15, 12);
8584             Rn = Bits32(opcode, 19, 16);
8585             Rm = Bits32(opcode, 3, 0);
8586             setflags = BitIsSet(opcode, 20);
8587             shift_n = DecodeImmShiftARM(opcode, shift_t);
8588 
8589             if (Rd == 15 && setflags)
8590                 return EmulateSUBSPcLrEtc (opcode, encoding);
8591             break;
8592         default:
8593             return false;
8594         }
8595 
8596         // Read the first operand.
8597         uint32_t val1 = ReadCoreReg(Rn, &success);
8598         if (!success)
8599             return false;
8600 
8601         // Read the second operand.
8602         uint32_t val2 = ReadCoreReg(Rm, &success);
8603         if (!success)
8604             return false;
8605 
8606         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8607         if (!success)
8608             return false;
8609         uint32_t result = val1 | shifted;
8610 
8611         EmulateInstruction::Context context;
8612         context.type = EmulateInstruction::eContextImmediate;
8613         context.SetNoArgs ();
8614 
8615         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8616             return false;
8617     }
8618     return true;
8619 }
8620 
8621 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to
8622 // the destination register. It can optionally update the condition flags based on the result.
8623 bool
8624 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding)
8625 {
8626 #if 0
8627     // ARM pseudo code...
8628     if ConditionPassed() then
8629         EncodingSpecificOperations();
8630         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
8631         if d == 15 then         // Can only occur for ARM encoding
8632             ALUWritePC(result); // setflags is always FALSE here
8633         else
8634             R[d] = result;
8635             if setflags then
8636                 APSR.N = result<31>;
8637                 APSR.Z = IsZeroBit(result);
8638                 APSR.C = carry;
8639                 APSR.V = overflow;
8640 #endif
8641 
8642     bool success = false;
8643 
8644     uint32_t Rd; // the destination register
8645     uint32_t Rn; // the first operand
8646     bool setflags;
8647     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8648     switch (encoding) {
8649     case eEncodingT1:
8650         Rd = Bits32(opcode, 2, 0);
8651         Rn = Bits32(opcode, 5, 3);
8652         setflags = !InITBlock();
8653         imm32 = 0;
8654         break;
8655     case eEncodingT2:
8656         Rd = Bits32(opcode, 11, 8);
8657         Rn = Bits32(opcode, 19, 16);
8658         setflags = BitIsSet(opcode, 20);
8659         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8660         if (BadReg(Rd) || BadReg(Rn))
8661             return false;
8662         break;
8663     case eEncodingA1:
8664         Rd = Bits32(opcode, 15, 12);
8665         Rn = Bits32(opcode, 19, 16);
8666         setflags = BitIsSet(opcode, 20);
8667         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8668 
8669         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8670         if (Rd == 15 && setflags)
8671             return EmulateSUBSPcLrEtc (opcode, encoding);
8672         break;
8673     default:
8674         return false;
8675     }
8676     // Read the register value from the operand register Rn.
8677     uint32_t reg_val = ReadCoreReg(Rn, &success);
8678     if (!success)
8679         return false;
8680 
8681     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
8682 
8683     EmulateInstruction::Context context;
8684     context.type = EmulateInstruction::eContextImmediate;
8685     context.SetNoArgs ();
8686 
8687     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8688         return false;
8689 
8690     return true;
8691 }
8692 
8693 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the
8694 // result to the destination register. It can optionally update the condition flags based on the result.
8695 bool
8696 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding)
8697 {
8698 #if 0
8699     // ARM pseudo code...
8700     if ConditionPassed() then
8701         EncodingSpecificOperations();
8702         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8703         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
8704         if d == 15 then         // Can only occur for ARM encoding
8705             ALUWritePC(result); // setflags is always FALSE here
8706         else
8707             R[d] = result;
8708             if setflags then
8709                 APSR.N = result<31>;
8710                 APSR.Z = IsZeroBit(result);
8711                 APSR.C = carry;
8712                 APSR.V = overflow;
8713 #endif
8714 
8715     bool success = false;
8716 
8717     uint32_t Rd; // the destination register
8718     uint32_t Rn; // the first operand
8719     uint32_t Rm; // the second operand
8720     bool setflags;
8721     ARM_ShifterType shift_t;
8722     uint32_t shift_n; // the shift applied to the value read from Rm
8723     switch (encoding) {
8724     case eEncodingT1:
8725         Rd = Bits32(opcode, 11, 8);
8726         Rn = Bits32(opcode, 19, 16);
8727         Rm = Bits32(opcode, 3, 0);
8728         setflags = BitIsSet(opcode, 20);
8729         shift_n = DecodeImmShiftThumb(opcode, shift_t);
8730         // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
8731         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8732             return false;
8733         break;
8734     case eEncodingA1:
8735         Rd = Bits32(opcode, 15, 12);
8736         Rn = Bits32(opcode, 19, 16);
8737         Rm = Bits32(opcode, 3, 0);
8738         setflags = BitIsSet(opcode, 20);
8739         shift_n = DecodeImmShiftARM(opcode, shift_t);
8740 
8741         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8742         if (Rd == 15 && setflags)
8743             return EmulateSUBSPcLrEtc (opcode, encoding);
8744         break;
8745     default:
8746         return false;
8747     }
8748     // Read the register value from register Rn.
8749     uint32_t val1 = ReadCoreReg(Rn, &success);
8750     if (!success)
8751         return false;
8752 
8753     // Read the register value from register Rm.
8754     uint32_t val2 = ReadCoreReg(Rm, &success);
8755     if (!success)
8756         return false;
8757 
8758     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8759     if (!success)
8760         return false;
8761     AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
8762 
8763     EmulateInstruction::Context context;
8764     context.type = EmulateInstruction::eContextImmediate;
8765     context.SetNoArgs();
8766     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8767         return false;
8768 
8769     return true;
8770 }
8771 
8772 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from
8773 // an immediate value, and writes the result to the destination register. It can optionally update the condition
8774 // flags based on the result.
8775 bool
8776 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding)
8777 {
8778 #if 0
8779     // ARM pseudo code...
8780     if ConditionPassed() then
8781         EncodingSpecificOperations();
8782         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
8783         if d == 15 then
8784             ALUWritePC(result); // setflags is always FALSE here
8785         else
8786             R[d] = result;
8787             if setflags then
8788                 APSR.N = result<31>;
8789                 APSR.Z = IsZeroBit(result);
8790                 APSR.C = carry;
8791                 APSR.V = overflow;
8792 #endif
8793 
8794     bool success = false;
8795 
8796     uint32_t Rd; // the destination register
8797     uint32_t Rn; // the first operand
8798     bool setflags;
8799     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8800     switch (encoding) {
8801     case eEncodingA1:
8802         Rd = Bits32(opcode, 15, 12);
8803         Rn = Bits32(opcode, 19, 16);
8804         setflags = BitIsSet(opcode, 20);
8805         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8806 
8807         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8808         if (Rd == 15 && setflags)
8809             return EmulateSUBSPcLrEtc  (opcode, encoding);
8810         break;
8811     default:
8812         return false;
8813     }
8814     // Read the register value from the operand register Rn.
8815     uint32_t reg_val = ReadCoreReg(Rn, &success);
8816     if (!success)
8817         return false;
8818 
8819     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
8820 
8821     EmulateInstruction::Context context;
8822     context.type = EmulateInstruction::eContextImmediate;
8823     context.SetNoArgs ();
8824 
8825     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8826         return false;
8827 
8828     return true;
8829 }
8830 
8831 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an
8832 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the
8833 // condition flags based on the result.
8834 bool
8835 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding)
8836 {
8837 #if 0
8838     // ARM pseudo code...
8839     if ConditionPassed() then
8840         EncodingSpecificOperations();
8841         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8842         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
8843         if d == 15 then
8844             ALUWritePC(result); // setflags is always FALSE here
8845         else
8846             R[d] = result;
8847             if setflags then
8848                 APSR.N = result<31>;
8849                 APSR.Z = IsZeroBit(result);
8850                 APSR.C = carry;
8851                 APSR.V = overflow;
8852 #endif
8853 
8854     bool success = false;
8855 
8856     uint32_t Rd; // the destination register
8857     uint32_t Rn; // the first operand
8858     uint32_t Rm; // the second operand
8859     bool setflags;
8860     ARM_ShifterType shift_t;
8861     uint32_t shift_n; // the shift applied to the value read from Rm
8862     switch (encoding) {
8863     case eEncodingA1:
8864         Rd = Bits32(opcode, 15, 12);
8865         Rn = Bits32(opcode, 19, 16);
8866         Rm = Bits32(opcode, 3, 0);
8867         setflags = BitIsSet(opcode, 20);
8868         shift_n = DecodeImmShiftARM(opcode, shift_t);
8869 
8870         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8871         if (Rd == 15 && setflags)
8872             return EmulateSUBSPcLrEtc (opcode, encoding);
8873         break;
8874     default:
8875         return false;
8876     }
8877     // Read the register value from register Rn.
8878     uint32_t val1 = ReadCoreReg(Rn, &success);
8879     if (!success)
8880         return false;
8881 
8882     // Read the register value from register Rm.
8883     uint32_t val2 = ReadCoreReg(Rm, &success);
8884     if (!success)
8885         return false;
8886 
8887     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8888     if (!success)
8889         return false;
8890     AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
8891 
8892     EmulateInstruction::Context context;
8893     context.type = EmulateInstruction::eContextImmediate;
8894     context.SetNoArgs();
8895     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8896         return false;
8897 
8898     return true;
8899 }
8900 
8901 // Subtract with Carry (immediate) subtracts an immediate value and the value of
8902 // NOT (Carry flag) from a register value, and writes the result to the destination register.
8903 // It can optionally update the condition flags based on the result.
8904 bool
8905 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding)
8906 {
8907 #if 0
8908     // ARM pseudo code...
8909     if ConditionPassed() then
8910         EncodingSpecificOperations();
8911         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
8912         if d == 15 then         // Can only occur for ARM encoding
8913             ALUWritePC(result); // setflags is always FALSE here
8914         else
8915             R[d] = result;
8916             if setflags then
8917                 APSR.N = result<31>;
8918                 APSR.Z = IsZeroBit(result);
8919                 APSR.C = carry;
8920                 APSR.V = overflow;
8921 #endif
8922 
8923     bool success = false;
8924 
8925     uint32_t Rd; // the destination register
8926     uint32_t Rn; // the first operand
8927     bool setflags;
8928     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8929     switch (encoding) {
8930     case eEncodingT1:
8931         Rd = Bits32(opcode, 11, 8);
8932         Rn = Bits32(opcode, 19, 16);
8933         setflags = BitIsSet(opcode, 20);
8934         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8935         if (BadReg(Rd) || BadReg(Rn))
8936             return false;
8937         break;
8938     case eEncodingA1:
8939         Rd = Bits32(opcode, 15, 12);
8940         Rn = Bits32(opcode, 19, 16);
8941         setflags = BitIsSet(opcode, 20);
8942         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8943 
8944         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8945         if (Rd == 15 && setflags)
8946             return EmulateSUBSPcLrEtc (opcode, encoding);
8947         break;
8948     default:
8949         return false;
8950     }
8951     // Read the register value from the operand register Rn.
8952     uint32_t reg_val = ReadCoreReg(Rn, &success);
8953     if (!success)
8954         return false;
8955 
8956     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
8957 
8958     EmulateInstruction::Context context;
8959     context.type = EmulateInstruction::eContextImmediate;
8960     context.SetNoArgs ();
8961 
8962     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8963         return false;
8964 
8965     return true;
8966 }
8967 
8968 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of
8969 // NOT (Carry flag) from a register value, and writes the result to the destination register.
8970 // It can optionally update the condition flags based on the result.
8971 bool
8972 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding)
8973 {
8974 #if 0
8975     // ARM pseudo code...
8976     if ConditionPassed() then
8977         EncodingSpecificOperations();
8978         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8979         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
8980         if d == 15 then         // Can only occur for ARM encoding
8981             ALUWritePC(result); // setflags is always FALSE here
8982         else
8983             R[d] = result;
8984             if setflags then
8985                 APSR.N = result<31>;
8986                 APSR.Z = IsZeroBit(result);
8987                 APSR.C = carry;
8988                 APSR.V = overflow;
8989 #endif
8990 
8991     bool success = false;
8992 
8993     uint32_t Rd; // the destination register
8994     uint32_t Rn; // the first operand
8995     uint32_t Rm; // the second operand
8996     bool setflags;
8997     ARM_ShifterType shift_t;
8998     uint32_t shift_n; // the shift applied to the value read from Rm
8999     switch (encoding) {
9000     case eEncodingT1:
9001         Rd = Rn = Bits32(opcode, 2, 0);
9002         Rm = Bits32(opcode, 5, 3);
9003         setflags = !InITBlock();
9004         shift_t = SRType_LSL;
9005         shift_n = 0;
9006         break;
9007     case eEncodingT2:
9008         Rd = Bits32(opcode, 11, 8);
9009         Rn = Bits32(opcode, 19, 16);
9010         Rm = Bits32(opcode, 3, 0);
9011         setflags = BitIsSet(opcode, 20);
9012         shift_n = DecodeImmShiftThumb(opcode, shift_t);
9013         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9014             return false;
9015         break;
9016     case eEncodingA1:
9017         Rd = Bits32(opcode, 15, 12);
9018         Rn = Bits32(opcode, 19, 16);
9019         Rm = Bits32(opcode, 3, 0);
9020         setflags = BitIsSet(opcode, 20);
9021         shift_n = DecodeImmShiftARM(opcode, shift_t);
9022 
9023         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9024         if (Rd == 15 && setflags)
9025             return EmulateSUBSPcLrEtc (opcode, encoding);
9026         break;
9027     default:
9028         return false;
9029     }
9030     // Read the register value from register Rn.
9031     uint32_t val1 = ReadCoreReg(Rn, &success);
9032     if (!success)
9033         return false;
9034 
9035     // Read the register value from register Rm.
9036     uint32_t val2 = ReadCoreReg(Rm, &success);
9037     if (!success)
9038         return false;
9039 
9040     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9041     if (!success)
9042         return false;
9043     AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
9044 
9045     EmulateInstruction::Context context;
9046     context.type = EmulateInstruction::eContextImmediate;
9047     context.SetNoArgs();
9048     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9049         return false;
9050 
9051     return true;
9052 }
9053 
9054 // This instruction subtracts an immediate value from a register value, and writes the result
9055 // to the destination register.  It can optionally update the condition flags based on the result.
9056 bool
9057 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding)
9058 {
9059 #if 0
9060     // ARM pseudo code...
9061     if ConditionPassed() then
9062         EncodingSpecificOperations();
9063         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9064         R[d] = result;
9065         if setflags then
9066             APSR.N = result<31>;
9067             APSR.Z = IsZeroBit(result);
9068             APSR.C = carry;
9069             APSR.V = overflow;
9070 #endif
9071 
9072     bool success = false;
9073 
9074     uint32_t Rd; // the destination register
9075     uint32_t Rn; // the first operand
9076     bool setflags;
9077     uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9078     switch (encoding) {
9079     case eEncodingT1:
9080         Rd = Bits32(opcode, 2, 0);
9081         Rn = Bits32(opcode, 5, 3);
9082         setflags = !InITBlock();
9083         imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9084         break;
9085     case eEncodingT2:
9086         Rd = Rn = Bits32(opcode, 10, 8);
9087         setflags = !InITBlock();
9088         imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9089         break;
9090     case eEncodingT3:
9091         Rd = Bits32(opcode, 11, 8);
9092         Rn = Bits32(opcode, 19, 16);
9093         setflags = BitIsSet(opcode, 20);
9094         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9095 
9096         // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9097         if (Rd == 15 && setflags)
9098             return EmulateCMPImm (opcode, eEncodingT2);
9099 
9100         // if Rn == '1101' then SEE SUB (SP minus immediate);
9101         if (Rn == 13)
9102             return EmulateSUBSPImm (opcode, eEncodingT2);
9103 
9104         // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9105         if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9106             return false;
9107         break;
9108     case eEncodingT4:
9109         Rd = Bits32(opcode, 11, 8);
9110         Rn = Bits32(opcode, 19, 16);
9111         setflags = BitIsSet(opcode, 20);
9112         imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9113 
9114         // if Rn == '1111' then SEE ADR;
9115         if (Rn == 15)
9116             return EmulateADR (opcode, eEncodingT2);
9117 
9118         // if Rn == '1101' then SEE SUB (SP minus immediate);
9119         if (Rn == 13)
9120             return EmulateSUBSPImm (opcode, eEncodingT3);
9121 
9122         if (BadReg(Rd))
9123             return false;
9124         break;
9125     default:
9126         return false;
9127     }
9128     // Read the register value from the operand register Rn.
9129     uint32_t reg_val = ReadCoreReg(Rn, &success);
9130     if (!success)
9131         return false;
9132 
9133     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9134 
9135     EmulateInstruction::Context context;
9136     context.type = EmulateInstruction::eContextImmediate;
9137     context.SetNoArgs ();
9138 
9139     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9140         return false;
9141 
9142     return true;
9143 }
9144 
9145 // This instruction subtracts an immediate value from a register value, and writes the result
9146 // to the destination register.  It can optionally update the condition flags based on the result.
9147 bool
9148 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9149 {
9150 #if 0
9151     // ARM pseudo code...
9152     if ConditionPassed() then
9153         EncodingSpecificOperations();
9154         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9155         if d == 15 then
9156             ALUWritePC(result); // setflags is always FALSE here
9157         else
9158             R[d] = result;
9159             if setflags then
9160                 APSR.N = result<31>;
9161                 APSR.Z = IsZeroBit(result);
9162                 APSR.C = carry;
9163                 APSR.V = overflow;
9164 #endif
9165 
9166     bool success = false;
9167 
9168     uint32_t Rd; // the destination register
9169     uint32_t Rn; // the first operand
9170     bool setflags;
9171     uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9172     switch (encoding) {
9173     case eEncodingA1:
9174         Rd = Bits32(opcode, 15, 12);
9175         Rn = Bits32(opcode, 19, 16);
9176         setflags = BitIsSet(opcode, 20);
9177         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9178 
9179         // if Rn == '1111' && S == '0' then SEE ADR;
9180         if (Rn == 15 && !setflags)
9181             return EmulateADR (opcode, eEncodingA2);
9182 
9183         // if Rn == '1101' then SEE SUB (SP minus immediate);
9184         if (Rn == 13)
9185             return EmulateSUBSPImm (opcode, eEncodingA1);
9186 
9187         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9188         if (Rd == 15 && setflags)
9189             return EmulateSUBSPcLrEtc (opcode, encoding);
9190         break;
9191     default:
9192         return false;
9193     }
9194     // Read the register value from the operand register Rn.
9195     uint32_t reg_val = ReadCoreReg(Rn, &success);
9196     if (!success)
9197         return false;
9198 
9199     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9200 
9201     EmulateInstruction::Context context;
9202     context.type = EmulateInstruction::eContextImmediate;
9203     context.SetNoArgs ();
9204 
9205     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9206         return false;
9207 
9208     return true;
9209 }
9210 
9211 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an
9212 // immediate value.  It updates the condition flags based on the result, and discards the result.
9213 bool
9214 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding)
9215 {
9216 #if 0
9217     // ARM pseudo code...
9218     if ConditionPassed() then
9219         EncodingSpecificOperations();
9220         result = R[n] EOR imm32;
9221         APSR.N = result<31>;
9222         APSR.Z = IsZeroBit(result);
9223         APSR.C = carry;
9224         // APSR.V unchanged
9225 #endif
9226 
9227     bool success = false;
9228 
9229     if (ConditionPassed(opcode))
9230     {
9231         uint32_t Rn;
9232         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9233         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9234         switch (encoding)
9235         {
9236         case eEncodingT1:
9237             Rn = Bits32(opcode, 19, 16);
9238             imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9239             if (BadReg(Rn))
9240                 return false;
9241             break;
9242         case eEncodingA1:
9243             Rn = Bits32(opcode, 19, 16);
9244             imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9245             break;
9246         default:
9247             return false;
9248         }
9249 
9250         // Read the first operand.
9251         uint32_t val1 = ReadCoreReg(Rn, &success);
9252         if (!success)
9253             return false;
9254 
9255         uint32_t result = val1 ^ imm32;
9256 
9257         EmulateInstruction::Context context;
9258         context.type = EmulateInstruction::eContextImmediate;
9259         context.SetNoArgs ();
9260 
9261         if (!WriteFlags(context, result, carry))
9262             return false;
9263     }
9264     return true;
9265 }
9266 
9267 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an
9268 // optionally-shifted register value.  It updates the condition flags based on the result, and discards
9269 // the result.
9270 bool
9271 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding)
9272 {
9273 #if 0
9274     // ARM pseudo code...
9275     if ConditionPassed() then
9276         EncodingSpecificOperations();
9277         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9278         result = R[n] EOR shifted;
9279         APSR.N = result<31>;
9280         APSR.Z = IsZeroBit(result);
9281         APSR.C = carry;
9282         // APSR.V unchanged
9283 #endif
9284 
9285     bool success = false;
9286 
9287     if (ConditionPassed(opcode))
9288     {
9289         uint32_t Rn, Rm;
9290         ARM_ShifterType shift_t;
9291         uint32_t shift_n; // the shift applied to the value read from Rm
9292         uint32_t carry;
9293         switch (encoding)
9294         {
9295         case eEncodingT1:
9296             Rn = Bits32(opcode, 19, 16);
9297             Rm = Bits32(opcode, 3, 0);
9298             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9299             if (BadReg(Rn) || BadReg(Rm))
9300                 return false;
9301             break;
9302         case eEncodingA1:
9303             Rn = Bits32(opcode, 19, 16);
9304             Rm = Bits32(opcode, 3, 0);
9305             shift_n = DecodeImmShiftARM(opcode, shift_t);
9306             break;
9307         default:
9308             return false;
9309         }
9310 
9311         // Read the first operand.
9312         uint32_t val1 = ReadCoreReg(Rn, &success);
9313         if (!success)
9314             return false;
9315 
9316         // Read the second operand.
9317         uint32_t val2 = ReadCoreReg(Rm, &success);
9318         if (!success)
9319             return false;
9320 
9321         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9322         if (!success)
9323             return false;
9324         uint32_t result = val1 ^ shifted;
9325 
9326         EmulateInstruction::Context context;
9327         context.type = EmulateInstruction::eContextImmediate;
9328         context.SetNoArgs ();
9329 
9330         if (!WriteFlags(context, result, carry))
9331             return false;
9332     }
9333     return true;
9334 }
9335 
9336 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value.
9337 // It updates the condition flags based on the result, and discards the result.
9338 bool
9339 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding)
9340 {
9341 #if 0
9342     // ARM pseudo code...
9343     if ConditionPassed() then
9344         EncodingSpecificOperations();
9345         result = R[n] AND imm32;
9346         APSR.N = result<31>;
9347         APSR.Z = IsZeroBit(result);
9348         APSR.C = carry;
9349         // APSR.V unchanged
9350 #endif
9351 
9352     bool success = false;
9353 
9354     if (ConditionPassed(opcode))
9355     {
9356         uint32_t Rn;
9357         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9358         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9359         switch (encoding)
9360         {
9361         case eEncodingT1:
9362             Rn = Bits32(opcode, 19, 16);
9363             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9364             if (BadReg(Rn))
9365                 return false;
9366             break;
9367         case eEncodingA1:
9368             Rn = Bits32(opcode, 19, 16);
9369             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9370             break;
9371         default:
9372             return false;
9373         }
9374 
9375         // Read the first operand.
9376         uint32_t val1 = ReadCoreReg(Rn, &success);
9377         if (!success)
9378             return false;
9379 
9380         uint32_t result = val1 & imm32;
9381 
9382         EmulateInstruction::Context context;
9383         context.type = EmulateInstruction::eContextImmediate;
9384         context.SetNoArgs ();
9385 
9386         if (!WriteFlags(context, result, carry))
9387             return false;
9388     }
9389     return true;
9390 }
9391 
9392 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value.
9393 // It updates the condition flags based on the result, and discards the result.
9394 bool
9395 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding)
9396 {
9397 #if 0
9398     // ARM pseudo code...
9399     if ConditionPassed() then
9400         EncodingSpecificOperations();
9401         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9402         result = R[n] AND shifted;
9403         APSR.N = result<31>;
9404         APSR.Z = IsZeroBit(result);
9405         APSR.C = carry;
9406         // APSR.V unchanged
9407 #endif
9408 
9409     bool success = false;
9410 
9411     if (ConditionPassed(opcode))
9412     {
9413         uint32_t Rn, Rm;
9414         ARM_ShifterType shift_t;
9415         uint32_t shift_n; // the shift applied to the value read from Rm
9416         uint32_t carry;
9417         switch (encoding)
9418         {
9419         case eEncodingT1:
9420             Rn = Bits32(opcode, 2, 0);
9421             Rm = Bits32(opcode, 5, 3);
9422             shift_t = SRType_LSL;
9423             shift_n = 0;
9424             break;
9425         case eEncodingT2:
9426             Rn = Bits32(opcode, 19, 16);
9427             Rm = Bits32(opcode, 3, 0);
9428             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9429             if (BadReg(Rn) || BadReg(Rm))
9430                 return false;
9431             break;
9432         case eEncodingA1:
9433             Rn = Bits32(opcode, 19, 16);
9434             Rm = Bits32(opcode, 3, 0);
9435             shift_n = DecodeImmShiftARM(opcode, shift_t);
9436             break;
9437         default:
9438             return false;
9439         }
9440 
9441         // Read the first operand.
9442         uint32_t val1 = ReadCoreReg(Rn, &success);
9443         if (!success)
9444             return false;
9445 
9446         // Read the second operand.
9447         uint32_t val2 = ReadCoreReg(Rm, &success);
9448         if (!success)
9449             return false;
9450 
9451         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9452         if (!success)
9453             return false;
9454         uint32_t result = val1 & shifted;
9455 
9456         EmulateInstruction::Context context;
9457         context.type = EmulateInstruction::eContextImmediate;
9458         context.SetNoArgs ();
9459 
9460         if (!WriteFlags(context, result, carry))
9461             return false;
9462     }
9463     return true;
9464 }
9465 
9466 // A8.6.216 SUB (SP minus register)
9467 bool
9468 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding)
9469 {
9470 #if 0
9471     if ConditionPassed() then
9472         EncodingSpecificOperations();
9473         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9474         (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9475         if d == 15 then // Can only occur for ARM encoding
9476             ALUWritePC(result); // setflags is always FALSE here
9477         else
9478             R[d] = result;
9479             if setflags then
9480                 APSR.N = result<31>;
9481                 APSR.Z = IsZeroBit(result);
9482                 APSR.C = carry;
9483                 APSR.V = overflow;
9484 #endif
9485 
9486     bool success = false;
9487 
9488     if (ConditionPassed(opcode))
9489     {
9490         uint32_t d;
9491         uint32_t m;
9492         bool setflags;
9493         ARM_ShifterType shift_t;
9494         uint32_t shift_n;
9495 
9496         switch (encoding)
9497         {
9498             case eEncodingT1:
9499                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9500                 d = Bits32 (opcode, 11, 8);
9501                 m = Bits32 (opcode, 3, 0);
9502                 setflags = BitIsSet (opcode, 20);
9503 
9504                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9505                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9506 
9507                 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE;
9508                 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
9509                     return false;
9510 
9511                 // if d == 15 || BadReg(m) then UNPREDICTABLE;
9512                 if ((d == 15) || BadReg (m))
9513                     return false;
9514                 break;
9515 
9516             case eEncodingA1:
9517                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9518                 d = Bits32 (opcode, 15, 12);
9519                 m = Bits32 (opcode, 3, 0);
9520                 setflags = BitIsSet (opcode, 20);
9521 
9522                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9523                 if (d == 15 && setflags)
9524                     EmulateSUBSPcLrEtc (opcode, encoding);
9525 
9526                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9527                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9528                 break;
9529 
9530             default:
9531                 return false;
9532         }
9533 
9534         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9535         uint32_t Rm = ReadCoreReg (m, &success);
9536         if (!success)
9537             return false;
9538 
9539         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9540         if (!success)
9541             return false;
9542 
9543         // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9544         uint32_t sp_val = ReadCoreReg (SP_REG, &success);
9545         if (!success)
9546             return false;
9547 
9548         AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1);
9549 
9550         EmulateInstruction::Context context;
9551         context.type = eContextArithmetic;
9552         RegisterInfo sp_reg;
9553         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
9554         RegisterInfo dwarf_reg;
9555         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
9556         context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
9557 
9558         if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9559             return false;
9560     }
9561     return true;
9562 }
9563 
9564 
9565 // A8.6.7 ADD (register-shifted register)
9566 bool
9567 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding)
9568 {
9569 #if 0
9570     if ConditionPassed() then
9571         EncodingSpecificOperations();
9572         shift_n = UInt(R[s]<7:0>);
9573         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9574         (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9575         R[d] = result;
9576         if setflags then
9577             APSR.N = result<31>;
9578             APSR.Z = IsZeroBit(result);
9579             APSR.C = carry;
9580             APSR.V = overflow;
9581 #endif
9582 
9583     bool success = false;
9584 
9585     if (ConditionPassed(opcode))
9586     {
9587         uint32_t d;
9588         uint32_t n;
9589         uint32_t m;
9590         uint32_t s;
9591         bool setflags;
9592         ARM_ShifterType shift_t;
9593 
9594         switch (encoding)
9595         {
9596             case eEncodingA1:
9597                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
9598                 d = Bits32 (opcode, 15, 12);
9599                 n = Bits32 (opcode, 19, 16);
9600                 m = Bits32 (opcode, 3, 0);
9601                 s = Bits32 (opcode, 11, 8);
9602 
9603                 // setflags = (S == �1�); shift_t = DecodeRegShift(type);
9604                 setflags = BitIsSet (opcode, 20);
9605                 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5));
9606 
9607                 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
9608                 if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
9609                     return false;
9610                 break;
9611 
9612             default:
9613                 return false;
9614         }
9615 
9616         // shift_n = UInt(R[s]<7:0>);
9617         uint32_t Rs = ReadCoreReg (s, &success);
9618         if (!success)
9619             return false;
9620 
9621         uint32_t shift_n = Bits32 (Rs, 7, 0);
9622 
9623         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9624         uint32_t Rm = ReadCoreReg (m, &success);
9625         if (!success)
9626             return false;
9627 
9628         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9629         if (!success)
9630             return false;
9631 
9632         // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9633         uint32_t Rn = ReadCoreReg (n, &success);
9634         if (!success)
9635             return false;
9636 
9637         AddWithCarryResult res = AddWithCarry (Rn, shifted, 0);
9638 
9639         // R[d] = result;
9640         EmulateInstruction::Context context;
9641         context.type = eContextArithmetic;
9642         RegisterInfo reg_n;
9643         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9644         RegisterInfo reg_m;
9645         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9646 
9647         context.SetRegisterRegisterOperands (reg_n, reg_m);
9648 
9649         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result))
9650             return false;
9651 
9652         // if setflags then
9653             // APSR.N = result<31>;
9654             // APSR.Z = IsZeroBit(result);
9655             // APSR.C = carry;
9656             // APSR.V = overflow;
9657         if (setflags)
9658             return WriteFlags (context, res.result, res.carry_out, res.overflow);
9659     }
9660     return true;
9661 }
9662 
9663 // A8.6.213 SUB (register)
9664 bool
9665 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding)
9666 {
9667 #if 0
9668     if ConditionPassed() then
9669         EncodingSpecificOperations();
9670         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9671         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9672         if d == 15 then // Can only occur for ARM encoding
9673             ALUWritePC(result); // setflags is always FALSE here
9674         else
9675             R[d] = result;
9676             if setflags then
9677                 APSR.N = result<31>;
9678                 APSR.Z = IsZeroBit(result);
9679                 APSR.C = carry;
9680                 APSR.V = overflow;
9681 #endif
9682 
9683     bool success = false;
9684 
9685     if (ConditionPassed(opcode))
9686     {
9687         uint32_t d;
9688         uint32_t n;
9689         uint32_t m;
9690         bool setflags;
9691         ARM_ShifterType shift_t;
9692         uint32_t shift_n;
9693 
9694         switch (encoding)
9695         {
9696             case eEncodingT1:
9697                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
9698                 d = Bits32 (opcode, 2, 0);
9699                 n = Bits32 (opcode, 5, 3);
9700                 m = Bits32 (opcode, 8, 6);
9701                 setflags = !InITBlock();
9702 
9703                 // (shift_t, shift_n) = (SRType_LSL, 0);
9704                 shift_t = SRType_LSL;
9705                 shift_n = 0;
9706 
9707                 break;
9708 
9709             case eEncodingT2:
9710                 // if Rd == �1111� && S == �1� then SEE CMP (register);
9711                 // if Rn == �1101� then SEE SUB (SP minus register);
9712                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9713                 d = Bits32 (opcode, 11, 8);
9714                 n = Bits32 (opcode, 19, 16);
9715                 m = Bits32 (opcode, 3, 0);
9716                 setflags = BitIsSet (opcode, 20);
9717 
9718                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9719                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9720 
9721                 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE;
9722                 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m))
9723                     return false;
9724 
9725                 break;
9726 
9727             case eEncodingA1:
9728                 // if Rn == �1101� then SEE SUB (SP minus register);
9729                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9730                 d = Bits32 (opcode, 15, 12);
9731                 n = Bits32 (opcode, 19, 16);
9732                 m = Bits32 (opcode, 3, 0);
9733                 setflags = BitIsSet (opcode, 20);
9734 
9735                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9736                 if ((d == 15) && setflags)
9737                     EmulateSUBSPcLrEtc (opcode, encoding);
9738 
9739                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9740                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9741 
9742                 break;
9743 
9744             default:
9745                 return false;
9746         }
9747 
9748         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9749         uint32_t Rm = ReadCoreReg (m, &success);
9750         if (!success)
9751             return false;
9752 
9753         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9754         if (!success)
9755             return false;
9756 
9757         // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9758         uint32_t Rn = ReadCoreReg (n, &success);
9759         if (!success)
9760             return false;
9761 
9762         AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1);
9763 
9764         // if d == 15 then // Can only occur for ARM encoding
9765             // ALUWritePC(result); // setflags is always FALSE here
9766         // else
9767             // R[d] = result;
9768             // if setflags then
9769                 // APSR.N = result<31>;
9770                 // APSR.Z = IsZeroBit(result);
9771                 // APSR.C = carry;
9772                 // APSR.V = overflow;
9773 
9774         EmulateInstruction::Context context;
9775         context.type = eContextArithmetic;
9776         RegisterInfo reg_n;
9777         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9778         RegisterInfo reg_m;
9779         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9780         context.SetRegisterRegisterOperands (reg_n, reg_m);
9781 
9782         if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9783             return false;
9784     }
9785     return true;
9786 }
9787 
9788 // A8.6.202 STREX
9789 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a
9790 // word from a register to memory if the executing processor has exclusive access to the memory addressed.
9791 bool
9792 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding)
9793 {
9794 #if 0
9795     if ConditionPassed() then
9796         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9797         address = R[n] + imm32;
9798         if ExclusiveMonitorsPass(address,4) then
9799             MemA[address,4] = R[t];
9800             R[d] = 0;
9801         else
9802             R[d] = 1;
9803 #endif
9804 
9805     bool success = false;
9806 
9807     if (ConditionPassed(opcode))
9808     {
9809         uint32_t d;
9810         uint32_t t;
9811         uint32_t n;
9812         uint32_t imm32;
9813         const uint32_t addr_byte_size = GetAddressByteSize();
9814 
9815         switch (encoding)
9816         {
9817             case eEncodingT1:
9818                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
9819                 d = Bits32 (opcode, 11, 8);
9820                 t = Bits32 (opcode, 15, 12);
9821                 n = Bits32 (opcode, 19, 16);
9822                 imm32 = Bits32 (opcode, 7, 0) << 2;
9823 
9824                 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
9825                 if (BadReg (d) || BadReg (t) || (n == 15))
9826                   return false;
9827 
9828                 // if d == n || d == t then UNPREDICTABLE;
9829                 if ((d == n) || (d == t))
9830                   return false;
9831 
9832                 break;
9833 
9834             case eEncodingA1:
9835                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset
9836                 d = Bits32 (opcode, 15, 12);
9837                 t = Bits32 (opcode, 3, 0);
9838                 n = Bits32 (opcode, 19, 16);
9839                 imm32 = 0;
9840 
9841                 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
9842                 if ((d == 15) || (t == 15) || (n == 15))
9843                     return false;
9844 
9845                 // if d == n || d == t then UNPREDICTABLE;
9846                 if ((d == n) || (d == t))
9847                     return false;
9848 
9849                 break;
9850 
9851             default:
9852                 return false;
9853         }
9854 
9855         // address = R[n] + imm32;
9856         uint32_t Rn = ReadCoreReg (n, &success);
9857         if (!success)
9858             return false;
9859 
9860         addr_t address = Rn + imm32;
9861 
9862         RegisterInfo base_reg;
9863         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9864         RegisterInfo data_reg;
9865         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9866         EmulateInstruction::Context context;
9867         context.type = eContextRegisterStore;
9868         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32);
9869 
9870         // if ExclusiveMonitorsPass(address,4) then
9871         // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this
9872         //                                                         always return true.
9873         if (true)
9874         {
9875             // MemA[address,4] = R[t];
9876             uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
9877             if (!success)
9878                 return false;
9879 
9880             if (!MemAWrite (context, address, Rt, addr_byte_size))
9881                 return false;
9882 
9883             // R[d] = 0;
9884             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0))
9885                 return false;
9886         }
9887 #if 0 // unreachable because if true
9888         else
9889         {
9890             // R[d] = 1;
9891             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
9892                 return false;
9893         }
9894 #endif // unreachable because if true
9895     }
9896     return true;
9897 }
9898 
9899 // A8.6.197 STRB (immediate, ARM)
9900 bool
9901 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9902 {
9903 #if 0
9904     if ConditionPassed() then
9905         EncodingSpecificOperations();
9906         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9907         address = if index then offset_addr else R[n];
9908         MemU[address,1] = R[t]<7:0>;
9909         if wback then R[n] = offset_addr;
9910 #endif
9911 
9912     bool success = false;
9913 
9914     if (ConditionPassed(opcode))
9915     {
9916         uint32_t t;
9917         uint32_t n;
9918         uint32_t imm32;
9919         bool index;
9920         bool add;
9921         bool wback;
9922 
9923         switch (encoding)
9924         {
9925             case eEncodingA1:
9926                 // if P == �0� && W == �1� then SEE STRBT;
9927                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9928                 t = Bits32 (opcode, 15, 12);
9929                 n = Bits32 (opcode, 19, 16);
9930                 imm32 = Bits32 (opcode, 11, 0);
9931 
9932                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9933                 index = BitIsSet (opcode, 24);
9934                 add = BitIsSet (opcode, 23);
9935                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9936 
9937                 // if t == 15 then UNPREDICTABLE;
9938                 if (t == 15)
9939                     return false;
9940 
9941                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9942                 if (wback && ((n == 15) || (n == t)))
9943                     return false;
9944 
9945                 break;
9946 
9947             default:
9948                 return false;
9949         }
9950 
9951         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9952         uint32_t Rn = ReadCoreReg (n, &success);
9953         if (!success)
9954             return false;
9955 
9956         addr_t offset_addr;
9957         if (add)
9958             offset_addr = Rn + imm32;
9959         else
9960             offset_addr = Rn - imm32;
9961 
9962         // address = if index then offset_addr else R[n];
9963         addr_t address;
9964         if (index)
9965             address = offset_addr;
9966         else
9967             address = Rn;
9968 
9969         // MemU[address,1] = R[t]<7:0>;
9970         uint32_t Rt = ReadCoreReg (t, &success);
9971         if (!success)
9972             return false;
9973 
9974         RegisterInfo base_reg;
9975         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9976         RegisterInfo data_reg;
9977         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9978         EmulateInstruction::Context context;
9979         context.type = eContextRegisterStore;
9980         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
9981 
9982         if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1))
9983             return false;
9984 
9985         // if wback then R[n] = offset_addr;
9986         if (wback)
9987         {
9988             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
9989                 return false;
9990         }
9991     }
9992     return true;
9993 }
9994 
9995 // A8.6.194 STR (immediate, ARM)
9996 bool
9997 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding)
9998 {
9999 #if 0
10000     if ConditionPassed() then
10001         EncodingSpecificOperations();
10002         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10003         address = if index then offset_addr else R[n];
10004         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10005         if wback then R[n] = offset_addr;
10006 #endif
10007 
10008     bool success = false;
10009 
10010     if (ConditionPassed(opcode))
10011     {
10012         uint32_t t;
10013         uint32_t n;
10014         uint32_t imm32;
10015         bool index;
10016         bool add;
10017         bool wback;
10018 
10019         const uint32_t addr_byte_size = GetAddressByteSize();
10020 
10021         switch (encoding)
10022         {
10023             case eEncodingA1:
10024                 // if P == �0� && W == �1� then SEE STRT;
10025                 // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH;
10026                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10027                 t = Bits32 (opcode, 15, 12);
10028                 n = Bits32 (opcode, 19, 16);
10029                 imm32 = Bits32 (opcode, 11, 0);
10030 
10031                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10032                 index = BitIsSet (opcode, 24);
10033                 add = BitIsSet (opcode, 23);
10034                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10035 
10036                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10037                 if (wback && ((n == 15) || (n == t)))
10038                     return false;
10039 
10040                 break;
10041 
10042             default:
10043                 return false;
10044         }
10045 
10046         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10047         uint32_t Rn = ReadCoreReg (n, &success);
10048         if (!success)
10049             return false;
10050 
10051         addr_t offset_addr;
10052         if (add)
10053             offset_addr = Rn + imm32;
10054         else
10055             offset_addr = Rn - imm32;
10056 
10057         // address = if index then offset_addr else R[n];
10058         addr_t address;
10059         if (index)
10060             address = offset_addr;
10061         else
10062             address = Rn;
10063 
10064         RegisterInfo base_reg;
10065         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10066         RegisterInfo data_reg;
10067         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10068         EmulateInstruction::Context context;
10069         context.type = eContextRegisterStore;
10070         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10071 
10072         // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10073         uint32_t Rt = ReadCoreReg (t, &success);
10074         if (!success)
10075             return false;
10076 
10077         if (t == 15)
10078         {
10079             uint32_t pc_value = ReadCoreReg (PC_REG, &success);
10080             if (!success)
10081                 return false;
10082 
10083             if (!MemUWrite (context, address, pc_value, addr_byte_size))
10084                 return false;
10085         }
10086         else
10087         {
10088             if (!MemUWrite (context, address, Rt, addr_byte_size))
10089                   return false;
10090         }
10091 
10092         // if wback then R[n] = offset_addr;
10093         if (wback)
10094         {
10095             context.type = eContextAdjustBaseRegister;
10096             context.SetImmediate (offset_addr);
10097 
10098             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10099                 return false;
10100         }
10101     }
10102     return true;
10103 }
10104 
10105 // A8.6.66 LDRD (immediate)
10106 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two
10107 // words from memory, and writes them to two registers.  It can use offset, post-indexed, or pre-indexed addressing.
10108 bool
10109 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding)
10110 {
10111 #if 0
10112     if ConditionPassed() then
10113         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10114         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10115         address = if index then offset_addr else R[n];
10116         R[t] = MemA[address,4];
10117         R[t2] = MemA[address+4,4];
10118         if wback then R[n] = offset_addr;
10119 #endif
10120 
10121     bool success = false;
10122 
10123     if (ConditionPassed(opcode))
10124     {
10125         uint32_t t;
10126         uint32_t t2;
10127         uint32_t n;
10128         uint32_t imm32;
10129         bool index;
10130         bool add;
10131         bool wback;
10132 
10133         switch (encoding)
10134         {
10135             case eEncodingT1:
10136                 //if P == �0� && W == �0� then SEE �Related encodings�;
10137                 //if Rn == �1111� then SEE LDRD (literal);
10138                 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10139                 t = Bits32 (opcode, 15, 12);
10140                 t2 = Bits32 (opcode, 11, 8);
10141                 n = Bits32 (opcode, 19, 16);
10142                 imm32 = Bits32 (opcode, 7, 0) << 2;
10143 
10144                 //index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10145                 index = BitIsSet (opcode, 24);
10146                 add = BitIsSet (opcode, 23);
10147                 wback = BitIsSet (opcode, 21);
10148 
10149                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10150                 if (wback && ((n == t) || (n == t2)))
10151                     return false;
10152 
10153                 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10154                 if (BadReg (t) || BadReg (t2) || (t == t2))
10155                     return false;
10156 
10157                 break;
10158 
10159             case eEncodingA1:
10160                 //if Rn == �1111� then SEE LDRD (literal);
10161                 //if Rt<0> == �1� then UNPREDICTABLE;
10162                 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10163                 t = Bits32 (opcode, 15, 12);
10164                 if (BitIsSet (t, 0))
10165                     return false;
10166                 t2 = t + 1;
10167                 n = Bits32 (opcode, 19, 16);
10168                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10169 
10170                 //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10171                 index = BitIsSet (opcode, 24);
10172                 add = BitIsSet (opcode, 23);
10173                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10174 
10175                 //if P == �0� && W == �1� then UNPREDICTABLE;
10176                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10177                     return false;
10178 
10179                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10180                 if (wback && ((n == t) || (n == t2)))
10181                     return false;
10182 
10183                 //if t2 == 15 then UNPREDICTABLE;
10184                 if (t2 == 15)
10185                     return false;
10186 
10187                 break;
10188 
10189             default:
10190                 return false;
10191         }
10192 
10193         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10194         uint32_t Rn = ReadCoreReg (n, &success);
10195         if (!success)
10196             return false;
10197 
10198         addr_t offset_addr;
10199         if (add)
10200                   offset_addr = Rn + imm32;
10201         else
10202             offset_addr = Rn - imm32;
10203 
10204         //address = if index then offset_addr else R[n];
10205         addr_t address;
10206         if (index)
10207             address = offset_addr;
10208         else
10209             address = Rn;
10210 
10211         //R[t] = MemA[address,4];
10212         RegisterInfo base_reg;
10213         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10214 
10215         EmulateInstruction::Context context;
10216         context.type = eContextRegisterLoad;
10217         context.SetRegisterPlusOffset (base_reg, address - Rn);
10218 
10219         const uint32_t addr_byte_size = GetAddressByteSize();
10220         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10221         if (!success)
10222             return false;
10223 
10224         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10225             return false;
10226 
10227         //R[t2] = MemA[address+4,4];
10228 
10229         context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10230         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10231         if (!success)
10232             return false;
10233 
10234         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10235             return false;
10236 
10237         //if wback then R[n] = offset_addr;
10238         if (wback)
10239         {
10240             context.type = eContextAdjustBaseRegister;
10241             context.SetAddress (offset_addr);
10242 
10243             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10244                 return false;
10245         }
10246     }
10247     return true;
10248 }
10249 
10250 // A8.6.68 LDRD (register)
10251 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two
10252 // words from memory, and writes them to two registers.  It can use offset, post-indexed or pre-indexed addressing.
10253 bool
10254 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding)
10255 {
10256 #if 0
10257     if ConditionPassed() then
10258         EncodingSpecificOperations();
10259         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10260         address = if index then offset_addr else R[n];
10261         R[t] = MemA[address,4];
10262         R[t2] = MemA[address+4,4];
10263         if wback then R[n] = offset_addr;
10264 #endif
10265 
10266     bool success = false;
10267 
10268     if (ConditionPassed(opcode))
10269     {
10270         uint32_t t;
10271         uint32_t t2;
10272         uint32_t n;
10273         uint32_t m;
10274         bool index;
10275         bool add;
10276         bool wback;
10277 
10278         switch (encoding)
10279         {
10280             case eEncodingA1:
10281                 // if Rt<0> == �1� then UNPREDICTABLE;
10282                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10283                 t = Bits32 (opcode, 15, 12);
10284                 if (BitIsSet (t, 0))
10285                     return false;
10286                 t2 = t + 1;
10287                 n = Bits32 (opcode, 19, 16);
10288                 m = Bits32 (opcode, 3, 0);
10289 
10290                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10291                 index = BitIsSet (opcode, 24);
10292                 add = BitIsSet (opcode, 23);
10293                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10294 
10295                 // if P == �0� && W == �1� then UNPREDICTABLE;
10296                   if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10297                   return false;
10298 
10299                 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10300                   if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10301                   return false;
10302 
10303                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10304                   if (wback && ((n == 15) || (n == t) || (n == t2)))
10305                   return false;
10306 
10307                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10308                 if ((ArchVersion() < 6) && wback && (m == n))
10309                   return false;
10310                 break;
10311 
10312             default:
10313                 return false;
10314         }
10315 
10316         uint32_t Rn = ReadCoreReg (n, &success);
10317         if (!success)
10318             return false;
10319         RegisterInfo base_reg;
10320         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10321 
10322         uint32_t Rm = ReadCoreReg (m, &success);
10323         if (!success)
10324             return false;
10325         RegisterInfo offset_reg;
10326         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10327 
10328         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10329         addr_t offset_addr;
10330         if (add)
10331             offset_addr = Rn + Rm;
10332         else
10333             offset_addr = Rn - Rm;
10334 
10335         // address = if index then offset_addr else R[n];
10336         addr_t address;
10337         if (index)
10338             address = offset_addr;
10339         else
10340             address = Rn;
10341 
10342         EmulateInstruction::Context context;
10343         context.type = eContextRegisterLoad;
10344         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
10345 
10346         // R[t] = MemA[address,4];
10347         const uint32_t addr_byte_size = GetAddressByteSize();
10348         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10349         if (!success)
10350             return false;
10351 
10352         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10353             return false;
10354 
10355         // R[t2] = MemA[address+4,4];
10356 
10357         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10358         if (!success)
10359             return false;
10360 
10361         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10362             return false;
10363 
10364         // if wback then R[n] = offset_addr;
10365         if (wback)
10366         {
10367             context.type = eContextAdjustBaseRegister;
10368             context.SetAddress (offset_addr);
10369 
10370             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10371                 return false;
10372         }
10373     }
10374     return true;
10375 }
10376 
10377 // A8.6.200 STRD (immediate)
10378 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and
10379 // stores two words from two registers to memory.  It can use offset, post-indexed, or pre-indexed addressing.
10380 bool
10381 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding)
10382 {
10383 #if 0
10384     if ConditionPassed() then
10385         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10386         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10387         address = if index then offset_addr else R[n];
10388         MemA[address,4] = R[t];
10389         MemA[address+4,4] = R[t2];
10390         if wback then R[n] = offset_addr;
10391 #endif
10392 
10393     bool success = false;
10394 
10395     if (ConditionPassed(opcode))
10396     {
10397         uint32_t t;
10398         uint32_t t2;
10399         uint32_t n;
10400         uint32_t imm32;
10401         bool index;
10402         bool add;
10403         bool wback;
10404 
10405         switch (encoding)
10406         {
10407             case eEncodingT1:
10408                 // if P == �0� && W == �0� then SEE �Related encodings�;
10409                 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10410                 t = Bits32 (opcode, 15, 12);
10411                 t2 = Bits32 (opcode, 11, 8);
10412                 n = Bits32 (opcode, 19, 16);
10413                 imm32 = Bits32 (opcode, 7, 0) << 2;
10414 
10415                 // index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10416                 index = BitIsSet (opcode, 24);
10417                 add = BitIsSet (opcode, 23);
10418                 wback = BitIsSet (opcode, 21);
10419 
10420                 // if wback && (n == t || n == t2) then UNPREDICTABLE;
10421                 if (wback && ((n == t) || (n == t2)))
10422                     return false;
10423 
10424                 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10425                 if ((n == 15) || BadReg (t) || BadReg (t2))
10426                     return false;
10427 
10428                 break;
10429 
10430             case eEncodingA1:
10431                 // if Rt<0> == �1� then UNPREDICTABLE;
10432                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10433                 t = Bits32 (opcode, 15, 12);
10434                 if (BitIsSet (t, 0))
10435                     return false;
10436 
10437                 t2 = t + 1;
10438                 n = Bits32 (opcode, 19, 16);
10439                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10440 
10441                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10442                 index = BitIsSet (opcode, 24);
10443                 add = BitIsSet (opcode, 23);
10444                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10445 
10446                 // if P == �0� && W == �1� then UNPREDICTABLE;
10447                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10448                     return false;
10449 
10450                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10451                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10452                     return false;
10453 
10454                 // if t2 == 15 then UNPREDICTABLE;
10455                 if (t2 == 15)
10456                     return false;
10457 
10458                 break;
10459 
10460             default:
10461                 return false;
10462         }
10463 
10464         RegisterInfo base_reg;
10465         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10466 
10467         uint32_t Rn = ReadCoreReg (n, &success);
10468         if (!success)
10469             return false;
10470 
10471         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10472         addr_t offset_addr;
10473         if (add)
10474             offset_addr = Rn + imm32;
10475         else
10476             offset_addr = Rn - imm32;
10477 
10478         //address = if index then offset_addr else R[n];
10479         addr_t address;
10480         if (index)
10481             address = offset_addr;
10482         else
10483             address = Rn;
10484 
10485         //MemA[address,4] = R[t];
10486         RegisterInfo data_reg;
10487         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10488 
10489         uint32_t data = ReadCoreReg (t, &success);
10490         if (!success)
10491             return false;
10492 
10493         EmulateInstruction::Context context;
10494         context.type = eContextRegisterStore;
10495         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10496 
10497         const uint32_t addr_byte_size = GetAddressByteSize();
10498 
10499         if (!MemAWrite (context, address, data, addr_byte_size))
10500             return false;
10501 
10502         //MemA[address+4,4] = R[t2];
10503         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10504         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10505 
10506         data = ReadCoreReg (t2, &success);
10507         if (!success)
10508             return false;
10509 
10510         if (!MemAWrite (context, address + 4, data, addr_byte_size))
10511             return false;
10512 
10513         //if wback then R[n] = offset_addr;
10514         if (wback)
10515         {
10516             context.type = eContextAdjustBaseRegister;
10517             context.SetAddress (offset_addr);
10518 
10519             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10520                 return false;
10521         }
10522     }
10523     return true;
10524 }
10525 
10526 
10527 // A8.6.201 STRD (register)
10528 bool
10529 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding)
10530 {
10531 #if 0
10532     if ConditionPassed() then
10533         EncodingSpecificOperations();
10534         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10535         address = if index then offset_addr else R[n];
10536         MemA[address,4] = R[t];
10537         MemA[address+4,4] = R[t2];
10538         if wback then R[n] = offset_addr;
10539 #endif
10540 
10541     bool success = false;
10542 
10543     if (ConditionPassed(opcode))
10544     {
10545         uint32_t t;
10546         uint32_t t2;
10547         uint32_t n;
10548         uint32_t m;
10549         bool index;
10550         bool add;
10551         bool wback;
10552 
10553         switch (encoding)
10554         {
10555             case eEncodingA1:
10556                 // if Rt<0> == �1� then UNPREDICTABLE;
10557                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10558                 t = Bits32 (opcode, 15, 12);
10559                 if (BitIsSet (t, 0))
10560                    return false;
10561 
10562                 t2 = t+1;
10563                 n = Bits32 (opcode, 19, 16);
10564                 m = Bits32 (opcode, 3, 0);
10565 
10566                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10567                 index = BitIsSet (opcode, 24);
10568                 add = BitIsSet (opcode, 23);
10569                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10570 
10571                 // if P == �0� && W == �1� then UNPREDICTABLE;
10572                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10573                    return false;
10574 
10575                 // if t2 == 15 || m == 15 then UNPREDICTABLE;
10576                 if ((t2 == 15) || (m == 15))
10577                    return false;
10578 
10579                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10580                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10581                    return false;
10582 
10583                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10584                 if ((ArchVersion() < 6) && wback && (m == n))
10585                    return false;
10586 
10587                 break;
10588 
10589             default:
10590                 return false;
10591         }
10592 
10593         RegisterInfo base_reg;
10594         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10595         RegisterInfo offset_reg;
10596         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10597         RegisterInfo data_reg;
10598 
10599         uint32_t Rn = ReadCoreReg (n, &success);
10600         if (!success)
10601             return false;
10602 
10603         uint32_t Rm = ReadCoreReg (m, &success);
10604         if (!success)
10605             return false;
10606 
10607         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10608         addr_t offset_addr;
10609         if (add)
10610             offset_addr = Rn + Rm;
10611         else
10612             offset_addr = Rn - Rm;
10613 
10614         // address = if index then offset_addr else R[n];
10615         addr_t address;
10616         if (index)
10617             address = offset_addr;
10618         else
10619             address = Rn;
10620                           // MemA[address,4] = R[t];
10621         uint32_t Rt = ReadCoreReg (t, &success);
10622         if (!success)
10623             return false;
10624 
10625         EmulateInstruction::Context context;
10626         context.type = eContextRegisterStore;
10627         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10628         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10629 
10630         const uint32_t addr_byte_size = GetAddressByteSize();
10631 
10632         if (!MemAWrite (context, address, Rt, addr_byte_size))
10633             return false;
10634 
10635         // MemA[address+4,4] = R[t2];
10636         uint32_t Rt2 = ReadCoreReg (t2, &success);
10637         if (!success)
10638             return false;
10639 
10640         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10641 
10642         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10643 
10644         if (!MemAWrite (context, address + 4, Rt2, addr_byte_size))
10645             return false;
10646 
10647         // if wback then R[n] = offset_addr;
10648         if (wback)
10649         {
10650             context.type = eContextAdjustBaseRegister;
10651             context.SetAddress (offset_addr);
10652 
10653             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10654                 return false;
10655 
10656         }
10657     }
10658     return true;
10659 }
10660 
10661 // A8.6.319 VLDM
10662 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from
10663 // an ARM core register.
10664 bool
10665 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding)
10666 {
10667 #if 0
10668     if ConditionPassed() then
10669         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10670         address = if add then R[n] else R[n]-imm32;
10671         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10672         for r = 0 to regs-1
10673             if single_regs then
10674                 S[d+r] = MemA[address,4]; address = address+4;
10675             else
10676                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10677                 // Combine the word-aligned words in the correct order for current endianness.
10678                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10679 #endif
10680 
10681     bool success = false;
10682 
10683     if (ConditionPassed(opcode))
10684     {
10685         bool single_regs;
10686         bool add;
10687         bool wback;
10688         uint32_t d;
10689         uint32_t n;
10690         uint32_t imm32;
10691         uint32_t regs;
10692 
10693         switch (encoding)
10694         {
10695             case eEncodingT1:
10696             case eEncodingA1:
10697                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10698                 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10699                 // if P == �1� && W == �0� then SEE VLDR;
10700                 // if P == U && W == �1� then UNDEFINED;
10701                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10702                     return false;
10703 
10704                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10705                 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10706                 single_regs = false;
10707                 add = BitIsSet (opcode, 23);
10708                 wback = BitIsSet (opcode, 21);
10709 
10710                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10711                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10712                 n = Bits32 (opcode, 19, 16);
10713                 imm32 = Bits32 (opcode, 7, 0) << 2;
10714 
10715                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�.
10716                 regs = Bits32 (opcode, 7, 0) / 2;
10717 
10718                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10719                 if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
10720                     return false;
10721 
10722                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10723                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10724                     return false;
10725 
10726                 break;
10727 
10728             case eEncodingT2:
10729             case eEncodingA2:
10730                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10731                 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10732                 // if P == �1� && W == �0� then SEE VLDR;
10733                 // if P == U && W == �1� then UNDEFINED;
10734                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10735                     return false;
10736 
10737                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10738                 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10739                 single_regs = true;
10740                 add = BitIsSet (opcode, 23);
10741                 wback = BitIsSet (opcode, 21);
10742                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10743                 n = Bits32 (opcode, 19, 16);
10744 
10745                 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10746                 imm32 = Bits32 (opcode, 7, 0) << 2;
10747                 regs = Bits32 (opcode, 7, 0);
10748 
10749                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10750                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10751                     return false;
10752 
10753                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10754                 if ((regs == 0) || ((d + regs) > 32))
10755                     return false;
10756                 break;
10757 
10758             default:
10759                 return false;
10760         }
10761 
10762         RegisterInfo base_reg;
10763         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10764 
10765         uint32_t Rn = ReadCoreReg (n, &success);
10766         if (!success)
10767             return false;
10768 
10769         // address = if add then R[n] else R[n]-imm32;
10770         addr_t address;
10771         if (add)
10772             address = Rn;
10773         else
10774             address = Rn - imm32;
10775 
10776         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10777         EmulateInstruction::Context context;
10778 
10779         if (wback)
10780         {
10781             uint32_t value;
10782             if (add)
10783                 value = Rn + imm32;
10784             else
10785                 value = Rn - imm32;
10786 
10787             context.type = eContextAdjustBaseRegister;
10788             context.SetImmediateSigned (value - Rn);
10789             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10790                 return false;
10791 
10792         }
10793 
10794         const uint32_t addr_byte_size = GetAddressByteSize();
10795         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10796 
10797         context.type = eContextRegisterLoad;
10798 
10799         // for r = 0 to regs-1
10800         for (uint32_t r = 0; r < regs; ++r)
10801         {
10802             if (single_regs)
10803             {
10804                 // S[d+r] = MemA[address,4]; address = address+4;
10805                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10806 
10807                 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10808                 if (!success)
10809                     return false;
10810 
10811                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10812                     return false;
10813 
10814                 address = address + 4;
10815             }
10816             else
10817             {
10818                 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10819                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10820                 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10821                 if (!success)
10822                     return false;
10823 
10824                 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10825                 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10826                 if (!success)
10827                     return false;
10828 
10829                 address = address + 8;
10830                 // // Combine the word-aligned words in the correct order for current endianness.
10831                 // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10832                 uint64_t data;
10833                 if (GetByteOrder() == eByteOrderBig)
10834                 {
10835                     data = word1;
10836                     data = (data << 32) | word2;
10837                 }
10838                 else
10839                 {
10840                     data = word2;
10841                     data = (data << 32) | word1;
10842                 }
10843 
10844                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10845                     return false;
10846             }
10847         }
10848     }
10849     return true;
10850 }
10851 
10852 // A8.6.399 VSTM
10853 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an
10854 // ARM core register.
10855 bool
10856 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding)
10857 {
10858 #if 0
10859     if ConditionPassed() then
10860         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10861         address = if add then R[n] else R[n]-imm32;
10862         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10863         for r = 0 to regs-1
10864             if single_regs then
10865                 MemA[address,4] = S[d+r]; address = address+4;
10866             else
10867                 // Store as two word-aligned words in the correct order for current endianness.
10868                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10869                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10870                 address = address+8;
10871 #endif
10872 
10873     bool success = false;
10874 
10875     if (ConditionPassed (opcode))
10876     {
10877         bool single_regs;
10878         bool add;
10879         bool wback;
10880         uint32_t d;
10881         uint32_t n;
10882         uint32_t imm32;
10883         uint32_t regs;
10884 
10885         switch (encoding)
10886         {
10887             case eEncodingT1:
10888             case eEncodingA1:
10889                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10890                 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10891                 // if P == �1� && W == �0� then SEE VSTR;
10892                 // if P == U && W == �1� then UNDEFINED;
10893                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10894                     return false;
10895 
10896                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10897                 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10898                 single_regs = false;
10899                 add = BitIsSet (opcode, 23);
10900                 wback = BitIsSet (opcode, 21);
10901 
10902                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10903                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10904                 n = Bits32 (opcode, 19, 16);
10905                 imm32 = Bits32 (opcode, 7, 0) << 2;
10906 
10907                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�.
10908                 regs = Bits32 (opcode, 7, 0) / 2;
10909 
10910                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10911                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10912                     return false;
10913 
10914                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10915                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10916                     return false;
10917 
10918                 break;
10919 
10920             case eEncodingT2:
10921             case eEncodingA2:
10922                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10923                 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10924                 // if P == �1� && W == �0� then SEE VSTR;
10925                 // if P == U && W == �1� then UNDEFINED;
10926                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10927                     return false;
10928 
10929                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10930                 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10931                 single_regs = true;
10932                 add = BitIsSet (opcode, 23);
10933                 wback = BitIsSet (opcode, 21);
10934                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10935                 n = Bits32 (opcode, 19, 16);
10936 
10937                 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10938                 imm32 = Bits32 (opcode, 7, 0) << 2;
10939                 regs = Bits32 (opcode, 7, 0);
10940 
10941                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10942                 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM)))
10943                     return false;
10944 
10945                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10946                 if ((regs == 0) || ((d + regs) > 32))
10947                     return false;
10948 
10949                 break;
10950 
10951             default:
10952                 return false;
10953         }
10954 
10955         RegisterInfo base_reg;
10956         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10957 
10958         uint32_t Rn = ReadCoreReg (n, &success);
10959         if (!success)
10960             return false;
10961 
10962         // address = if add then R[n] else R[n]-imm32;
10963         addr_t address;
10964         if (add)
10965             address = Rn;
10966         else
10967             address = Rn - imm32;
10968 
10969         EmulateInstruction::Context context;
10970         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10971         if (wback)
10972         {
10973             uint32_t value;
10974             if (add)
10975                 value = Rn + imm32;
10976             else
10977                 value = Rn - imm32;
10978 
10979             context.type = eContextAdjustBaseRegister;
10980             context.SetRegisterPlusOffset (base_reg, value - Rn);
10981 
10982             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10983                 return false;
10984         }
10985 
10986         const uint32_t addr_byte_size = GetAddressByteSize();
10987         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10988 
10989         context.type = eContextRegisterStore;
10990         // for r = 0 to regs-1
10991         for (uint32_t r = 0; r < regs; ++r)
10992         {
10993 
10994             if (single_regs)
10995             {
10996                 // MemA[address,4] = S[d+r]; address = address+4;
10997                 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10998                 if (!success)
10999                     return false;
11000 
11001                 RegisterInfo data_reg;
11002                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
11003                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11004                 if (!MemAWrite (context, address, data, addr_byte_size))
11005                     return false;
11006 
11007                 address = address + 4;
11008             }
11009             else
11010             {
11011                 // // Store as two word-aligned words in the correct order for current endianness.
11012                 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
11013                 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
11014                 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
11015                 if (!success)
11016                     return false;
11017 
11018                 RegisterInfo data_reg;
11019                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
11020 
11021                 if (GetByteOrder() == eByteOrderBig)
11022                 {
11023                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11024                     if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11025                         return false;
11026 
11027                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11028                     if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size))
11029                         return false;
11030                 }
11031                 else
11032                 {
11033                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11034                     if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11035                         return false;
11036 
11037                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11038                     if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11039                         return false;
11040                 }
11041                 // address = address+8;
11042                 address = address + 8;
11043             }
11044         }
11045     }
11046     return true;
11047 }
11048 
11049 // A8.6.320
11050 // This instruction loads a single extension register from memory, using an address from an ARM core register, with
11051 // an optional offset.
11052 bool
11053 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
11054 {
11055 #if 0
11056     if ConditionPassed() then
11057         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11058         base = if n == 15 then Align(PC,4) else R[n];
11059         address = if add then (base + imm32) else (base - imm32);
11060         if single_reg then
11061             S[d] = MemA[address,4];
11062         else
11063             word1 = MemA[address,4]; word2 = MemA[address+4,4];
11064             // Combine the word-aligned words in the correct order for current endianness.
11065             D[d] = if BigEndian() then word1:word2 else word2:word1;
11066 #endif
11067 
11068     bool success = false;
11069 
11070     if (ConditionPassed (opcode))
11071     {
11072         bool single_reg;
11073         bool add;
11074         uint32_t imm32;
11075         uint32_t d;
11076         uint32_t n;
11077 
11078         switch (encoding)
11079         {
11080             case eEncodingT1:
11081             case eEncodingA1:
11082                 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11083                 single_reg = false;
11084                 add = BitIsSet (opcode, 23);
11085                 imm32 = Bits32 (opcode, 7, 0) << 2;
11086 
11087                 // d = UInt(D:Vd); n = UInt(Rn);
11088                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11089                 n = Bits32 (opcode, 19, 16);
11090 
11091                 break;
11092 
11093             case eEncodingT2:
11094             case eEncodingA2:
11095                 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11096                 single_reg = true;
11097                 add = BitIsSet (opcode, 23);
11098                 imm32 = Bits32 (opcode, 7, 0) << 2;
11099 
11100                 // d = UInt(Vd:D); n = UInt(Rn);
11101                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11102                 n = Bits32 (opcode, 19, 16);
11103 
11104                 break;
11105 
11106             default:
11107                 return false;
11108         }
11109         RegisterInfo base_reg;
11110         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11111 
11112         uint32_t Rn = ReadCoreReg (n, &success);
11113         if (!success)
11114             return false;
11115 
11116         // base = if n == 15 then Align(PC,4) else R[n];
11117         uint32_t base;
11118         if (n == 15)
11119             base = AlignPC (Rn);
11120         else
11121             base = Rn;
11122 
11123         // address = if add then (base + imm32) else (base - imm32);
11124         addr_t address;
11125         if (add)
11126             address = base + imm32;
11127         else
11128             address = base - imm32;
11129 
11130         const uint32_t addr_byte_size = GetAddressByteSize();
11131         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11132 
11133         EmulateInstruction::Context context;
11134         context.type = eContextRegisterLoad;
11135         context.SetRegisterPlusOffset (base_reg, address - base);
11136 
11137         if (single_reg)
11138         {
11139             // S[d] = MemA[address,4];
11140             uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
11141             if (!success)
11142                 return false;
11143 
11144             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data))
11145                 return false;
11146         }
11147         else
11148         {
11149             // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11150             uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
11151             if (!success)
11152                 return false;
11153 
11154             context.SetRegisterPlusOffset (base_reg, (address + 4) - base);
11155             uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
11156             if (!success)
11157                 return false;
11158             // // Combine the word-aligned words in the correct order for current endianness.
11159             // D[d] = if BigEndian() then word1:word2 else word2:word1;
11160             uint64_t data64;
11161             if (GetByteOrder() == eByteOrderBig)
11162             {
11163                 data64 = word1;
11164                 data64 = (data64 << 32) | word2;
11165             }
11166             else
11167             {
11168                 data64 = word2;
11169                 data64 = (data64 << 32) | word1;
11170             }
11171 
11172             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64))
11173                 return false;
11174         }
11175     }
11176     return true;
11177 }
11178 
11179 // A8.6.400 VSTR
11180 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an
11181 // optional offset.
11182 bool
11183 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
11184 {
11185 #if 0
11186     if ConditionPassed() then
11187         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11188         address = if add then (R[n] + imm32) else (R[n] - imm32);
11189         if single_reg then
11190             MemA[address,4] = S[d];
11191         else
11192             // Store as two word-aligned words in the correct order for current endianness.
11193             MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11194             MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11195 #endif
11196 
11197     bool success = false;
11198 
11199     if (ConditionPassed (opcode))
11200     {
11201         bool single_reg;
11202         bool add;
11203         uint32_t imm32;
11204         uint32_t d;
11205         uint32_t n;
11206 
11207         switch (encoding)
11208         {
11209             case eEncodingT1:
11210             case eEncodingA1:
11211                 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11212                 single_reg = false;
11213                 add = BitIsSet (opcode, 23);
11214                 imm32 = Bits32 (opcode, 7, 0) << 2;
11215 
11216                 // d = UInt(D:Vd); n = UInt(Rn);
11217                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11218                 n = Bits32 (opcode, 19, 16);
11219 
11220                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11221                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11222                     return false;
11223 
11224                 break;
11225 
11226             case eEncodingT2:
11227             case eEncodingA2:
11228                 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11229                 single_reg = true;
11230                 add = BitIsSet (opcode, 23);
11231                 imm32 = Bits32 (opcode, 7, 0) << 2;
11232 
11233                 // d = UInt(Vd:D); n = UInt(Rn);
11234                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11235                 n = Bits32 (opcode, 19, 16);
11236 
11237                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11238                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11239                     return false;
11240 
11241                 break;
11242 
11243             default:
11244                 return false;
11245         }
11246 
11247         RegisterInfo base_reg;
11248         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11249 
11250         uint32_t Rn = ReadCoreReg (n, &success);
11251         if (!success)
11252             return false;
11253 
11254         // address = if add then (R[n] + imm32) else (R[n] - imm32);
11255         addr_t address;
11256         if (add)
11257             address = Rn + imm32;
11258         else
11259             address = Rn - imm32;
11260 
11261         const uint32_t addr_byte_size = GetAddressByteSize();
11262         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11263 
11264         RegisterInfo data_reg;
11265         GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg);
11266         EmulateInstruction::Context context;
11267         context.type = eContextRegisterStore;
11268         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11269 
11270         if (single_reg)
11271         {
11272             // MemA[address,4] = S[d];
11273             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11274             if (!success)
11275                 return false;
11276 
11277             if (!MemAWrite (context, address, data, addr_byte_size))
11278                 return false;
11279         }
11280         else
11281         {
11282             // // Store as two word-aligned words in the correct order for current endianness.
11283             // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11284             // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11285             uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11286             if (!success)
11287                 return false;
11288 
11289             if (GetByteOrder() == eByteOrderBig)
11290             {
11291                 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11292                     return false;
11293 
11294                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11295                 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size))
11296                     return false;
11297             }
11298             else
11299             {
11300                 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11301                     return false;
11302 
11303                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11304                 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11305                     return false;
11306             }
11307         }
11308     }
11309     return true;
11310 }
11311 
11312 // A8.6.307 VLDI1 (multiple single elements)
11313 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving.  Every
11314 // element of each register is loaded.
11315 bool
11316 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding)
11317 {
11318 #if 0
11319     if ConditionPassed() then
11320         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11321         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11322         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11323         for r = 0 to regs-1
11324             for e = 0 to elements-1
11325                 Elem[D[d+r],e,esize] = MemU[address,ebytes];
11326                 address = address + ebytes;
11327 #endif
11328 
11329     bool success = false;
11330 
11331     if (ConditionPassed (opcode))
11332     {
11333         uint32_t regs;
11334         uint32_t alignment;
11335         uint32_t ebytes;
11336         uint32_t esize;
11337         uint32_t elements;
11338         uint32_t d;
11339         uint32_t n;
11340         uint32_t m;
11341         bool wback;
11342         bool register_index;
11343 
11344         switch (encoding)
11345         {
11346             case eEncodingT1:
11347             case eEncodingA1:
11348             {
11349                 // case type of
11350                     // when �0111�
11351                         // regs = 1; if align<1> == �1� then UNDEFINED;
11352                     // when �1010�
11353                         // regs = 2; if align == �11� then UNDEFINED;
11354                     // when �0110�
11355                         // regs = 3; if align<1> == �1� then UNDEFINED;
11356                     // when �0010�
11357                         // regs = 4;
11358                     // otherwise
11359                         // SEE �Related encodings�;
11360                 uint32_t type = Bits32 (opcode, 11, 8);
11361                 uint32_t align = Bits32 (opcode, 5, 4);
11362                 if (type == 7) // '0111'
11363                 {
11364                     regs = 1;
11365                     if (BitIsSet (align, 1))
11366                         return false;
11367                 }
11368                 else if (type == 10) // '1010'
11369                 {
11370                     regs = 2;
11371                     if (align == 3)
11372                         return false;
11373 
11374                 }
11375                 else if (type == 6) // '0110'
11376                 {
11377                     regs = 3;
11378                     if (BitIsSet (align, 1))
11379                         return false;
11380                 }
11381                 else if (type == 2) // '0010'
11382                 {
11383                     regs = 4;
11384                 }
11385                 else
11386                     return false;
11387 
11388                 // alignment = if align == �00� then 1 else 4 << UInt(align);
11389                 if (align == 0)
11390                     alignment = 1;
11391                 else
11392                     alignment = 4 << align;
11393 
11394                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11395                 ebytes = 1 << Bits32 (opcode, 7, 6);
11396                 esize = 8 * ebytes;
11397                 elements = 8 / ebytes;
11398 
11399                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11400                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11401                 n = Bits32 (opcode, 19, 15);
11402                 m = Bits32 (opcode, 3, 0);
11403 
11404                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11405                 wback = (m != 15);
11406                 register_index = ((m != 15) && (m != 13));
11407 
11408                 // if d+regs > 32 then UNPREDICTABLE;
11409                 if ((d + regs) > 32)
11410                     return false;
11411             }
11412                 break;
11413 
11414             default:
11415                 return false;
11416         }
11417 
11418         RegisterInfo base_reg;
11419         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11420 
11421         uint32_t Rn = ReadCoreReg (n, &success);
11422         if (!success)
11423             return false;
11424 
11425         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11426         addr_t address = Rn;
11427         if ((address % alignment) != 0)
11428             return false;
11429 
11430         EmulateInstruction::Context context;
11431         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11432         if (wback)
11433         {
11434             uint32_t Rm = ReadCoreReg (m, &success);
11435             if (!success)
11436                 return false;
11437 
11438             uint32_t offset;
11439             if (register_index)
11440                 offset = Rm;
11441             else
11442                 offset = 8 * regs;
11443 
11444             uint32_t value = Rn + offset;
11445             context.type = eContextAdjustBaseRegister;
11446             context.SetRegisterPlusOffset (base_reg, offset);
11447 
11448             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11449                 return false;
11450 
11451         }
11452 
11453         // for r = 0 to regs-1
11454         for (uint32_t r = 0; r < regs; ++r)
11455         {
11456             // for e = 0 to elements-1
11457             uint64_t assembled_data = 0;
11458             for (uint32_t e = 0; e < elements; ++e)
11459             {
11460                 // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11461                 context.type = eContextRegisterLoad;
11462                 context.SetRegisterPlusOffset (base_reg, address - Rn);
11463                 uint64_t data = MemURead (context, address, ebytes, 0, &success);
11464                 if (!success)
11465                     return false;
11466 
11467                 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data
11468 
11469                 // address = address + ebytes;
11470                 address = address + ebytes;
11471             }
11472             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data))
11473                 return false;
11474         }
11475     }
11476     return true;
11477 }
11478 
11479 // A8.6.308 VLD1 (single element to one lane)
11480 //
11481 bool
11482 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding)
11483 {
11484 #if 0
11485     if ConditionPassed() then
11486         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11487         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11488         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11489         Elem[D[d],index,esize] = MemU[address,ebytes];
11490 #endif
11491 
11492     bool success = false;
11493 
11494     if (ConditionPassed (opcode))
11495     {
11496         uint32_t ebytes;
11497         uint32_t esize;
11498         uint32_t index;
11499         uint32_t alignment;
11500         uint32_t d;
11501         uint32_t n;
11502         uint32_t m;
11503         bool wback;
11504         bool register_index;
11505 
11506         switch (encoding)
11507         {
11508             case eEncodingT1:
11509             case eEncodingA1:
11510             {
11511                 uint32_t size = Bits32 (opcode, 11, 10);
11512                 uint32_t index_align = Bits32 (opcode, 7, 4);
11513                 // if size == �11� then SEE VLD1 (single element to all lanes);
11514                 if (size == 3)
11515                    return EmulateVLD1SingleAll (opcode, encoding);
11516                 // case size of
11517                 if (size == 0) // when '00'
11518                 {
11519                     // if index_align<0> != �0� then UNDEFINED;
11520                     if (BitIsClear (index_align, 0))
11521                         return false;
11522 
11523                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11524                     ebytes = 1;
11525                     esize = 8;
11526                     index = Bits32 (index_align, 3, 1);
11527                     alignment = 1;
11528                 }
11529                 else if (size == 1) // when �01�
11530                 {
11531                     // if index_align<1> != �0� then UNDEFINED;
11532                     if (BitIsClear (index_align, 1))
11533                         return false;
11534 
11535                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11536                     ebytes = 2;
11537                     esize = 16;
11538                     index = Bits32 (index_align, 3, 2);
11539 
11540                     // alignment = if index_align<0> == �0� then 1 else 2;
11541                     if (BitIsClear (index_align, 0))
11542                         alignment = 1;
11543                     else
11544                         alignment = 2;
11545                 }
11546                 else if (size == 2) // when �10�
11547                 {
11548                     // if index_align<2> != �0� then UNDEFINED;
11549                     if (BitIsClear (index_align, 2))
11550                         return false;
11551 
11552                     // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11553                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11554                         return false;
11555 
11556                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11557                     ebytes = 4;
11558                     esize = 32;
11559                     index = Bit32 (index_align, 3);
11560 
11561                     // alignment = if index_align<1:0> == �00� then 1 else 4;
11562                     if (Bits32 (index_align, 1, 0) == 0)
11563                         alignment = 1;
11564                     else
11565                         alignment = 4;
11566                 }
11567                 else
11568                 {
11569                     return false;
11570                 }
11571                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11572                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11573                 n = Bits32 (opcode, 19, 16);
11574                 m = Bits32 (opcode, 3, 0);
11575 
11576                 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
11577                 wback = (m != 15);
11578                 register_index = ((m != 15) && (m != 13));
11579 
11580                 if (n == 15)
11581                     return false;
11582 
11583             }
11584                 break;
11585 
11586             default:
11587                 return false;
11588         }
11589 
11590         RegisterInfo base_reg;
11591         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11592 
11593         uint32_t Rn = ReadCoreReg (n, &success);
11594         if (!success)
11595             return false;
11596 
11597         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11598         addr_t address = Rn;
11599         if ((address % alignment) != 0)
11600             return false;
11601 
11602         EmulateInstruction::Context context;
11603         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11604         if (wback)
11605         {
11606             uint32_t Rm = ReadCoreReg (m, &success);
11607             if (!success)
11608                 return false;
11609 
11610             uint32_t offset;
11611             if (register_index)
11612                 offset = Rm;
11613             else
11614                 offset = ebytes;
11615 
11616             uint32_t value = Rn + offset;
11617 
11618             context.type = eContextAdjustBaseRegister;
11619             context.SetRegisterPlusOffset (base_reg, offset);
11620 
11621             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11622                 return false;
11623         }
11624 
11625         // Elem[D[d],index,esize] = MemU[address,ebytes];
11626         uint32_t element = MemURead (context, address, esize, 0, &success);
11627         if (!success)
11628             return false;
11629 
11630         element = element << (index * esize);
11631 
11632         uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11633         if (!success)
11634             return false;
11635 
11636         uint64_t all_ones = -1;
11637         uint64_t mask = all_ones << ((index+1) * esize);  // mask is all 1's to left of where 'element' goes, & all 0's
11638                                                           // at element & to the right of element.
11639         if (index > 0)
11640             mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes.
11641                                                                      // now mask should be 0's where element goes & 1's
11642                                                                      // everywhere else.
11643 
11644         uint64_t masked_reg = reg_data & mask;  // Take original reg value & zero out 'element' bits
11645         reg_data = masked_reg & element;        // Put 'element' into those bits in reg_data.
11646 
11647         context.type = eContextRegisterLoad;
11648         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data))
11649             return false;
11650     }
11651     return true;
11652 }
11653 
11654 // A8.6.391 VST1 (multiple single elements)
11655 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four registers, without
11656 // interleaving.  Every element of each register is stored.
11657 bool
11658 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding)
11659 {
11660 #if 0
11661     if ConditionPassed() then
11662         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11663         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11664         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11665         for r = 0 to regs-1
11666             for e = 0 to elements-1
11667                 MemU[address,ebytes] = Elem[D[d+r],e,esize];
11668                 address = address + ebytes;
11669 #endif
11670 
11671     bool success = false;
11672 
11673     if (ConditionPassed (opcode))
11674     {
11675         uint32_t regs;
11676         uint32_t alignment;
11677         uint32_t ebytes;
11678         uint32_t esize;
11679         uint32_t elements;
11680         uint32_t d;
11681         uint32_t n;
11682         uint32_t m;
11683         bool wback;
11684         bool register_index;
11685 
11686         switch (encoding)
11687         {
11688             case eEncodingT1:
11689             case eEncodingA1:
11690             {
11691                 uint32_t type = Bits32 (opcode, 11, 8);
11692                 uint32_t align = Bits32 (opcode, 5, 4);
11693 
11694                 // case type of
11695                 if (type == 7)    // when �0111�
11696                 {
11697                     // regs = 1; if align<1> == �1� then UNDEFINED;
11698                     regs = 1;
11699                     if (BitIsSet (align, 1))
11700                         return false;
11701                 }
11702                 else if (type == 10) // when �1010�
11703                 {
11704                     // regs = 2; if align == �11� then UNDEFINED;
11705                     regs = 2;
11706                     if (align == 3)
11707                         return false;
11708                 }
11709                 else if (type == 6) // when �0110�
11710                 {
11711                     // regs = 3; if align<1> == �1� then UNDEFINED;
11712                     regs = 3;
11713                     if (BitIsSet (align, 1))
11714                         return false;
11715                 }
11716                 else if (type == 2) // when �0010�
11717                     // regs = 4;
11718                     regs = 4;
11719                 else // otherwise
11720                     // SEE �Related encodings�;
11721                     return false;
11722 
11723                 // alignment = if align == �00� then 1 else 4 << UInt(align);
11724                 if (align == 0)
11725                     alignment = 1;
11726                 else
11727                     alignment = 4 << align;
11728 
11729                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11730                 ebytes = 1 << Bits32 (opcode,7, 6);
11731                 esize = 8 * ebytes;
11732                 elements = 8 / ebytes;
11733 
11734                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11735                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11736                 n = Bits32 (opcode, 19, 16);
11737                 m = Bits32 (opcode, 3, 0);
11738 
11739                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11740                 wback = (m != 15);
11741                 register_index = ((m != 15) && (m != 13));
11742 
11743                 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11744                 if ((d + regs) > 32)
11745                     return false;
11746 
11747                 if (n == 15)
11748                     return false;
11749 
11750             }
11751                 break;
11752 
11753             default:
11754                 return false;
11755         }
11756 
11757         RegisterInfo base_reg;
11758         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11759 
11760         uint32_t Rn = ReadCoreReg (n, &success);
11761         if (!success)
11762             return false;
11763 
11764         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11765         addr_t address = Rn;
11766         if ((address % alignment) != 0)
11767             return false;
11768 
11769         EmulateInstruction::Context context;
11770         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11771         if (wback)
11772         {
11773             uint32_t Rm = ReadCoreReg (m, &success);
11774             if (!success)
11775                 return false;
11776 
11777             uint32_t offset;
11778             if (register_index)
11779                 offset = Rm;
11780             else
11781                 offset = 8 * regs;
11782 
11783             context.type = eContextAdjustBaseRegister;
11784             context.SetRegisterPlusOffset (base_reg, offset);
11785 
11786             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11787                 return false;
11788         }
11789 
11790         RegisterInfo data_reg;
11791         context.type = eContextRegisterStore;
11792         // for r = 0 to regs-1
11793         for (uint32_t r = 0; r < regs; ++r)
11794         {
11795             GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
11796             uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
11797             if (!success)
11798                 return false;
11799 
11800              // for e = 0 to elements-1
11801             for (uint32_t e = 0; e < elements; ++e)
11802             {
11803                 // MemU[address,ebytes] = Elem[D[d+r],e,esize];
11804                 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize);
11805 
11806                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11807                 if (!MemUWrite (context, address, word, ebytes))
11808                     return false;
11809 
11810                 // address = address + ebytes;
11811                 address = address + ebytes;
11812             }
11813         }
11814     }
11815     return true;
11816 }
11817 
11818 // A8.6.392 VST1 (single element from one lane)
11819 // This instruction stores one element to memory from one element of a register.
11820 bool
11821 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding)
11822 {
11823 #if 0
11824     if ConditionPassed() then
11825         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11826         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11827         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11828         MemU[address,ebytes] = Elem[D[d],index,esize];
11829 #endif
11830 
11831     bool success = false;
11832 
11833     if (ConditionPassed (opcode))
11834     {
11835         uint32_t ebytes;
11836         uint32_t esize;
11837         uint32_t index;
11838         uint32_t alignment;
11839         uint32_t d;
11840         uint32_t n;
11841         uint32_t m;
11842         bool wback;
11843         bool register_index;
11844 
11845         switch (encoding)
11846         {
11847             case eEncodingT1:
11848             case eEncodingA1:
11849             {
11850                 uint32_t size = Bits32 (opcode, 11, 10);
11851                 uint32_t index_align = Bits32 (opcode, 7, 4);
11852 
11853                 // if size == �11� then UNDEFINED;
11854                 if (size == 3)
11855                     return false;
11856 
11857                 // case size of
11858                 if (size == 0) // when �00�
11859                 {
11860                     // if index_align<0> != �0� then UNDEFINED;
11861                     if (BitIsClear (index_align, 0))
11862                         return false;
11863                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11864                     ebytes = 1;
11865                     esize = 8;
11866                     index = Bits32 (index_align, 3, 1);
11867                     alignment = 1;
11868                 }
11869                 else if (size == 1) // when �01�
11870                 {
11871                     // if index_align<1> != �0� then UNDEFINED;
11872                     if (BitIsClear (index_align, 1))
11873                         return false;
11874 
11875                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11876                     ebytes = 2;
11877                     esize = 16;
11878                     index = Bits32 (index_align, 3, 2);
11879 
11880                     // alignment = if index_align<0> == �0� then 1 else 2;
11881                     if (BitIsClear (index_align, 0))
11882                         alignment = 1;
11883                     else
11884                         alignment = 2;
11885                 }
11886                 else if (size == 2) // when �10�
11887                 {
11888                     // if index_align<2> != �0� then UNDEFINED;
11889                     if (BitIsClear (index_align, 2))
11890                         return false;
11891 
11892                     // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11893                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11894                         return false;
11895 
11896                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11897                     ebytes = 4;
11898                     esize = 32;
11899                     index = Bit32 (index_align, 3);
11900 
11901                     // alignment = if index_align<1:0> == �00� then 1 else 4;
11902                     if (Bits32 (index_align, 1, 0) == 0)
11903                         alignment = 1;
11904                     else
11905                         alignment = 4;
11906                 }
11907                 else
11908                 {
11909                     return false;
11910                 }
11911                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11912                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11913                 n = Bits32 (opcode, 19, 16);
11914                 m = Bits32 (opcode, 3, 0);
11915 
11916                 // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15 then UNPREDICTABLE;
11917                 wback = (m != 15);
11918                 register_index = ((m != 15) && (m != 13));
11919 
11920                 if (n == 15)
11921                     return false;
11922             }
11923                 break;
11924 
11925             default:
11926                 return false;
11927         }
11928 
11929         RegisterInfo base_reg;
11930         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11931 
11932         uint32_t Rn = ReadCoreReg (n, &success);
11933         if (!success)
11934             return false;
11935 
11936         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11937         addr_t address = Rn;
11938         if ((address % alignment) != 0)
11939             return false;
11940 
11941         EmulateInstruction::Context context;
11942         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11943         if (wback)
11944         {
11945             uint32_t Rm = ReadCoreReg (m, &success);
11946             if (!success)
11947                 return false;
11948 
11949             uint32_t offset;
11950             if (register_index)
11951                 offset = Rm;
11952             else
11953                 offset = ebytes;
11954 
11955             context.type = eContextAdjustBaseRegister;
11956             context.SetRegisterPlusOffset (base_reg, offset);
11957 
11958             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11959                 return false;
11960         }
11961 
11962         // MemU[address,ebytes] = Elem[D[d],index,esize];
11963         uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11964         if (!success)
11965             return false;
11966 
11967         uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1,  index * esize);
11968 
11969         RegisterInfo data_reg;
11970         GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg);
11971         context.type = eContextRegisterStore;
11972         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11973 
11974         if (!MemUWrite (context, address, word, ebytes))
11975             return false;
11976     }
11977     return true;
11978 }
11979 
11980 // A8.6.309 VLD1 (single element to all lanes)
11981 // This instruction loads one element from memory into every element of one or two vectors.
11982 bool
11983 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding)
11984 {
11985 #if 0
11986     if ConditionPassed() then
11987         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11988         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11989         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11990         replicated_element = Replicate(MemU[address,ebytes], elements);
11991         for r = 0 to regs-1
11992             D[d+r] = replicated_element;
11993 #endif
11994 
11995     bool success = false;
11996 
11997     if (ConditionPassed (opcode))
11998     {
11999         uint32_t ebytes;
12000         uint32_t elements;
12001         uint32_t regs;
12002         uint32_t alignment;
12003         uint32_t d;
12004         uint32_t n;
12005         uint32_t m;
12006         bool wback;
12007         bool register_index;
12008 
12009         switch (encoding)
12010         {
12011             case eEncodingT1:
12012             case eEncodingA1:
12013             {
12014                 //if size == �11� || (size == �00� && a == �1�) then UNDEFINED;
12015                 uint32_t size = Bits32 (opcode, 7, 6);
12016                 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4)))
12017                     return false;
12018 
12019                 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2;
12020                 ebytes = 1 << size;
12021                 elements = 8 / ebytes;
12022                 if (BitIsClear (opcode, 5))
12023                     regs = 1;
12024                 else
12025                     regs = 2;
12026 
12027                 //alignment = if a == �0� then 1 else ebytes;
12028                 if (BitIsClear (opcode, 4))
12029                     alignment = 1;
12030                 else
12031                     alignment = ebytes;
12032 
12033                 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12034                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
12035                 n = Bits32 (opcode, 19, 16);
12036                 m = Bits32 (opcode, 3, 0);
12037 
12038                 //wback = (m != 15); register_index = (m != 15 && m != 13);
12039                 wback = (m != 15);
12040                 register_index = ((m != 15) && (m != 13));
12041 
12042                 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12043                 if ((d + regs) > 32)
12044                     return false;
12045 
12046                 if (n == 15)
12047                     return false;
12048             }
12049             break;
12050 
12051             default:
12052                 return false;
12053         }
12054 
12055         RegisterInfo base_reg;
12056         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12057 
12058         uint32_t Rn = ReadCoreReg (n, &success);
12059         if (!success)
12060             return false;
12061 
12062         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12063         addr_t address = Rn;
12064         if ((address % alignment) != 0)
12065             return false;
12066 
12067         EmulateInstruction::Context context;
12068         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12069         if (wback)
12070         {
12071             uint32_t Rm = ReadCoreReg (m, &success);
12072             if (!success)
12073                 return false;
12074 
12075             uint32_t offset;
12076             if (register_index)
12077                 offset = Rm;
12078             else
12079                 offset = ebytes;
12080 
12081             context.type = eContextAdjustBaseRegister;
12082             context.SetRegisterPlusOffset (base_reg, offset);
12083 
12084             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
12085                 return false;
12086         }
12087 
12088         // replicated_element = Replicate(MemU[address,ebytes], elements);
12089 
12090         context.type = eContextRegisterLoad;
12091         uint64_t word = MemURead (context, address, ebytes, 0, &success);
12092         if (!success)
12093             return false;
12094 
12095         uint64_t replicated_element = 0;
12096         uint32_t esize = ebytes * 8;
12097         for (uint32_t e = 0; e < elements; ++e)
12098             replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0);
12099 
12100         // for r = 0 to regs-1
12101         for (uint32_t r = 0; r < regs; ++r)
12102         {
12103             // D[d+r] = replicated_element;
12104             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element))
12105                 return false;
12106         }
12107     }
12108     return true;
12109 }
12110 
12111 // B6.2.13 SUBS PC, LR and related instructions
12112 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack.  It subtracts the
12113 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR.
12114 bool
12115 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding)
12116 {
12117 #if 0
12118     if ConditionPassed() then
12119         EncodingSpecificOperations();
12120         if CurrentInstrSet() == InstrSet_ThumbEE then
12121             UNPREDICTABLE;
12122         operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12123         case opcode of
12124             when0000result = R[n] AND operand2; // AND
12125             when0001result = R[n] EOR operand2; // EOR
12126             when0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12127             when0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12128             when0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12129             when0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12130             when0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12131             when0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12132             when1100result = R[n] OR operand2; // ORR
12133             when1101result = operand2; // MOV
12134             when1110result = R[n] AND NOT(operand2); // BIC
12135             when1111result = NOT(operand2); // MVN
12136         CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12137         BranchWritePC(result);
12138 #endif
12139 
12140     bool success = false;
12141 
12142     if (ConditionPassed (opcode))
12143     {
12144         uint32_t n;
12145         uint32_t m;
12146         uint32_t imm32;
12147         bool register_form;
12148         ARM_ShifterType shift_t;
12149         uint32_t shift_n;
12150         uint32_t code;
12151 
12152         switch (encoding)
12153         {
12154             case eEncodingT1:
12155                 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
12156                 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB
12157                 n = 14;
12158                 imm32 = Bits32 (opcode, 7, 0);
12159                 register_form = false;
12160                 code = 2;
12161 
12162                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12163                 if (InITBlock() && !LastInITBlock())
12164                     return false;
12165 
12166                 break;
12167 
12168             case eEncodingA1:
12169                 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12170                 n = Bits32 (opcode, 19, 16);
12171                 imm32 = ARMExpandImm (opcode);
12172                 register_form = false;
12173                 code = Bits32 (opcode, 24, 21);
12174 
12175                 break;
12176 
12177             case eEncodingA2:
12178                 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12179                 n = Bits32 (opcode, 19, 16);
12180                 m = Bits32 (opcode, 3, 0);
12181                 register_form = true;
12182 
12183                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12184                 shift_n = DecodeImmShiftARM (opcode, shift_t);
12185 
12186                 break;
12187 
12188             default:
12189                 return false;
12190         }
12191 
12192         // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12193         uint32_t operand2;
12194         if (register_form)
12195         {
12196             uint32_t Rm = ReadCoreReg (m, &success);
12197             if (!success)
12198                 return false;
12199 
12200             operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success);
12201             if (!success)
12202                 return false;
12203         }
12204         else
12205         {
12206             operand2 = imm32;
12207         }
12208 
12209         uint32_t Rn = ReadCoreReg (n, &success);
12210         if (!success)
12211             return false;
12212 
12213         AddWithCarryResult result;
12214 
12215         // case opcode of
12216         switch (code)
12217         {
12218             case 0: // when �0000�
12219                 // result = R[n] AND operand2; // AND
12220                 result.result = Rn & operand2;
12221                 break;
12222 
12223             case 1: // when �0001�
12224                 // result = R[n] EOR operand2; // EOR
12225                 result.result = Rn ^ operand2;
12226                 break;
12227 
12228             case 2: // when �0010�
12229                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12230                 result = AddWithCarry (Rn, ~(operand2), 1);
12231                 break;
12232 
12233             case 3: // when �0011�
12234                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12235                 result = AddWithCarry (~(Rn), operand2, 1);
12236                 break;
12237 
12238             case 4: // when �0100�
12239                 // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12240                 result = AddWithCarry (Rn, operand2, 0);
12241                 break;
12242 
12243             case 5: // when �0101�
12244                 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12245                 result = AddWithCarry (Rn, operand2, APSR_C);
12246                 break;
12247 
12248             case 6: // when �0110�
12249                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12250                 result = AddWithCarry (Rn, ~(operand2), APSR_C);
12251                 break;
12252 
12253             case 7: // when �0111�
12254                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12255                 result = AddWithCarry (~(Rn), operand2, APSR_C);
12256                 break;
12257 
12258             case 10: // when �1100�
12259                 // result = R[n] OR operand2; // ORR
12260                 result.result = Rn | operand2;
12261                 break;
12262 
12263             case 11: // when �1101�
12264                 // result = operand2; // MOV
12265                 result.result = operand2;
12266                 break;
12267 
12268             case 12: // when �1110�
12269                 // result = R[n] AND NOT(operand2); // BIC
12270                 result.result = Rn & ~(operand2);
12271                 break;
12272 
12273             case 15: // when �1111�
12274                 // result = NOT(operand2); // MVN
12275                 result.result = ~(operand2);
12276                 break;
12277 
12278             default:
12279                 return false;
12280         }
12281         // CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12282 
12283         // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for
12284         // the best.
12285         uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12286         if (!success)
12287             return false;
12288 
12289         CPSRWriteByInstr (spsr, 15, true);
12290 
12291         // BranchWritePC(result);
12292         EmulateInstruction::Context context;
12293         context.type = eContextAdjustPC;
12294         context.SetImmediate (result.result);
12295 
12296         BranchWritePC (context, result.result);
12297     }
12298     return true;
12299 }
12300 
12301 EmulateInstructionARM::ARMOpcode*
12302 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12303 {
12304     static ARMOpcode
12305     g_arm_opcodes[] =
12306     {
12307         //----------------------------------------------------------------------
12308         // Prologue instructions
12309         //----------------------------------------------------------------------
12310 
12311         // push register(s)
12312         { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12313         { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
12314 
12315         // set r7 to point to a stack offset
12316         { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
12317         { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12318         // copy the stack pointer to ip
12319         { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
12320         { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
12321         { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12322 
12323         // adjust the stack pointer
12324         { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12325         { 0x0fef0010, 0x004d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12326 
12327         // push one register
12328         // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12329         { 0x0e5f0000, 0x040d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
12330 
12331         // vector push consecutive extension register(s)
12332         { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12333         { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12334 
12335         //----------------------------------------------------------------------
12336         // Epilogue instructions
12337         //----------------------------------------------------------------------
12338 
12339         { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12340         { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12341         { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12342         { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12343 
12344         //----------------------------------------------------------------------
12345         // Supervisor Call (previously Software Interrupt)
12346         //----------------------------------------------------------------------
12347         { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12348 
12349         //----------------------------------------------------------------------
12350         // Branch instructions
12351         //----------------------------------------------------------------------
12352         // To resolve ambiguity, "blx <label>" should come before "b #imm24" and "bl <label>".
12353         { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12354         { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
12355         { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12356         { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12357         // for example, "bx lr"
12358         { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12359         // bxj
12360         { 0x0ffffff0, 0x012fff20, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12361 
12362         //----------------------------------------------------------------------
12363         // Data-processing instructions
12364         //----------------------------------------------------------------------
12365         // adc (immediate)
12366         { 0x0fe00000, 0x02a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12367         // adc (register)
12368         { 0x0fe00010, 0x00a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12369         // add (immediate)
12370         { 0x0fe00000, 0x02800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
12371         // add (register)
12372         { 0x0fe00010, 0x00800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12373         // add (register-shifted register)
12374         { 0x0fe00090, 0x00800010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12375         // adr
12376         { 0x0fff0000, 0x028f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12377         { 0x0fff0000, 0x024f0000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12378         // and (immediate)
12379         { 0x0fe00000, 0x02000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12380         // and (register)
12381         { 0x0fe00010, 0x00000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12382         // bic (immediate)
12383         { 0x0fe00000, 0x03c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12384         // bic (register)
12385         { 0x0fe00010, 0x01c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12386         // eor (immediate)
12387         { 0x0fe00000, 0x02200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12388         // eor (register)
12389         { 0x0fe00010, 0x00200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12390         // orr (immediate)
12391         { 0x0fe00000, 0x03800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12392         // orr (register)
12393         { 0x0fe00010, 0x01800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12394         // rsb (immediate)
12395         { 0x0fe00000, 0x02600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12396         // rsb (register)
12397         { 0x0fe00010, 0x00600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12398         // rsc (immediate)
12399         { 0x0fe00000, 0x02e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12400         // rsc (register)
12401         { 0x0fe00010, 0x00e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12402         // sbc (immediate)
12403         { 0x0fe00000, 0x02c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12404         // sbc (register)
12405         { 0x0fe00010, 0x00c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12406         // sub (immediate, ARM)
12407         { 0x0fe00000, 0x02400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
12408         // sub (sp minus immediate)
12409         { 0x0fef0000, 0x024d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12410         // sub (register)
12411         { 0x0fe00010, 0x00400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12412         // teq (immediate)
12413         { 0x0ff0f000, 0x03300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12414         // teq (register)
12415         { 0x0ff0f010, 0x01300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12416         // tst (immediate)
12417         { 0x0ff0f000, 0x03100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12418         // tst (register)
12419         { 0x0ff0f010, 0x01100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12420 
12421         // mov (immediate)
12422         { 0x0fef0000, 0x03a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12423         { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
12424         // mov (register)
12425         { 0x0fef0ff0, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12426         // mvn (immediate)
12427         { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12428         // mvn (register)
12429         { 0x0fef0010, 0x01e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12430         // cmn (immediate)
12431         { 0x0ff0f000, 0x03700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12432         // cmn (register)
12433         { 0x0ff0f010, 0x01700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12434         // cmp (immediate)
12435         { 0x0ff0f000, 0x03500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
12436         // cmp (register)
12437         { 0x0ff0f010, 0x01500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
12438         // asr (immediate)
12439         { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
12440         // asr (register)
12441         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
12442         // lsl (immediate)
12443         { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
12444         // lsl (register)
12445         { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
12446         // lsr (immediate)
12447         { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
12448         // lsr (register)
12449         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
12450         // rrx is a special case encoding of ror (immediate)
12451         { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
12452         // ror (immediate)
12453         { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
12454         // ror (register)
12455         { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
12456         // mul
12457         { 0x0fe000f0, 0x00000090, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
12458 
12459         // subs pc, lr and related instructions
12460         { 0x0e10f000, 0x0210f000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" },
12461         { 0x0e10f010, 0x0010f000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" },
12462 
12463         //----------------------------------------------------------------------
12464         // Load instructions
12465         //----------------------------------------------------------------------
12466         { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12467         { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
12468         { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12469         { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
12470         { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
12471         { 0x0e500010, 0x06100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
12472         { 0x0e5f0000, 0x045f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
12473         { 0xfe500010, 0x06500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
12474         { 0x0e5f00f0, 0x005f00b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12475         { 0x0e5000f0, 0x001000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"  },
12476         { 0x0e5000f0, 0x005000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
12477         { 0x0e5f00f0, 0x005f00d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
12478         { 0x0e5000f0, 0x001000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12479         { 0x0e5000f0, 0x005000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
12480         { 0x0e5f00f0, 0x005f00f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12481         { 0x0e5000f0, 0x001000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12482         { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
12483         { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12484         { 0x0e100f00, 0x0c100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12485         { 0x0e100f00, 0x0c100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12486         { 0x0f300f00, 0x0d100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12487         { 0x0f300f00, 0x0d100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12488         { 0xffb00000, 0xf4200000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12489         { 0xffb00300, 0xf4a00000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12490         { 0xffb00f00, 0xf4a00c00, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12491 
12492         //----------------------------------------------------------------------
12493         // Store instructions
12494         //----------------------------------------------------------------------
12495         { 0x0fd00000, 0x08800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12496         { 0x0fd00000, 0x08000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
12497         { 0x0fd00000, 0x09000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12498         { 0x0fd00000, 0x09800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
12499         { 0x0e500010, 0x06000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
12500         { 0x0e5000f0, 0x000000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
12501         { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
12502         { 0x0e500000, 0x04400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12503         { 0x0e500000, 0x04000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12504         { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
12505         { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12506         { 0x0e100f00, 0x0c000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12507         { 0x0e100f00, 0x0c000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12508         { 0x0f300f00, 0x0d000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
12509         { 0x0f300f00, 0x0d000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
12510         { 0xffb00000, 0xf4000000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12511         { 0xffb00300, 0xf4800000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12512 
12513         //----------------------------------------------------------------------
12514         // Other instructions
12515         //----------------------------------------------------------------------
12516         { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
12517         { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
12518         { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
12519         { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
12520         { 0xfe500000, 0xf8100000, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
12521 
12522     };
12523     static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes);
12524 
12525     for (size_t i=0; i<k_num_arm_opcodes; ++i)
12526     {
12527         if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
12528             (g_arm_opcodes[i].variants & arm_isa) != 0)
12529             return &g_arm_opcodes[i];
12530     }
12531     return NULL;
12532 }
12533 
12534 
12535 EmulateInstructionARM::ARMOpcode*
12536 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12537 {
12538 
12539     static ARMOpcode
12540     g_thumb_opcodes[] =
12541     {
12542         //----------------------------------------------------------------------
12543         // Prologue instructions
12544         //----------------------------------------------------------------------
12545 
12546         // push register(s)
12547         { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12548         { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
12549         { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
12550 
12551         // set r7 to point to a stack offset
12552         { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
12553         // copy the stack pointer to r7
12554         { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
12555         // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
12556         { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
12557 
12558         // PC-relative load into register (see also EmulateADDSPRm)
12559         { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
12560 
12561         // adjust the stack pointer
12562         { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
12563         { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
12564         { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
12565         { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
12566         { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12567 
12568         // vector push consecutive extension register(s)
12569         { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12570         { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12571 
12572         //----------------------------------------------------------------------
12573         // Epilogue instructions
12574         //----------------------------------------------------------------------
12575 
12576         { 0xfffff800, 0x0000a800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
12577         { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
12578         { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12579         { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
12580         { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
12581         { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12582         { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12583 
12584         //----------------------------------------------------------------------
12585         // Supervisor Call (previously Software Interrupt)
12586         //----------------------------------------------------------------------
12587         { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
12588 
12589         //----------------------------------------------------------------------
12590         // If Then makes up to four following instructions conditional.
12591         //----------------------------------------------------------------------
12592         // The next 5 opcode _must_ come before the if then instruction
12593         { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"},
12594         { 0xffffffff, 0x0000bf10, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
12595         { 0xffffffff, 0x0000bf20, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
12596         { 0xffffffff, 0x0000bf30, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
12597         { 0xffffffff, 0x0000bf40, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
12598         { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
12599 
12600         //----------------------------------------------------------------------
12601         // Branch instructions
12602         //----------------------------------------------------------------------
12603         // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
12604         { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
12605         { 0xfffff800, 0x0000e000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
12606         { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
12607         { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
12608         // J1 == J2 == 1
12609         { 0xf800d000, 0xf000d000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12610         // J1 == J2 == 1
12611         { 0xf800d001, 0xf000c000, ARMV5_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12612         { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12613         // for example, "bx lr"
12614         { 0xffffff87, 0x00004700, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12615         // bxj
12616         { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12617         // compare and branch
12618         { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
12619         // table branch byte
12620         { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
12621         // table branch halfword
12622         { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
12623 
12624         //----------------------------------------------------------------------
12625         // Data-processing instructions
12626         //----------------------------------------------------------------------
12627         // adc (immediate)
12628         { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
12629         // adc (register)
12630         { 0xffffffc0, 0x00004140, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
12631         { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12632         // add (register)
12633         { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
12634         // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
12635         { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
12636         // adr
12637         { 0xfffff800, 0x0000a000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12638         { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12639         { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12640         // and (immediate)
12641         { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
12642         // and (register)
12643         { 0xffffffc0, 0x00004000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
12644         { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12645         // bic (immediate)
12646         { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
12647         // bic (register)
12648         { 0xffffffc0, 0x00004380, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
12649         { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12650         // eor (immediate)
12651         { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
12652         // eor (register)
12653         { 0xffffffc0, 0x00004040, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
12654         { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12655         // orr (immediate)
12656         { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
12657         // orr (register)
12658         { 0xffffffc0, 0x00004300, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
12659         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12660         // rsb (immediate)
12661         { 0xffffffc0, 0x00004240, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
12662         { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
12663         // rsb (register)
12664         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12665         // sbc (immediate)
12666         { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12667         // sbc (register)
12668         { 0xffffffc0, 0x00004180, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
12669         { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12670         // add (immediate, Thumb)
12671         { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
12672         { 0xfffff800, 0x00003000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
12673         { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
12674         { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
12675         // sub (immediate, Thumb)
12676         { 0xfffffe00, 0x00001e00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
12677         { 0xfffff800, 0x00003800, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
12678         { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
12679         { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
12680         // sub (sp minus immediate)
12681         { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
12682         { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
12683         // sub (register)
12684         { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
12685         { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
12686         // teq (immediate)
12687         { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
12688         // teq (register)
12689         { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12690         // tst (immediate)
12691         { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
12692         // tst (register)
12693         { 0xffffffc0, 0x00004200, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
12694         { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
12695 
12696 
12697         // move from high register to high register
12698         { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
12699         // move from low register to low register
12700         { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
12701         // mov{s}<c>.w <Rd>, <Rm>
12702         { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
12703         // move immediate
12704         { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
12705         { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
12706         { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
12707         // mvn (immediate)
12708         { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
12709         // mvn (register)
12710         { 0xffffffc0, 0x000043c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
12711         { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
12712         // cmn (immediate)
12713         { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12714         // cmn (register)
12715         { 0xffffffc0, 0x000042c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
12716         { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12717         // cmp (immediate)
12718         { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
12719         { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
12720         // cmp (register) (Rn and Rm both from r0-r7)
12721         { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12722         // cmp (register) (Rn and Rm not both from r0-r7)
12723         { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12724         // asr (immediate)
12725         { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
12726         { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
12727         // asr (register)
12728         { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
12729         { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12730         // lsl (immediate)
12731         { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
12732         { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
12733         // lsl (register)
12734         { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
12735         { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
12736         // lsr (immediate)
12737         { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
12738         { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
12739         // lsr (register)
12740         { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
12741         { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12742         // rrx is a special case encoding of ror (immediate)
12743         { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
12744         // ror (immediate)
12745         { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
12746         // ror (register)
12747         { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
12748         { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
12749         // mul
12750         { 0xffffffc0, 0x00004340, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
12751         // mul
12752         { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
12753 
12754         // subs pc, lr and related instructions
12755         { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" },
12756 
12757         //----------------------------------------------------------------------
12758         // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table;
12759         // otherwise the wrong instructions will be selected.
12760         //----------------------------------------------------------------------
12761 
12762         { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
12763         { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
12764 
12765         //----------------------------------------------------------------------
12766         // Load instructions
12767         //----------------------------------------------------------------------
12768         { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12769         { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
12770         { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12771         { 0xfffff800, 0x00006800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
12772         { 0xfffff800, 0x00009800, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
12773         { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
12774         { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
12775                   // Thumb2 PC-relative load into register
12776         { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
12777         { 0xfffffe00, 0x00005800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
12778         { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
12779         { 0xfffff800, 0x00007800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
12780         { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12781         { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" },
12782         { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
12783         { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
12784         { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
12785         { 0xfffff800, 0x00008800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"  },
12786         { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12787         { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"  },
12788         { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12789         { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
12790         { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12791         { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
12792         { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12793         { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
12794         { 0xfffffe00, 0x00005600, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
12795         { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"  },
12796         { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
12797         { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12798         { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12799         { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
12800         { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12801         { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
12802         { 0xfe100f00, 0xec100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12803         { 0xfe100f00, 0xec100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
12804         { 0xffe00f00, 0xed100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12805         { 0xff300f00, 0xed100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
12806         { 0xffb00000, 0xf9200000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12807         { 0xffb00300, 0xf9a00000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12808         { 0xffb00f00, 0xf9a00c00, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12809 
12810         //----------------------------------------------------------------------
12811         // Store instructions
12812         //----------------------------------------------------------------------
12813         { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12814         { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
12815         { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12816         { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
12817         { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
12818         { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
12819         { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
12820         { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
12821         { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
12822         { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
12823         { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
12824         { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
12825         { 0xfffffe00, 0x00005200, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
12826         { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12827         { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
12828         { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
12829         { 0xfe100f00, 0xec000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12830         { 0xfea00f00, 0xec000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12831         { 0xff300f00, 0xed000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12832         { 0xff300f00, 0xed000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12833         { 0xffb00000, 0xf9000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12834         { 0xffb00300, 0xf9800000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12835 
12836         //----------------------------------------------------------------------
12837         // Other instructions
12838         //----------------------------------------------------------------------
12839         { 0xffffffc0, 0x0000b240, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
12840         { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12841         { 0xffffffc0, 0x0000b200, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
12842         { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12843         { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
12844         { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12845         { 0xffffffc0, 0x0000b280, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
12846         { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12847     };
12848 
12849     const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes);
12850     for (size_t i=0; i<k_num_thumb_opcodes; ++i)
12851     {
12852         if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
12853             (g_thumb_opcodes[i].variants & arm_isa) != 0)
12854             return &g_thumb_opcodes[i];
12855     }
12856     return NULL;
12857 }
12858 
12859 bool
12860 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
12861 {
12862     m_arch = arch;
12863     m_arm_isa = 0;
12864     const char *arch_cstr = arch.GetArchitectureName ();
12865     if (arch_cstr)
12866     {
12867         if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
12868         else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
12869         else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
12870         else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
12871         else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
12872         else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
12873         else if (0 == ::strcasecmp(arch_cstr, "armv7s"))    m_arm_isa = ARMv7S;
12874         else if (0 == ::strcasecmp(arch_cstr, "arm"))       m_arm_isa = ARMvAll;
12875         else if (0 == ::strcasecmp(arch_cstr, "thumb"))     m_arm_isa = ARMvAll;
12876         else if (0 == ::strncasecmp(arch_cstr,"armv4", 5))  m_arm_isa = ARMv4;
12877         else if (0 == ::strncasecmp(arch_cstr,"armv6", 5))  m_arm_isa = ARMv6;
12878         else if (0 == ::strncasecmp(arch_cstr,"armv7", 5))  m_arm_isa = ARMv7;
12879         else if (0 == ::strncasecmp(arch_cstr,"armv8", 5))  m_arm_isa = ARMv8;
12880     }
12881     return m_arm_isa != 0;
12882 }
12883 
12884 bool
12885 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
12886 {
12887     if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
12888     {
12889         if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
12890             m_opcode_mode = eModeThumb;
12891         else
12892         {
12893             AddressClass addr_class = inst_addr.GetAddressClass();
12894 
12895             if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
12896                 m_opcode_mode = eModeARM;
12897             else if (addr_class == eAddressClassCodeAlternateISA)
12898                 m_opcode_mode = eModeThumb;
12899             else
12900                 return false;
12901         }
12902         if (m_opcode_mode == eModeThumb)
12903             m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
12904         else
12905             m_opcode_cpsr = CPSR_MODE_USR;
12906         return true;
12907     }
12908     return false;
12909 }
12910 
12911 bool
12912 EmulateInstructionARM::ReadInstruction ()
12913 {
12914     bool success = false;
12915     m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
12916     if (success)
12917     {
12918         addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
12919         if (success)
12920         {
12921             Context read_inst_context;
12922             read_inst_context.type = eContextReadOpcode;
12923             read_inst_context.SetNoArgs ();
12924 
12925             if (m_opcode_cpsr & MASK_CPSR_T)
12926             {
12927                 m_opcode_mode = eModeThumb;
12928                 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
12929 
12930                 if (success)
12931                 {
12932                     if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
12933                     {
12934                         m_opcode.SetOpcode16 (thumb_opcode, GetByteOrder());
12935                     }
12936                     else
12937                     {
12938                         m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success), GetByteOrder());
12939                     }
12940                 }
12941             }
12942             else
12943             {
12944                 m_opcode_mode = eModeARM;
12945                 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success), GetByteOrder());
12946             }
12947         }
12948     }
12949     if (!success)
12950     {
12951         m_opcode_mode = eModeInvalid;
12952         m_addr = LLDB_INVALID_ADDRESS;
12953     }
12954     return success;
12955 }
12956 
12957 uint32_t
12958 EmulateInstructionARM::ArchVersion ()
12959 {
12960     return m_arm_isa;
12961 }
12962 
12963 bool
12964 EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional)
12965 {
12966    // If we are ignoring conditions, then always return true.
12967    // this allows us to iterate over disassembly code and still
12968    // emulate an instruction even if we don't have all the right
12969    // bits set in the CPSR register...
12970     if (m_ignore_conditions)
12971         return true;
12972 
12973     if (is_conditional)
12974         *is_conditional = true;
12975 
12976     const uint32_t cond = CurrentCond (opcode);
12977 
12978     if (cond == UINT32_MAX)
12979         return false;
12980 
12981     bool result = false;
12982     switch (UnsignedBits(cond, 3, 1))
12983     {
12984     case 0:
12985 		if (m_opcode_cpsr == 0)
12986 			result = true;
12987         else
12988             result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
12989 		break;
12990     case 1:
12991         if (m_opcode_cpsr == 0)
12992             result = true;
12993         else
12994             result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
12995 		break;
12996     case 2:
12997         if (m_opcode_cpsr == 0)
12998             result = true;
12999         else
13000             result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
13001 		break;
13002     case 3:
13003         if (m_opcode_cpsr == 0)
13004             result = true;
13005         else
13006             result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
13007 		break;
13008     case 4:
13009         if (m_opcode_cpsr == 0)
13010             result = true;
13011         else
13012             result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13013 		break;
13014     case 5:
13015         if (m_opcode_cpsr == 0)
13016             result = true;
13017         else
13018 		{
13019             bool n = (m_opcode_cpsr & MASK_CPSR_N);
13020             bool v = (m_opcode_cpsr & MASK_CPSR_V);
13021             result = n == v;
13022         }
13023         break;
13024     case 6:
13025         if (m_opcode_cpsr == 0)
13026             result = true;
13027         else
13028 		{
13029             bool n = (m_opcode_cpsr & MASK_CPSR_N);
13030             bool v = (m_opcode_cpsr & MASK_CPSR_V);
13031             result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13032         }
13033         break;
13034     case 7:
13035         // Always execute (cond == 0b1110, or the special 0b1111 which gives
13036         // opcodes different meanings, but always means execution happens.
13037         if (is_conditional)
13038             *is_conditional = false;
13039         return true;
13040     }
13041 
13042     if (cond & 1)
13043         result = !result;
13044     return result;
13045 }
13046 
13047 uint32_t
13048 EmulateInstructionARM::CurrentCond (const uint32_t opcode)
13049 {
13050     switch (m_opcode_mode)
13051     {
13052     case eModeInvalid:
13053         break;
13054 
13055     case eModeARM:
13056         return UnsignedBits(opcode, 31, 28);
13057 
13058     case eModeThumb:
13059         // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
13060         // 'cond' field of the encoding.
13061         {
13062             const uint32_t byte_size = m_opcode.GetByteSize();
13063             if (byte_size == 2)
13064             {
13065                 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f)
13066                     return Bits32(opcode, 11, 7);
13067             }
13068             else if (byte_size == 4)
13069             {
13070                 if (Bits32(opcode, 31, 27) == 0x1e &&
13071                     Bits32(opcode, 15, 14) == 0x02 &&
13072                     Bits32(opcode, 12, 12) == 0x00 &&
13073                     Bits32(opcode, 25, 22) <= 0x0d)
13074                 {
13075                     return Bits32(opcode, 25, 22);
13076                 }
13077             }
13078             else
13079                 // We have an invalid thumb instruction, let's bail out.
13080                 break;
13081 
13082             return m_it_session.GetCond();
13083         }
13084     }
13085     return UINT32_MAX;  // Return invalid value
13086 }
13087 
13088 bool
13089 EmulateInstructionARM::InITBlock()
13090 {
13091     return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13092 }
13093 
13094 bool
13095 EmulateInstructionARM::LastInITBlock()
13096 {
13097     return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13098 }
13099 
13100 bool
13101 EmulateInstructionARM::BadMode (uint32_t mode)
13102 {
13103 
13104     switch (mode)
13105     {
13106         case 16: return false; // '10000'
13107         case 17: return false; // '10001'
13108         case 18: return false; // '10010'
13109         case 19: return false; // '10011'
13110         case 22: return false; // '10110'
13111         case 23: return false; // '10111'
13112         case 27: return false; // '11011'
13113         case 31: return false; // '11111'
13114         default: return true;
13115     }
13116     return true;
13117 }
13118 
13119 bool
13120 EmulateInstructionARM::CurrentModeIsPrivileged ()
13121 {
13122     uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
13123 
13124     if (BadMode (mode))
13125         return false;
13126 
13127     if (mode == 16)
13128         return false;
13129 
13130     return true;
13131 }
13132 
13133 void
13134 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
13135 {
13136     bool privileged = CurrentModeIsPrivileged();
13137 
13138     uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20;
13139 
13140     if (BitIsSet (bytemask, 3))
13141     {
13142         tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
13143         if (affect_execstate)
13144             tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
13145     }
13146 
13147     if (BitIsSet (bytemask, 2))
13148     {
13149         tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
13150     }
13151 
13152     if (BitIsSet (bytemask, 1))
13153     {
13154         if (affect_execstate)
13155             tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
13156         tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
13157         if (privileged)
13158             tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
13159     }
13160 
13161     if (BitIsSet (bytemask, 0))
13162     {
13163         if (privileged)
13164             tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
13165         if (affect_execstate)
13166             tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
13167         if (privileged)
13168             tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
13169     }
13170 
13171     m_opcode_cpsr = tmp_cpsr;
13172 }
13173 
13174 
13175 bool
13176 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
13177 {
13178     addr_t target;
13179 
13180     // Check the current instruction set.
13181     if (CurrentInstrSet() == eModeARM)
13182         target = addr & 0xfffffffc;
13183     else
13184         target = addr & 0xfffffffe;
13185 
13186     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13187         return false;
13188 
13189     return true;
13190 }
13191 
13192 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
13193 bool
13194 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
13195 {
13196     addr_t target;
13197     // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
13198     // we want to record it and issue a WriteRegister callback so the clients
13199     // can track the mode changes accordingly.
13200     bool cpsr_changed = false;
13201 
13202     if (BitIsSet(addr, 0))
13203     {
13204         if (CurrentInstrSet() != eModeThumb)
13205         {
13206             SelectInstrSet(eModeThumb);
13207             cpsr_changed = true;
13208         }
13209         target = addr & 0xfffffffe;
13210         context.SetISA (eModeThumb);
13211     }
13212     else if (BitIsClear(addr, 1))
13213     {
13214         if (CurrentInstrSet() != eModeARM)
13215         {
13216             SelectInstrSet(eModeARM);
13217             cpsr_changed = true;
13218         }
13219         target = addr & 0xfffffffc;
13220         context.SetISA (eModeARM);
13221     }
13222     else
13223         return false; // address<1:0> == '10' => UNPREDICTABLE
13224 
13225     if (cpsr_changed)
13226     {
13227         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13228             return false;
13229     }
13230     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13231         return false;
13232 
13233     return true;
13234 }
13235 
13236 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
13237 bool
13238 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
13239 {
13240     if (ArchVersion() >= ARMv5T)
13241         return BXWritePC(context, addr);
13242     else
13243         return BranchWritePC((const Context)context, addr);
13244 }
13245 
13246 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
13247 bool
13248 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
13249 {
13250     if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
13251         return BXWritePC(context, addr);
13252     else
13253         return BranchWritePC((const Context)context, addr);
13254 }
13255 
13256 EmulateInstructionARM::Mode
13257 EmulateInstructionARM::CurrentInstrSet ()
13258 {
13259     return m_opcode_mode;
13260 }
13261 
13262 // Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
13263 // ReadInstruction() is performed.  This function has a side effect of updating
13264 // the m_new_inst_cpsr member variable if necessary.
13265 bool
13266 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
13267 {
13268     m_new_inst_cpsr = m_opcode_cpsr;
13269     switch (arm_or_thumb)
13270     {
13271     default:
13272         return false;
13273     case eModeARM:
13274         // Clear the T bit.
13275         m_new_inst_cpsr &= ~MASK_CPSR_T;
13276         break;
13277     case eModeThumb:
13278         // Set the T bit.
13279         m_new_inst_cpsr |= MASK_CPSR_T;
13280         break;
13281     }
13282     return true;
13283 }
13284 
13285 // This function returns TRUE if the processor currently provides support for
13286 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
13287 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
13288 bool
13289 EmulateInstructionARM::UnalignedSupport()
13290 {
13291     return (ArchVersion() >= ARMv7);
13292 }
13293 
13294 // The main addition and subtraction instructions can produce status information
13295 // about both unsigned carry and signed overflow conditions.  This status
13296 // information can be used to synthesize multi-word additions and subtractions.
13297 EmulateInstructionARM::AddWithCarryResult
13298 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
13299 {
13300     uint32_t result;
13301     uint8_t carry_out;
13302     uint8_t overflow;
13303 
13304     uint64_t unsigned_sum = x + y + carry_in;
13305     int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
13306 
13307     result = UnsignedBits(unsigned_sum, 31, 0);
13308 //    carry_out = (result == unsigned_sum ? 0 : 1);
13309     overflow = ((int32_t)result == signed_sum ? 0 : 1);
13310 
13311     if (carry_in)
13312         carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0;
13313     else
13314         carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0;
13315 
13316     AddWithCarryResult res = { result, carry_out, overflow };
13317     return res;
13318 }
13319 
13320 uint32_t
13321 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
13322 {
13323     lldb::RegisterKind reg_kind;
13324     uint32_t reg_num;
13325     switch (num)
13326     {
13327     case SP_REG:
13328         reg_kind = eRegisterKindGeneric;
13329         reg_num  = LLDB_REGNUM_GENERIC_SP;
13330         break;
13331     case LR_REG:
13332         reg_kind = eRegisterKindGeneric;
13333         reg_num  = LLDB_REGNUM_GENERIC_RA;
13334         break;
13335     case PC_REG:
13336         reg_kind = eRegisterKindGeneric;
13337         reg_num  = LLDB_REGNUM_GENERIC_PC;
13338         break;
13339     default:
13340         if (num < SP_REG)
13341         {
13342             reg_kind = eRegisterKindDWARF;
13343             reg_num  = dwarf_r0 + num;
13344         }
13345         else
13346         {
13347             //assert(0 && "Invalid register number");
13348             *success = false;
13349             return UINT32_MAX;
13350         }
13351         break;
13352     }
13353 
13354     // Read our register.
13355     uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
13356 
13357     // When executing an ARM instruction , PC reads as the address of the current
13358     // instruction plus 8.
13359     // When executing a Thumb instruction , PC reads as the address of the current
13360     // instruction plus 4.
13361     if (num == 15)
13362     {
13363         if (CurrentInstrSet() == eModeARM)
13364             val += 8;
13365         else
13366             val += 4;
13367     }
13368 
13369     return val;
13370 }
13371 
13372 // Write the result to the ARM core register Rd, and optionally update the
13373 // condition flags based on the result.
13374 //
13375 // This helper method tries to encapsulate the following pseudocode from the
13376 // ARM Architecture Reference Manual:
13377 //
13378 // if d == 15 then         // Can only occur for encoding A1
13379 //     ALUWritePC(result); // setflags is always FALSE here
13380 // else
13381 //     R[d] = result;
13382 //     if setflags then
13383 //         APSR.N = result<31>;
13384 //         APSR.Z = IsZeroBit(result);
13385 //         APSR.C = carry;
13386 //         // APSR.V unchanged
13387 //
13388 // In the above case, the API client does not pass in the overflow arg, which
13389 // defaults to ~0u.
13390 bool
13391 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
13392                                                   const uint32_t result,
13393                                                   const uint32_t Rd,
13394                                                   bool setflags,
13395                                                   const uint32_t carry,
13396                                                   const uint32_t overflow)
13397 {
13398     if (Rd == 15)
13399     {
13400         if (!ALUWritePC (context, result))
13401             return false;
13402     }
13403     else
13404     {
13405         lldb::RegisterKind reg_kind;
13406         uint32_t reg_num;
13407         switch (Rd)
13408         {
13409         case SP_REG:
13410             reg_kind = eRegisterKindGeneric;
13411             reg_num  = LLDB_REGNUM_GENERIC_SP;
13412             break;
13413         case LR_REG:
13414             reg_kind = eRegisterKindGeneric;
13415             reg_num  = LLDB_REGNUM_GENERIC_RA;
13416             break;
13417         default:
13418             reg_kind = eRegisterKindDWARF;
13419             reg_num  = dwarf_r0 + Rd;
13420         }
13421         if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
13422             return false;
13423         if (setflags)
13424             return WriteFlags (context, result, carry, overflow);
13425     }
13426     return true;
13427 }
13428 
13429 // This helper method tries to encapsulate the following pseudocode from the
13430 // ARM Architecture Reference Manual:
13431 //
13432 // APSR.N = result<31>;
13433 // APSR.Z = IsZeroBit(result);
13434 // APSR.C = carry;
13435 // APSR.V = overflow
13436 //
13437 // Default arguments can be specified for carry and overflow parameters, which means
13438 // not to update the respective flags.
13439 bool
13440 EmulateInstructionARM::WriteFlags (Context &context,
13441                                    const uint32_t result,
13442                                    const uint32_t carry,
13443                                    const uint32_t overflow)
13444 {
13445     m_new_inst_cpsr = m_opcode_cpsr;
13446     SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
13447     SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
13448     if (carry != ~0u)
13449         SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
13450     if (overflow != ~0u)
13451         SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
13452     if (m_new_inst_cpsr != m_opcode_cpsr)
13453     {
13454         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13455             return false;
13456     }
13457     return true;
13458 }
13459 
13460 bool
13461 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
13462 {
13463     // Advance the ITSTATE bits to their values for the next instruction.
13464     if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
13465         m_it_session.ITAdvance();
13466 
13467     ARMOpcode *opcode_data = NULL;
13468 
13469     if (m_opcode_mode == eModeThumb)
13470         opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13471     else if (m_opcode_mode == eModeARM)
13472         opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13473 
13474     if (opcode_data == NULL)
13475         return false;
13476 
13477     const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
13478     m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
13479 
13480     bool success = false;
13481     if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
13482     {
13483         m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF,
13484                                                 dwarf_cpsr,
13485                                                 0,
13486                                                 &success);
13487     }
13488 
13489     // Only return false if we are unable to read the CPSR if we care about conditions
13490     if (success == false && m_ignore_conditions == false)
13491         return false;
13492 
13493     uint32_t orig_pc_value = 0;
13494     if (auto_advance_pc)
13495     {
13496         orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13497         if (!success)
13498             return false;
13499     }
13500 
13501     // Call the Emulate... function.
13502     success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
13503     if (!success)
13504         return false;
13505 
13506     if (auto_advance_pc)
13507     {
13508         uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13509         if (!success)
13510             return false;
13511 
13512         if (auto_advance_pc && (after_pc_value == orig_pc_value))
13513         {
13514             if (opcode_data->size == eSize32)
13515                 after_pc_value += 4;
13516             else if (opcode_data->size == eSize16)
13517                 after_pc_value += 2;
13518 
13519             EmulateInstruction::Context context;
13520             context.type = eContextAdvancePC;
13521             context.SetNoArgs();
13522             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
13523                 return false;
13524 
13525         }
13526     }
13527     return true;
13528 }
13529 
13530 bool
13531 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data)
13532 {
13533     if (!test_data)
13534     {
13535         out_stream->Printf ("TestEmulation: Missing test data.\n");
13536         return false;
13537     }
13538 
13539     static ConstString opcode_key ("opcode");
13540     static ConstString before_key ("before_state");
13541     static ConstString after_key ("after_state");
13542 
13543     OptionValueSP value_sp = test_data->GetValueForKey (opcode_key);
13544 
13545     uint32_t test_opcode;
13546     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64))
13547     {
13548         out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n");
13549         return false;
13550     }
13551     test_opcode = value_sp->GetUInt64Value ();
13552 
13553     if (arch.GetTriple().getArch() == llvm::Triple::arm)
13554     {
13555         m_opcode_mode = eModeARM;
13556         m_opcode.SetOpcode32 (test_opcode, GetByteOrder());
13557     }
13558     else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
13559     {
13560         m_opcode_mode = eModeThumb;
13561         if (test_opcode < 0x10000)
13562             m_opcode.SetOpcode16 (test_opcode, GetByteOrder());
13563         else
13564             m_opcode.SetOpcode32 (test_opcode, GetByteOrder());
13565 
13566     }
13567     else
13568     {
13569         out_stream->Printf ("TestEmulation:  Invalid arch.\n");
13570         return false;
13571     }
13572 
13573     EmulationStateARM before_state;
13574     EmulationStateARM after_state;
13575 
13576     value_sp = test_data->GetValueForKey (before_key);
13577     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13578     {
13579         out_stream->Printf ("TestEmulation:  Failed to find 'before' state.\n");
13580         return false;
13581     }
13582 
13583     OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary ();
13584     if (!before_state.LoadStateFromDictionary (state_dictionary))
13585     {
13586         out_stream->Printf ("TestEmulation:  Failed loading 'before' state.\n");
13587         return false;
13588     }
13589 
13590     value_sp = test_data->GetValueForKey (after_key);
13591     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13592     {
13593         out_stream->Printf ("TestEmulation:  Failed to find 'after' state.\n");
13594         return false;
13595     }
13596 
13597     state_dictionary = value_sp->GetAsDictionary ();
13598     if (!after_state.LoadStateFromDictionary (state_dictionary))
13599     {
13600         out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n");
13601         return false;
13602     }
13603 
13604     SetBaton ((void *) &before_state);
13605     SetCallbacks (&EmulationStateARM::ReadPseudoMemory,
13606                   &EmulationStateARM::WritePseudoMemory,
13607                   &EmulationStateARM::ReadPseudoRegister,
13608                   &EmulationStateARM::WritePseudoRegister);
13609 
13610     bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC);
13611     if (!success)
13612     {
13613         out_stream->Printf ("TestEmulation:  EvaluateInstruction() failed.\n");
13614         return false;
13615     }
13616 
13617     success = before_state.CompareState (after_state);
13618     if (!success)
13619         out_stream->Printf ("TestEmulation:  'before' and 'after' states do not match.\n");
13620 
13621     return success;
13622 }
13623 //
13624 //
13625 //const char *
13626 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
13627 //{
13628 //    if (reg_kind == eRegisterKindGeneric)
13629 //    {
13630 //        switch (reg_num)
13631 //        {
13632 //        case LLDB_REGNUM_GENERIC_PC:    return "pc";
13633 //        case LLDB_REGNUM_GENERIC_SP:    return "sp";
13634 //        case LLDB_REGNUM_GENERIC_FP:    return "fp";
13635 //        case LLDB_REGNUM_GENERIC_RA:    return "lr";
13636 //        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
13637 //        default: return NULL;
13638 //        }
13639 //    }
13640 //    else if (reg_kind == eRegisterKindDWARF)
13641 //    {
13642 //        return GetARMDWARFRegisterName (reg_num);
13643 //    }
13644 //    return NULL;
13645 //}
13646 //
13647 bool
13648 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
13649 {
13650     unwind_plan.Clear();
13651     unwind_plan.SetRegisterKind (eRegisterKindDWARF);
13652 
13653     UnwindPlan::RowSP row(new UnwindPlan::Row);
13654 
13655     // Our previous Call Frame Address is the stack pointer
13656     row->GetCFAValue().SetIsRegisterPlusOffset (dwarf_sp, 0);
13657 
13658     // Our previous PC is in the LR
13659     row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true);
13660     unwind_plan.AppendRow (row);
13661 
13662     // All other registers are the same.
13663 
13664     unwind_plan.SetSourceName ("EmulateInstructionARM");
13665     unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
13666     unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
13667     return true;
13668 }
13669