1 //===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include <stdlib.h>
11 
12 #include "EmulateInstructionARM.h"
13 #include "EmulationStateARM.h"
14 #include "lldb/Core/ArchSpec.h"
15 #include "lldb/Core/Address.h"
16 #include "lldb/Core/ConstString.h"
17 #include "lldb/Core/PluginManager.h"
18 #include "lldb/Core/Stream.h"
19 #include "lldb/Interpreter/OptionValueArray.h"
20 #include "lldb/Interpreter/OptionValueDictionary.h"
21 #include "lldb/Symbol/UnwindPlan.h"
22 
23 #include "Plugins/Process/Utility/ARMDefines.h"
24 #include "Plugins/Process/Utility/ARMUtils.h"
25 #include "Utility/ARM_DWARF_Registers.h"
26 
27 #include "llvm/ADT/STLExtras.h"
28 #include "llvm/Support/MathExtras.h" // for SignExtend32 template function
29                                      // and countTrailingZeros function
30 
31 using namespace lldb;
32 using namespace lldb_private;
33 
34 // Convenient macro definitions.
35 #define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS)
36 #define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS)
37 
38 #define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
39 
40 //----------------------------------------------------------------------
41 //
42 // ITSession implementation
43 //
44 //----------------------------------------------------------------------
45 
46 // A8.6.50
47 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
48 static uint32_t
49 CountITSize (uint32_t ITMask) {
50     // First count the trailing zeros of the IT mask.
51     uint32_t TZ = llvm::countTrailingZeros(ITMask);
52     if (TZ > 3)
53     {
54 #ifdef LLDB_CONFIGURATION_DEBUG
55         printf("Encoding error: IT Mask '0000'\n");
56 #endif
57         return 0;
58     }
59     return (4 - TZ);
60 }
61 
62 // Init ITState.  Note that at least one bit is always 1 in mask.
63 bool ITSession::InitIT(uint32_t bits7_0)
64 {
65     ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
66     if (ITCounter == 0)
67         return false;
68 
69     // A8.6.50 IT
70     unsigned short FirstCond = Bits32(bits7_0, 7, 4);
71     if (FirstCond == 0xF)
72     {
73 #ifdef LLDB_CONFIGURATION_DEBUG
74         printf("Encoding error: IT FirstCond '1111'\n");
75 #endif
76         return false;
77     }
78     if (FirstCond == 0xE && ITCounter != 1)
79     {
80 #ifdef LLDB_CONFIGURATION_DEBUG
81         printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
82 #endif
83         return false;
84     }
85 
86     ITState = bits7_0;
87     return true;
88 }
89 
90 // Update ITState if necessary.
91 void ITSession::ITAdvance()
92 {
93     //assert(ITCounter);
94     --ITCounter;
95     if (ITCounter == 0)
96         ITState = 0;
97     else
98     {
99         unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
100         SetBits32(ITState, 4, 0, NewITState4_0);
101     }
102 }
103 
104 // Return true if we're inside an IT Block.
105 bool ITSession::InITBlock()
106 {
107     return ITCounter != 0;
108 }
109 
110 // Return true if we're the last instruction inside an IT Block.
111 bool ITSession::LastInITBlock()
112 {
113     return ITCounter == 1;
114 }
115 
116 // Get condition bits for the current thumb instruction.
117 uint32_t ITSession::GetCond()
118 {
119     if (InITBlock())
120         return Bits32(ITState, 7, 4);
121     else
122         return COND_AL;
123 }
124 
125 // ARM constants used during decoding
126 #define REG_RD          0
127 #define LDM_REGLIST     1
128 #define SP_REG          13
129 #define LR_REG          14
130 #define PC_REG          15
131 #define PC_REGLIST_BIT  0x8000
132 
133 #define ARMv4     (1u << 0)
134 #define ARMv4T    (1u << 1)
135 #define ARMv5T    (1u << 2)
136 #define ARMv5TE   (1u << 3)
137 #define ARMv5TEJ  (1u << 4)
138 #define ARMv6     (1u << 5)
139 #define ARMv6K    (1u << 6)
140 #define ARMv6T2   (1u << 7)
141 #define ARMv7     (1u << 8)
142 #define ARMv7S    (1u << 9)
143 #define ARMv8     (1u << 10)
144 #define ARMvAll   (0xffffffffu)
145 
146 #define ARMV4T_ABOVE  (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
147 #define ARMV5_ABOVE   (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
148 #define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
149 #define ARMV5J_ABOVE  (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
150 #define ARMV6_ABOVE   (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
151 #define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv7S|ARMv8)
152 #define ARMV7_ABOVE   (ARMv7|ARMv7S|ARMv8)
153 
154 #define No_VFP  0
155 #define VFPv1   (1u << 1)
156 #define VFPv2   (1u << 2)
157 #define VFPv3   (1u << 3)
158 #define AdvancedSIMD (1u << 4)
159 
160 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
161 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
162 #define VFPv2v3     (VFPv2 | VFPv3)
163 
164 //----------------------------------------------------------------------
165 //
166 // EmulateInstructionARM implementation
167 //
168 //----------------------------------------------------------------------
169 
170 void
171 EmulateInstructionARM::Initialize ()
172 {
173     PluginManager::RegisterPlugin (GetPluginNameStatic (),
174                                    GetPluginDescriptionStatic (),
175                                    CreateInstance);
176 }
177 
178 void
179 EmulateInstructionARM::Terminate ()
180 {
181     PluginManager::UnregisterPlugin (CreateInstance);
182 }
183 
184 ConstString
185 EmulateInstructionARM::GetPluginNameStatic ()
186 {
187     static ConstString g_name("arm");
188     return g_name;
189 }
190 
191 const char *
192 EmulateInstructionARM::GetPluginDescriptionStatic ()
193 {
194     return "Emulate instructions for the ARM architecture.";
195 }
196 
197 EmulateInstruction *
198 EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type)
199 {
200     if (EmulateInstructionARM::SupportsEmulatingInstructionsOfTypeStatic(inst_type))
201     {
202         if (arch.GetTriple().getArch() == llvm::Triple::arm)
203         {
204             std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
205 
206             if (emulate_insn_ap.get())
207                 return emulate_insn_ap.release();
208         }
209         else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
210         {
211             std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
212 
213             if (emulate_insn_ap.get())
214                 return emulate_insn_ap.release();
215         }
216     }
217 
218     return NULL;
219 }
220 
221 bool
222 EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch)
223 {
224     if (arch.GetTriple().getArch () == llvm::Triple::arm)
225         return true;
226     else if (arch.GetTriple().getArch () == llvm::Triple::thumb)
227         return true;
228 
229     return false;
230 }
231 
232 // Write "bits (32) UNKNOWN" to memory address "address".  Helper function for many ARM instructions.
233 bool
234 EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address)
235 {
236     EmulateInstruction::Context context;
237     context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
238     context.SetNoArgs ();
239 
240     uint32_t random_data = rand ();
241     const uint32_t addr_byte_size = GetAddressByteSize();
242 
243     if (!MemAWrite (context, address, random_data, addr_byte_size))
244         return false;
245 
246     return true;
247 }
248 
249 // Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM instructions.
250 bool
251 EmulateInstructionARM::WriteBits32Unknown (int n)
252 {
253     EmulateInstruction::Context context;
254     context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
255     context.SetNoArgs ();
256 
257     bool success;
258     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
259 
260     if (!success)
261         return false;
262 
263     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
264         return false;
265 
266     return true;
267 }
268 
269 bool
270 EmulateInstructionARM::GetRegisterInfo (lldb::RegisterKind reg_kind, uint32_t reg_num, RegisterInfo &reg_info)
271 {
272     if (reg_kind == eRegisterKindGeneric)
273     {
274         switch (reg_num)
275         {
276             case LLDB_REGNUM_GENERIC_PC:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break;
277             case LLDB_REGNUM_GENERIC_SP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break;
278             case LLDB_REGNUM_GENERIC_FP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break;
279             case LLDB_REGNUM_GENERIC_RA:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break;
280             case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break;
281             default: return false;
282         }
283     }
284 
285     if (reg_kind == eRegisterKindDWARF)
286         return GetARMDWARFRegisterInfo(reg_num, reg_info);
287     return false;
288 }
289 
290 uint32_t
291 EmulateInstructionARM::GetFramePointerRegisterNumber () const
292 {
293     if (m_arch.GetTriple().getEnvironment() == llvm::Triple::Android)
294         return LLDB_INVALID_REGNUM; // Don't use frame pointer on android
295 
296     bool is_apple = false;
297     if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
298         is_apple = true;
299     switch (m_arch.GetTriple().getOS())
300     {
301             case llvm::Triple::Darwin:
302             case llvm::Triple::MacOSX:
303             case llvm::Triple::IOS:
304                 is_apple = true;
305                 break;
306             default:
307                 break;
308     }
309 
310     /* On Apple iOS et al, the frame pointer register is always r7.
311      * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
312      */
313 
314     uint32_t fp_regnum = 11;
315 
316     if (is_apple)
317         fp_regnum = 7;
318 
319     if (m_opcode_mode == eModeThumb)
320         fp_regnum = 7;
321 
322     return fp_regnum;
323 }
324 
325 uint32_t
326 EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const
327 {
328     bool is_apple = false;
329     if (m_arch.GetTriple().getVendor() == llvm::Triple::Apple)
330         is_apple = true;
331     switch (m_arch.GetTriple().getOS())
332     {
333             case llvm::Triple::Darwin:
334             case llvm::Triple::MacOSX:
335             case llvm::Triple::IOS:
336                 is_apple = true;
337                 break;
338             default:
339                 break;
340     }
341 
342     /* On Apple iOS et al, the frame pointer register is always r7.
343      * Typically on other ARM systems, thumb code uses r7; arm code uses r11.
344      */
345 
346     uint32_t fp_regnum = dwarf_r11;
347 
348     if (is_apple)
349         fp_regnum = dwarf_r7;
350 
351     if (m_opcode_mode == eModeThumb)
352         fp_regnum = dwarf_r7;
353 
354     return fp_regnum;
355 }
356 
357 // Push Multiple Registers stores multiple registers to the stack, storing to
358 // consecutive memory locations ending just below the address in SP, and updates
359 // SP to point to the start of the stored data.
360 bool
361 EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding)
362 {
363 #if 0
364     // ARM pseudo code...
365     if (ConditionPassed())
366     {
367         EncodingSpecificOperations();
368         NullCheckIfThumbEE(13);
369         address = SP - 4*BitCount(registers);
370 
371         for (i = 0 to 14)
372         {
373             if (registers<i> == '1')
374             {
375                 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
376                     MemA[address,4] = bits(32) UNKNOWN;
377                 else
378                     MemA[address,4] = R[i];
379                 address = address + 4;
380             }
381         }
382 
383         if (registers<15> == '1') // Only possible for encoding A1 or A2
384             MemA[address,4] = PCStoreValue();
385 
386         SP = SP - 4*BitCount(registers);
387     }
388 #endif
389 
390     bool success = false;
391     if (ConditionPassed(opcode))
392     {
393         const uint32_t addr_byte_size = GetAddressByteSize();
394         const addr_t sp = ReadCoreReg (SP_REG, &success);
395         if (!success)
396             return false;
397         uint32_t registers = 0;
398         uint32_t Rt; // the source register
399         switch (encoding) {
400         case eEncodingT1:
401             registers = Bits32(opcode, 7, 0);
402             // The M bit represents LR.
403             if (Bit32(opcode, 8))
404                 registers |= (1u << 14);
405             // if BitCount(registers) < 1 then UNPREDICTABLE;
406             if (BitCount(registers) < 1)
407                 return false;
408             break;
409         case eEncodingT2:
410             // Ignore bits 15 & 13.
411             registers = Bits32(opcode, 15, 0) & ~0xa000;
412             // if BitCount(registers) < 2 then UNPREDICTABLE;
413             if (BitCount(registers) < 2)
414                 return false;
415             break;
416         case eEncodingT3:
417             Rt = Bits32(opcode, 15, 12);
418             // if BadReg(t) then UNPREDICTABLE;
419             if (BadReg(Rt))
420                 return false;
421             registers = (1u << Rt);
422             break;
423         case eEncodingA1:
424             registers = Bits32(opcode, 15, 0);
425             // Instead of return false, let's handle the following case as well,
426             // which amounts to pushing one reg onto the full descending stacks.
427             // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
428             break;
429         case eEncodingA2:
430             Rt = Bits32(opcode, 15, 12);
431             // if t == 13 then UNPREDICTABLE;
432             if (Rt == dwarf_sp)
433                 return false;
434             registers = (1u << Rt);
435             break;
436         default:
437             return false;
438         }
439         addr_t sp_offset = addr_byte_size * BitCount (registers);
440         addr_t addr = sp - sp_offset;
441         uint32_t i;
442 
443         EmulateInstruction::Context context;
444         context.type = EmulateInstruction::eContextPushRegisterOnStack;
445         RegisterInfo reg_info;
446         RegisterInfo sp_reg;
447         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
448         for (i=0; i<15; ++i)
449         {
450             if (BitIsSet (registers, i))
451             {
452                 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info);
453                 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
454                 uint32_t reg_value = ReadCoreReg(i, &success);
455                 if (!success)
456                     return false;
457                 if (!MemAWrite (context, addr, reg_value, addr_byte_size))
458                     return false;
459                 addr += addr_byte_size;
460             }
461         }
462 
463         if (BitIsSet (registers, 15))
464         {
465             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info);
466             context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
467             const uint32_t pc = ReadCoreReg(PC_REG, &success);
468             if (!success)
469                 return false;
470             if (!MemAWrite (context, addr, pc, addr_byte_size))
471                 return false;
472         }
473 
474         context.type = EmulateInstruction::eContextAdjustStackPointer;
475         context.SetImmediateSigned (-sp_offset);
476 
477         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
478             return false;
479     }
480     return true;
481 }
482 
483 // Pop Multiple Registers loads multiple registers from the stack, loading from
484 // consecutive memory locations staring at the address in SP, and updates
485 // SP to point just above the loaded data.
486 bool
487 EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding)
488 {
489 #if 0
490     // ARM pseudo code...
491     if (ConditionPassed())
492     {
493         EncodingSpecificOperations(); NullCheckIfThumbEE(13);
494         address = SP;
495         for i = 0 to 14
496             if registers<i> == '1' then
497                 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
498         if registers<15> == '1' then
499             if UnalignedAllowed then
500                 LoadWritePC(MemU[address,4]);
501             else
502                 LoadWritePC(MemA[address,4]);
503         if registers<13> == '0' then SP = SP + 4*BitCount(registers);
504         if registers<13> == '1' then SP = bits(32) UNKNOWN;
505     }
506 #endif
507 
508     bool success = false;
509 
510     if (ConditionPassed(opcode))
511     {
512         const uint32_t addr_byte_size = GetAddressByteSize();
513         const addr_t sp = ReadCoreReg (SP_REG, &success);
514         if (!success)
515             return false;
516         uint32_t registers = 0;
517         uint32_t Rt; // the destination register
518         switch (encoding) {
519         case eEncodingT1:
520             registers = Bits32(opcode, 7, 0);
521             // The P bit represents PC.
522             if (Bit32(opcode, 8))
523                 registers |= (1u << 15);
524             // if BitCount(registers) < 1 then UNPREDICTABLE;
525             if (BitCount(registers) < 1)
526                 return false;
527             break;
528         case eEncodingT2:
529             // Ignore bit 13.
530             registers = Bits32(opcode, 15, 0) & ~0x2000;
531             // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
532             if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
533                 return false;
534             // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
535             if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
536                 return false;
537             break;
538         case eEncodingT3:
539             Rt = Bits32(opcode, 15, 12);
540             // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
541             if (Rt == 13)
542                 return false;
543             if (Rt == 15 && InITBlock() && !LastInITBlock())
544                 return false;
545             registers = (1u << Rt);
546             break;
547         case eEncodingA1:
548             registers = Bits32(opcode, 15, 0);
549             // Instead of return false, let's handle the following case as well,
550             // which amounts to popping one reg from the full descending stacks.
551             // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
552 
553             // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
554             if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
555                 return false;
556             break;
557         case eEncodingA2:
558             Rt = Bits32(opcode, 15, 12);
559             // if t == 13 then UNPREDICTABLE;
560             if (Rt == dwarf_sp)
561                 return false;
562             registers = (1u << Rt);
563             break;
564         default:
565             return false;
566         }
567         addr_t sp_offset = addr_byte_size * BitCount (registers);
568         addr_t addr = sp;
569         uint32_t i, data;
570 
571         EmulateInstruction::Context context;
572         context.type = EmulateInstruction::eContextPopRegisterOffStack;
573 
574         RegisterInfo sp_reg;
575         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
576 
577         for (i=0; i<15; ++i)
578         {
579             if (BitIsSet (registers, i))
580             {
581                 context.SetRegisterPlusOffset (sp_reg, addr - sp);
582                 data = MemARead(context, addr, 4, 0, &success);
583                 if (!success)
584                     return false;
585                 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data))
586                     return false;
587                 addr += addr_byte_size;
588             }
589         }
590 
591         if (BitIsSet (registers, 15))
592         {
593             context.SetRegisterPlusOffset (sp_reg, addr - sp);
594             data = MemARead(context, addr, 4, 0, &success);
595             if (!success)
596                 return false;
597             // In ARMv5T and above, this is an interworking branch.
598             if (!LoadWritePC(context, data))
599                 return false;
600             //addr += addr_byte_size;
601         }
602 
603         context.type = EmulateInstruction::eContextAdjustStackPointer;
604         context.SetImmediateSigned (sp_offset);
605 
606         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
607             return false;
608     }
609     return true;
610 }
611 
612 // Set r7 or ip to point to saved value residing within the stack.
613 // ADD (SP plus immediate)
614 bool
615 EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding)
616 {
617 #if 0
618     // ARM pseudo code...
619     if (ConditionPassed())
620     {
621         EncodingSpecificOperations();
622         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
623         if d == 15 then
624            ALUWritePC(result); // setflags is always FALSE here
625         else
626             R[d] = result;
627             if setflags then
628                 APSR.N = result<31>;
629                 APSR.Z = IsZeroBit(result);
630                 APSR.C = carry;
631                 APSR.V = overflow;
632     }
633 #endif
634 
635     bool success = false;
636 
637     if (ConditionPassed(opcode))
638     {
639         const addr_t sp = ReadCoreReg (SP_REG, &success);
640         if (!success)
641             return false;
642         uint32_t Rd; // the destination register
643         uint32_t imm32;
644         switch (encoding) {
645         case eEncodingT1:
646             Rd = 7;
647             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
648             break;
649         case eEncodingA1:
650             Rd = Bits32(opcode, 15, 12);
651             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
652             break;
653         default:
654             return false;
655         }
656         addr_t sp_offset = imm32;
657         addr_t addr = sp + sp_offset; // a pointer to the stack area
658 
659         EmulateInstruction::Context context;
660         if (Rd == GetFramePointerRegisterNumber())
661             context.type = eContextSetFramePointer;
662         else
663             context.type = EmulateInstruction::eContextRegisterPlusOffset;
664         RegisterInfo sp_reg;
665         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
666         context.SetRegisterPlusOffset (sp_reg, sp_offset);
667 
668         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
669             return false;
670     }
671     return true;
672 }
673 
674 // Set r7 or ip to the current stack pointer.
675 // MOV (register)
676 bool
677 EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding)
678 {
679 #if 0
680     // ARM pseudo code...
681     if (ConditionPassed())
682     {
683         EncodingSpecificOperations();
684         result = R[m];
685         if d == 15 then
686             ALUWritePC(result); // setflags is always FALSE here
687         else
688             R[d] = result;
689             if setflags then
690                 APSR.N = result<31>;
691                 APSR.Z = IsZeroBit(result);
692                 // APSR.C unchanged
693                 // APSR.V unchanged
694     }
695 #endif
696 
697     bool success = false;
698 
699     if (ConditionPassed(opcode))
700     {
701         const addr_t sp = ReadCoreReg (SP_REG, &success);
702         if (!success)
703             return false;
704         uint32_t Rd; // the destination register
705         switch (encoding) {
706         case eEncodingT1:
707             Rd = 7;
708             break;
709         case eEncodingA1:
710             Rd = 12;
711             break;
712         default:
713             return false;
714         }
715 
716         EmulateInstruction::Context context;
717         if (Rd == GetFramePointerRegisterNumber())
718             context.type = EmulateInstruction::eContextSetFramePointer;
719         else
720             context.type = EmulateInstruction::eContextRegisterPlusOffset;
721         RegisterInfo sp_reg;
722         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
723         context.SetRegisterPlusOffset (sp_reg, 0);
724 
725         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
726             return false;
727     }
728     return true;
729 }
730 
731 // Move from high register (r8-r15) to low register (r0-r7).
732 // MOV (register)
733 bool
734 EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding)
735 {
736     return EmulateMOVRdRm (opcode, encoding);
737 }
738 
739 // Move from register to register.
740 // MOV (register)
741 bool
742 EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding)
743 {
744 #if 0
745     // ARM pseudo code...
746     if (ConditionPassed())
747     {
748         EncodingSpecificOperations();
749         result = R[m];
750         if d == 15 then
751             ALUWritePC(result); // setflags is always FALSE here
752         else
753             R[d] = result;
754             if setflags then
755                 APSR.N = result<31>;
756                 APSR.Z = IsZeroBit(result);
757                 // APSR.C unchanged
758                 // APSR.V unchanged
759     }
760 #endif
761 
762     bool success = false;
763 
764     if (ConditionPassed(opcode))
765     {
766         uint32_t Rm; // the source register
767         uint32_t Rd; // the destination register
768         bool setflags;
769         switch (encoding) {
770         case eEncodingT1:
771             Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
772             Rm = Bits32(opcode, 6, 3);
773             setflags = false;
774             if (Rd == 15 && InITBlock() && !LastInITBlock())
775                 return false;
776             break;
777         case eEncodingT2:
778             Rd = Bits32(opcode, 2, 0);
779             Rm = Bits32(opcode, 5, 3);
780             setflags = true;
781             if (InITBlock())
782                 return false;
783             break;
784         case eEncodingT3:
785             Rd = Bits32(opcode, 11, 8);
786             Rm = Bits32(opcode, 3, 0);
787             setflags = BitIsSet(opcode, 20);
788             // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
789             if (setflags && (BadReg(Rd) || BadReg(Rm)))
790                 return false;
791             // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE;
792             if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
793                 return false;
794             break;
795         case eEncodingA1:
796             Rd = Bits32(opcode, 15, 12);
797             Rm = Bits32(opcode, 3, 0);
798             setflags = BitIsSet(opcode, 20);
799 
800             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
801             if (Rd == 15 && setflags)
802                 return EmulateSUBSPcLrEtc (opcode, encoding);
803             break;
804         default:
805             return false;
806         }
807         uint32_t result = ReadCoreReg(Rm, &success);
808         if (!success)
809             return false;
810 
811         // The context specifies that Rm is to be moved into Rd.
812         EmulateInstruction::Context context;
813         if (Rd == 13)
814             context.type = EmulateInstruction::eContextAdjustStackPointer;
815         else
816             context.type = EmulateInstruction::eContextRegisterPlusOffset;
817         RegisterInfo dwarf_reg;
818         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
819         context.SetRegisterPlusOffset (dwarf_reg, 0);
820 
821         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
822             return false;
823     }
824     return true;
825 }
826 
827 // Move (immediate) writes an immediate value to the destination register.  It
828 // can optionally update the condition flags based on the value.
829 // MOV (immediate)
830 bool
831 EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding)
832 {
833 #if 0
834     // ARM pseudo code...
835     if (ConditionPassed())
836     {
837         EncodingSpecificOperations();
838         result = imm32;
839         if d == 15 then         // Can only occur for ARM encoding
840             ALUWritePC(result); // setflags is always FALSE here
841         else
842             R[d] = result;
843             if setflags then
844                 APSR.N = result<31>;
845                 APSR.Z = IsZeroBit(result);
846                 APSR.C = carry;
847                 // APSR.V unchanged
848     }
849 #endif
850 
851     if (ConditionPassed(opcode))
852     {
853         uint32_t Rd; // the destination register
854         uint32_t imm32; // the immediate value to be written to Rd
855         uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
856                             // for setflags == false, this value is a don't care
857                             // initialized to 0 to silence the static analyzer
858         bool setflags;
859         switch (encoding) {
860             case eEncodingT1:
861                 Rd = Bits32(opcode, 10, 8);
862                 setflags = !InITBlock();
863                 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
864                 carry = APSR_C;
865 
866                 break;
867 
868             case eEncodingT2:
869                 Rd = Bits32(opcode, 11, 8);
870                 setflags = BitIsSet(opcode, 20);
871                 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
872                 if (BadReg(Rd))
873                   return false;
874 
875                 break;
876 
877             case eEncodingT3:
878             {
879                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32);
880                 Rd = Bits32 (opcode, 11, 8);
881                 setflags = false;
882                 uint32_t imm4 = Bits32 (opcode, 19, 16);
883                 uint32_t imm3 = Bits32 (opcode, 14, 12);
884                 uint32_t i = Bit32 (opcode, 26);
885                 uint32_t imm8 = Bits32 (opcode, 7, 0);
886                 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
887 
888                 // if BadReg(d) then UNPREDICTABLE;
889                 if (BadReg (Rd))
890                     return false;
891             }
892                 break;
893 
894             case eEncodingA1:
895                 // d = UInt(Rd); setflags = (S == '1'); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C);
896                 Rd = Bits32 (opcode, 15, 12);
897                 setflags = BitIsSet (opcode, 20);
898                 imm32 = ARMExpandImm_C (opcode, APSR_C, carry);
899 
900                 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
901                 if ((Rd == 15) && setflags)
902                     return EmulateSUBSPcLrEtc (opcode, encoding);
903 
904                 break;
905 
906             case eEncodingA2:
907             {
908                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
909                 Rd = Bits32 (opcode, 15, 12);
910                 setflags = false;
911                 uint32_t imm4 = Bits32 (opcode, 19, 16);
912                 uint32_t imm12 = Bits32 (opcode, 11, 0);
913                 imm32 = (imm4 << 12) | imm12;
914 
915                 // if d == 15 then UNPREDICTABLE;
916                 if (Rd == 15)
917                     return false;
918             }
919                 break;
920 
921             default:
922                 return false;
923         }
924         uint32_t result = imm32;
925 
926         // The context specifies that an immediate is to be moved into Rd.
927         EmulateInstruction::Context context;
928         context.type = EmulateInstruction::eContextImmediate;
929         context.SetNoArgs ();
930 
931         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
932             return false;
933     }
934     return true;
935 }
936 
937 // MUL multiplies two register values.  The least significant 32 bits of the result are written to the destination
938 // register.  These 32 bits do not depend on whether the source register values are considered to be signed values or
939 // unsigned values.
940 //
941 // Optionally, it can update the condition flags based on the result.  In the Thumb instruction set, this option is
942 // limited to only a few forms of the instruction.
943 bool
944 EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding)
945 {
946 #if 0
947     if ConditionPassed() then
948         EncodingSpecificOperations();
949         operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
950         operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
951         result = operand1 * operand2;
952         R[d] = result<31:0>;
953         if setflags then
954             APSR.N = result<31>;
955             APSR.Z = IsZeroBit(result);
956             if ArchVersion() == 4 then
957                 APSR.C = bit UNKNOWN;
958             // else APSR.C unchanged
959             // APSR.V always unchanged
960 #endif
961 
962     if (ConditionPassed(opcode))
963     {
964         uint32_t d;
965         uint32_t n;
966         uint32_t m;
967         bool setflags;
968 
969         // EncodingSpecificOperations();
970         switch (encoding)
971         {
972             case eEncodingT1:
973                 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
974                 d = Bits32 (opcode, 2, 0);
975                 n = Bits32 (opcode, 5, 3);
976                 m = Bits32 (opcode, 2, 0);
977                 setflags = !InITBlock();
978 
979                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
980                 if ((ArchVersion() < ARMv6) && (d == n))
981                     return false;
982 
983                 break;
984 
985             case eEncodingT2:
986                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
987                 d = Bits32 (opcode, 11, 8);
988                 n = Bits32 (opcode, 19, 16);
989                 m = Bits32 (opcode, 3, 0);
990                 setflags = false;
991 
992                 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
993                 if (BadReg (d) || BadReg (n) || BadReg (m))
994                     return false;
995 
996                 break;
997 
998             case eEncodingA1:
999                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
1000                 d = Bits32 (opcode, 19, 16);
1001                 n = Bits32 (opcode, 3, 0);
1002                 m = Bits32 (opcode, 11, 8);
1003                 setflags = BitIsSet (opcode, 20);
1004 
1005                 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
1006                 if ((d == 15) ||  (n == 15) || (m == 15))
1007                     return false;
1008 
1009                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
1010                 if ((ArchVersion() < ARMv6) && (d == n))
1011                     return false;
1012 
1013                 break;
1014 
1015             default:
1016                 return false;
1017         }
1018 
1019         bool success = false;
1020 
1021         // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
1022         uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
1023         if (!success)
1024             return false;
1025 
1026         // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
1027         uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
1028         if (!success)
1029             return false;
1030 
1031         // result = operand1 * operand2;
1032         uint64_t result = operand1 * operand2;
1033 
1034         // R[d] = result<31:0>;
1035         RegisterInfo op1_reg;
1036         RegisterInfo op2_reg;
1037         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
1038         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
1039 
1040         EmulateInstruction::Context context;
1041         context.type = eContextArithmetic;
1042         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
1043 
1044         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result)))
1045             return false;
1046 
1047         // if setflags then
1048         if (setflags)
1049         {
1050             // APSR.N = result<31>;
1051             // APSR.Z = IsZeroBit(result);
1052             m_new_inst_cpsr = m_opcode_cpsr;
1053             SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31));
1054             SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1055             if (m_new_inst_cpsr != m_opcode_cpsr)
1056             {
1057                 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1058                     return false;
1059             }
1060 
1061             // if ArchVersion() == 4 then
1062                 // APSR.C = bit UNKNOWN;
1063         }
1064     }
1065     return true;
1066 }
1067 
1068 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register.
1069 // It can optionally update the condition flags based on the value.
1070 bool
1071 EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding)
1072 {
1073 #if 0
1074     // ARM pseudo code...
1075     if (ConditionPassed())
1076     {
1077         EncodingSpecificOperations();
1078         result = NOT(imm32);
1079         if d == 15 then         // Can only occur for ARM encoding
1080             ALUWritePC(result); // setflags is always FALSE here
1081         else
1082             R[d] = result;
1083             if setflags then
1084                 APSR.N = result<31>;
1085                 APSR.Z = IsZeroBit(result);
1086                 APSR.C = carry;
1087                 // APSR.V unchanged
1088     }
1089 #endif
1090 
1091     if (ConditionPassed(opcode))
1092     {
1093         uint32_t Rd; // the destination register
1094         uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1095         uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1096         bool setflags;
1097         switch (encoding) {
1098         case eEncodingT1:
1099             Rd = Bits32(opcode, 11, 8);
1100             setflags = BitIsSet(opcode, 20);
1101             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1102             break;
1103         case eEncodingA1:
1104             Rd = Bits32(opcode, 15, 12);
1105             setflags = BitIsSet(opcode, 20);
1106             imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1107 
1108             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1109             if (Rd == 15 && setflags)
1110                 return EmulateSUBSPcLrEtc (opcode, encoding);
1111             break;
1112         default:
1113             return false;
1114         }
1115         uint32_t result = ~imm32;
1116 
1117         // The context specifies that an immediate is to be moved into Rd.
1118         EmulateInstruction::Context context;
1119         context.type = EmulateInstruction::eContextImmediate;
1120         context.SetNoArgs ();
1121 
1122         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1123             return false;
1124     }
1125     return true;
1126 }
1127 
1128 // Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register.
1129 // It can optionally update the condition flags based on the result.
1130 bool
1131 EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding)
1132 {
1133 #if 0
1134     // ARM pseudo code...
1135     if (ConditionPassed())
1136     {
1137         EncodingSpecificOperations();
1138         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1139         result = NOT(shifted);
1140         if d == 15 then         // Can only occur for ARM encoding
1141             ALUWritePC(result); // setflags is always FALSE here
1142         else
1143             R[d] = result;
1144             if setflags then
1145                 APSR.N = result<31>;
1146                 APSR.Z = IsZeroBit(result);
1147                 APSR.C = carry;
1148                 // APSR.V unchanged
1149     }
1150 #endif
1151 
1152     if (ConditionPassed(opcode))
1153     {
1154         uint32_t Rm; // the source register
1155         uint32_t Rd; // the destination register
1156         ARM_ShifterType shift_t;
1157         uint32_t shift_n; // the shift applied to the value read from Rm
1158         bool setflags;
1159         uint32_t carry; // the carry bit after the shift operation
1160         switch (encoding) {
1161         case eEncodingT1:
1162             Rd = Bits32(opcode, 2, 0);
1163             Rm = Bits32(opcode, 5, 3);
1164             setflags = !InITBlock();
1165             shift_t = SRType_LSL;
1166             shift_n = 0;
1167             if (InITBlock())
1168                 return false;
1169             break;
1170         case eEncodingT2:
1171             Rd = Bits32(opcode, 11, 8);
1172             Rm = Bits32(opcode, 3, 0);
1173             setflags = BitIsSet(opcode, 20);
1174             shift_n = DecodeImmShiftThumb(opcode, shift_t);
1175             // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1176             if (BadReg(Rd) || BadReg(Rm))
1177                 return false;
1178             break;
1179         case eEncodingA1:
1180             Rd = Bits32(opcode, 15, 12);
1181             Rm = Bits32(opcode, 3, 0);
1182             setflags = BitIsSet(opcode, 20);
1183             shift_n = DecodeImmShiftARM(opcode, shift_t);
1184             break;
1185         default:
1186             return false;
1187         }
1188         bool success = false;
1189         uint32_t value = ReadCoreReg(Rm, &success);
1190         if (!success)
1191             return false;
1192 
1193         uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1194         if (!success)
1195             return false;
1196         uint32_t result = ~shifted;
1197 
1198         // The context specifies that an immediate is to be moved into Rd.
1199         EmulateInstruction::Context context;
1200         context.type = EmulateInstruction::eContextImmediate;
1201         context.SetNoArgs ();
1202 
1203         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1204             return false;
1205     }
1206     return true;
1207 }
1208 
1209 // PC relative immediate load into register, possibly followed by ADD (SP plus register).
1210 // LDR (literal)
1211 bool
1212 EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding)
1213 {
1214 #if 0
1215     // ARM pseudo code...
1216     if (ConditionPassed())
1217     {
1218         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1219         base = Align(PC,4);
1220         address = if add then (base + imm32) else (base - imm32);
1221         data = MemU[address,4];
1222         if t == 15 then
1223             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1224         elsif UnalignedSupport() || address<1:0> = '00' then
1225             R[t] = data;
1226         else // Can only apply before ARMv7
1227             if CurrentInstrSet() == InstrSet_ARM then
1228                 R[t] = ROR(data, 8*UInt(address<1:0>));
1229             else
1230                 R[t] = bits(32) UNKNOWN;
1231     }
1232 #endif
1233 
1234     if (ConditionPassed(opcode))
1235     {
1236         bool success = false;
1237         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1238         if (!success)
1239             return false;
1240 
1241         // PC relative immediate load context
1242         EmulateInstruction::Context context;
1243         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1244         RegisterInfo pc_reg;
1245         GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
1246         context.SetRegisterPlusOffset (pc_reg, 0);
1247 
1248         uint32_t Rt;    // the destination register
1249         uint32_t imm32; // immediate offset from the PC
1250         bool add;       // +imm32 or -imm32?
1251         addr_t base;    // the base address
1252         addr_t address; // the PC relative address
1253         uint32_t data;  // the literal data value from the PC relative load
1254         switch (encoding) {
1255         case eEncodingT1:
1256             Rt = Bits32(opcode, 10, 8);
1257             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1258             add = true;
1259             break;
1260         case eEncodingT2:
1261             Rt = Bits32(opcode, 15, 12);
1262             imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1263             add = BitIsSet(opcode, 23);
1264             if (Rt == 15 && InITBlock() && !LastInITBlock())
1265                 return false;
1266             break;
1267         default:
1268             return false;
1269         }
1270 
1271         base = Align(pc, 4);
1272         if (add)
1273             address = base + imm32;
1274         else
1275             address = base - imm32;
1276 
1277         context.SetRegisterPlusOffset(pc_reg, address - base);
1278         data = MemURead(context, address, 4, 0, &success);
1279         if (!success)
1280             return false;
1281 
1282         if (Rt == 15)
1283         {
1284             if (Bits32(address, 1, 0) == 0)
1285             {
1286                 // In ARMv5T and above, this is an interworking branch.
1287                 if (!LoadWritePC(context, data))
1288                     return false;
1289             }
1290             else
1291                 return false;
1292         }
1293         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
1294         {
1295             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
1296                 return false;
1297         }
1298         else // We don't handle ARM for now.
1299             return false;
1300 
1301     }
1302     return true;
1303 }
1304 
1305 // An add operation to adjust the SP.
1306 // ADD (SP plus immediate)
1307 bool
1308 EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding)
1309 {
1310 #if 0
1311     // ARM pseudo code...
1312     if (ConditionPassed())
1313     {
1314         EncodingSpecificOperations();
1315         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1316         if d == 15 then // Can only occur for ARM encoding
1317             ALUWritePC(result); // setflags is always FALSE here
1318         else
1319             R[d] = result;
1320             if setflags then
1321                 APSR.N = result<31>;
1322                 APSR.Z = IsZeroBit(result);
1323                 APSR.C = carry;
1324                 APSR.V = overflow;
1325     }
1326 #endif
1327 
1328     bool success = false;
1329 
1330     if (ConditionPassed(opcode))
1331     {
1332         const addr_t sp = ReadCoreReg (SP_REG, &success);
1333         if (!success)
1334             return false;
1335         uint32_t imm32; // the immediate operand
1336         uint32_t d;
1337         bool setflags;
1338         switch (encoding)
1339         {
1340             case eEncodingT1:
1341                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1342                 d = Bits32 (opcode, 10, 8);
1343                 imm32 = (Bits32 (opcode, 7, 0) << 2);
1344                 setflags = false;
1345                 break;
1346 
1347             case eEncodingT2:
1348                 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1349                 d = 13;
1350                 imm32 = ThumbImm7Scaled (opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1351                 setflags = false;
1352                 break;
1353 
1354             case eEncodingT3:
1355                 // d = UInt(Rd); setflags = (S == "1"); imm32 = ThumbExpandImm(i:imm3:imm8);
1356                 d = Bits32 (opcode, 11, 8);
1357                 imm32 = ThumbExpandImm (opcode);
1358                 setflags = Bit32 (opcode, 20);
1359 
1360                 // if Rd == "1111" && S == "1" then SEE CMN (immediate);
1361                 if (d == 15 && setflags == 1)
1362                     return false; // CMN (immediate) not yet supported
1363 
1364                 // if d == 15 && S == "0" then UNPREDICTABLE;
1365                 if (d == 15 && setflags == 0)
1366                     return false;
1367                 break;
1368 
1369             case eEncodingT4:
1370                 {
1371                     // if Rn == '1111' then SEE ADR;
1372                     // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
1373                     d = Bits32 (opcode, 11, 8);
1374                     setflags = false;
1375                     uint32_t i = Bit32 (opcode, 26);
1376                     uint32_t imm3 = Bits32 (opcode, 14, 12);
1377                     uint32_t imm8 = Bits32 (opcode, 7, 0);
1378                     imm32 = (i << 11) | (imm3 << 8) | imm8;
1379 
1380                     // if d == 15 then UNPREDICTABLE;
1381                     if (d == 15)
1382                         return false;
1383                 }
1384                 break;
1385 
1386             default:
1387                 return false;
1388         }
1389         // (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
1390         AddWithCarryResult res = AddWithCarry (sp, imm32, 0);
1391 
1392         EmulateInstruction::Context context;
1393         if (d == 13)
1394             context.type = EmulateInstruction::eContextAdjustStackPointer;
1395         else
1396             context.type = EmulateInstruction::eContextRegisterPlusOffset;
1397 
1398         RegisterInfo sp_reg;
1399         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1400         context.SetRegisterPlusOffset (sp_reg, res.result - sp);
1401 
1402         if (d == 15)
1403         {
1404             if (!ALUWritePC (context, res.result))
1405                 return false;
1406         }
1407         else
1408         {
1409             // R[d] = result;
1410             // if setflags then
1411             //     APSR.N = result<31>;
1412             //     APSR.Z = IsZeroBit(result);
1413             //     APSR.C = carry;
1414             //     APSR.V = overflow;
1415             if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
1416                 return false;
1417         }
1418     }
1419     return true;
1420 }
1421 
1422 // An add operation to adjust the SP.
1423 // ADD (SP plus register)
1424 bool
1425 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding)
1426 {
1427 #if 0
1428     // ARM pseudo code...
1429     if (ConditionPassed())
1430     {
1431         EncodingSpecificOperations();
1432         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1433         (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1434         if d == 15 then
1435             ALUWritePC(result); // setflags is always FALSE here
1436         else
1437             R[d] = result;
1438             if setflags then
1439                 APSR.N = result<31>;
1440                 APSR.Z = IsZeroBit(result);
1441                 APSR.C = carry;
1442                 APSR.V = overflow;
1443     }
1444 #endif
1445 
1446     bool success = false;
1447 
1448     if (ConditionPassed(opcode))
1449     {
1450         const addr_t sp = ReadCoreReg (SP_REG, &success);
1451         if (!success)
1452             return false;
1453         uint32_t Rm; // the second operand
1454         switch (encoding) {
1455         case eEncodingT2:
1456             Rm = Bits32(opcode, 6, 3);
1457             break;
1458         default:
1459             return false;
1460         }
1461         int32_t reg_value = ReadCoreReg(Rm, &success);
1462         if (!success)
1463             return false;
1464 
1465         addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1466 
1467         EmulateInstruction::Context context;
1468         context.type = eContextArithmetic;
1469         RegisterInfo sp_reg;
1470         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1471 
1472         RegisterInfo other_reg;
1473         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1474         context.SetRegisterRegisterOperands (sp_reg, other_reg);
1475 
1476         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
1477             return false;
1478     }
1479     return true;
1480 }
1481 
1482 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
1483 // at a PC-relative address, and changes instruction set from ARM to Thumb, or
1484 // from Thumb to ARM.
1485 // BLX (immediate)
1486 bool
1487 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding)
1488 {
1489 #if 0
1490     // ARM pseudo code...
1491     if (ConditionPassed())
1492     {
1493         EncodingSpecificOperations();
1494         if CurrentInstrSet() == InstrSet_ARM then
1495             LR = PC - 4;
1496         else
1497             LR = PC<31:1> : '1';
1498         if targetInstrSet == InstrSet_ARM then
1499             targetAddress = Align(PC,4) + imm32;
1500         else
1501             targetAddress = PC + imm32;
1502         SelectInstrSet(targetInstrSet);
1503         BranchWritePC(targetAddress);
1504     }
1505 #endif
1506 
1507     bool success = true;
1508 
1509     if (ConditionPassed(opcode))
1510     {
1511         EmulateInstruction::Context context;
1512         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1513         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1514         if (!success)
1515             return false;
1516         addr_t lr; // next instruction address
1517         addr_t target; // target address
1518         int32_t imm32; // PC-relative offset
1519         switch (encoding) {
1520         case eEncodingT1:
1521             {
1522             lr = pc | 1u; // return address
1523             uint32_t S = Bit32(opcode, 26);
1524             uint32_t imm10 = Bits32(opcode, 25, 16);
1525             uint32_t J1 = Bit32(opcode, 13);
1526             uint32_t J2 = Bit32(opcode, 11);
1527             uint32_t imm11 = Bits32(opcode, 10, 0);
1528             uint32_t I1 = !(J1 ^ S);
1529             uint32_t I2 = !(J2 ^ S);
1530             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1531             imm32 = llvm::SignExtend32<25>(imm25);
1532             target = pc + imm32;
1533             SelectInstrSet (eModeThumb);
1534             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
1535             if (InITBlock() && !LastInITBlock())
1536                 return false;
1537             break;
1538             }
1539         case eEncodingT2:
1540             {
1541             lr = pc | 1u; // return address
1542             uint32_t S = Bit32(opcode, 26);
1543             uint32_t imm10H = Bits32(opcode, 25, 16);
1544             uint32_t J1 = Bit32(opcode, 13);
1545             uint32_t J2 = Bit32(opcode, 11);
1546             uint32_t imm10L = Bits32(opcode, 10, 1);
1547             uint32_t I1 = !(J1 ^ S);
1548             uint32_t I2 = !(J2 ^ S);
1549             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
1550             imm32 = llvm::SignExtend32<25>(imm25);
1551             target = Align(pc, 4) + imm32;
1552             SelectInstrSet (eModeARM);
1553             context.SetISAAndImmediateSigned (eModeARM, 4 + imm32);
1554             if (InITBlock() && !LastInITBlock())
1555                 return false;
1556             break;
1557             }
1558         case eEncodingA1:
1559             lr = pc - 4; // return address
1560             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1561             target = Align(pc, 4) + imm32;
1562             SelectInstrSet (eModeARM);
1563             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
1564             break;
1565         case eEncodingA2:
1566             lr = pc - 4; // return address
1567             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
1568             target = pc + imm32;
1569             SelectInstrSet (eModeThumb);
1570             context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32);
1571             break;
1572         default:
1573             return false;
1574         }
1575         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1576             return false;
1577         if (!BranchWritePC(context, target))
1578             return false;
1579         if (m_opcode_cpsr != m_new_inst_cpsr)
1580             if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1581                 return false;
1582     }
1583     return true;
1584 }
1585 
1586 // Branch with Link and Exchange (register) calls a subroutine at an address and
1587 // instruction set specified by a register.
1588 // BLX (register)
1589 bool
1590 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding)
1591 {
1592 #if 0
1593     // ARM pseudo code...
1594     if (ConditionPassed())
1595     {
1596         EncodingSpecificOperations();
1597         target = R[m];
1598         if CurrentInstrSet() == InstrSet_ARM then
1599             next_instr_addr = PC - 4;
1600             LR = next_instr_addr;
1601         else
1602             next_instr_addr = PC - 2;
1603             LR = next_instr_addr<31:1> : '1';
1604         BXWritePC(target);
1605     }
1606 #endif
1607 
1608     bool success = false;
1609 
1610     if (ConditionPassed(opcode))
1611     {
1612         EmulateInstruction::Context context;
1613         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1614         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1615         addr_t lr; // next instruction address
1616         if (!success)
1617             return false;
1618         uint32_t Rm; // the register with the target address
1619         switch (encoding) {
1620         case eEncodingT1:
1621             lr = (pc - 2) | 1u; // return address
1622             Rm = Bits32(opcode, 6, 3);
1623             // if m == 15 then UNPREDICTABLE;
1624             if (Rm == 15)
1625                 return false;
1626             if (InITBlock() && !LastInITBlock())
1627                 return false;
1628             break;
1629         case eEncodingA1:
1630             lr = pc - 4; // return address
1631             Rm = Bits32(opcode, 3, 0);
1632             // if m == 15 then UNPREDICTABLE;
1633             if (Rm == 15)
1634                 return false;
1635             break;
1636         default:
1637             return false;
1638         }
1639         addr_t target = ReadCoreReg (Rm, &success);
1640         if (!success)
1641             return false;
1642         RegisterInfo dwarf_reg;
1643         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1644         context.SetRegister (dwarf_reg);
1645         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1646             return false;
1647         if (!BXWritePC(context, target))
1648             return false;
1649     }
1650     return true;
1651 }
1652 
1653 // Branch and Exchange causes a branch to an address and instruction set specified by a register.
1654 bool
1655 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding)
1656 {
1657 #if 0
1658     // ARM pseudo code...
1659     if (ConditionPassed())
1660     {
1661         EncodingSpecificOperations();
1662         BXWritePC(R[m]);
1663     }
1664 #endif
1665 
1666     if (ConditionPassed(opcode))
1667     {
1668         EmulateInstruction::Context context;
1669         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1670         uint32_t Rm; // the register with the target address
1671         switch (encoding) {
1672         case eEncodingT1:
1673             Rm = Bits32(opcode, 6, 3);
1674             if (InITBlock() && !LastInITBlock())
1675                 return false;
1676             break;
1677         case eEncodingA1:
1678             Rm = Bits32(opcode, 3, 0);
1679             break;
1680         default:
1681             return false;
1682         }
1683         bool success = false;
1684         addr_t target = ReadCoreReg (Rm, &success);
1685         if (!success)
1686             return false;
1687 
1688         RegisterInfo dwarf_reg;
1689         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1690         context.SetRegister (dwarf_reg);
1691         if (!BXWritePC(context, target))
1692             return false;
1693     }
1694     return true;
1695 }
1696 
1697 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an
1698 // address and instruction set specified by a register as though it were a BX instruction.
1699 //
1700 // TODO: Emulate Jazelle architecture?
1701 //       We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation.
1702 bool
1703 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding)
1704 {
1705 #if 0
1706     // ARM pseudo code...
1707     if (ConditionPassed())
1708     {
1709         EncodingSpecificOperations();
1710         if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
1711             BXWritePC(R[m]);
1712         else
1713             if JazelleAcceptsExecution() then
1714                 SwitchToJazelleExecution();
1715             else
1716                 SUBARCHITECTURE_DEFINED handler call;
1717     }
1718 #endif
1719 
1720     if (ConditionPassed(opcode))
1721     {
1722         EmulateInstruction::Context context;
1723         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1724         uint32_t Rm; // the register with the target address
1725         switch (encoding) {
1726         case eEncodingT1:
1727             Rm = Bits32(opcode, 19, 16);
1728             if (BadReg(Rm))
1729                 return false;
1730             if (InITBlock() && !LastInITBlock())
1731                 return false;
1732             break;
1733         case eEncodingA1:
1734             Rm = Bits32(opcode, 3, 0);
1735             if (Rm == 15)
1736                 return false;
1737             break;
1738         default:
1739             return false;
1740         }
1741         bool success = false;
1742         addr_t target = ReadCoreReg (Rm, &success);
1743         if (!success)
1744             return false;
1745 
1746         RegisterInfo dwarf_reg;
1747         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1748         context.SetRegister (dwarf_reg);
1749         if (!BXWritePC(context, target))
1750             return false;
1751     }
1752     return true;
1753 }
1754 
1755 // Set r7 to point to some ip offset.
1756 // SUB (immediate)
1757 bool
1758 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding)
1759 {
1760 #if 0
1761     // ARM pseudo code...
1762     if (ConditionPassed())
1763     {
1764         EncodingSpecificOperations();
1765         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1766         if d == 15 then // Can only occur for ARM encoding
1767            ALUWritePC(result); // setflags is always FALSE here
1768         else
1769             R[d] = result;
1770             if setflags then
1771                 APSR.N = result<31>;
1772                 APSR.Z = IsZeroBit(result);
1773                 APSR.C = carry;
1774                 APSR.V = overflow;
1775     }
1776 #endif
1777 
1778     if (ConditionPassed(opcode))
1779     {
1780         bool success = false;
1781         const addr_t ip = ReadCoreReg (12, &success);
1782         if (!success)
1783             return false;
1784         uint32_t imm32;
1785         switch (encoding) {
1786         case eEncodingA1:
1787             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1788             break;
1789         default:
1790             return false;
1791         }
1792         addr_t ip_offset = imm32;
1793         addr_t addr = ip - ip_offset; // the adjusted ip value
1794 
1795         EmulateInstruction::Context context;
1796         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1797         RegisterInfo dwarf_reg;
1798         GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg);
1799         context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
1800 
1801         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
1802             return false;
1803     }
1804     return true;
1805 }
1806 
1807 // Set ip to point to some stack offset.
1808 // SUB (SP minus immediate)
1809 bool
1810 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding)
1811 {
1812 #if 0
1813     // ARM pseudo code...
1814     if (ConditionPassed())
1815     {
1816         EncodingSpecificOperations();
1817         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1818         if d == 15 then // Can only occur for ARM encoding
1819            ALUWritePC(result); // setflags is always FALSE here
1820         else
1821             R[d] = result;
1822             if setflags then
1823                 APSR.N = result<31>;
1824                 APSR.Z = IsZeroBit(result);
1825                 APSR.C = carry;
1826                 APSR.V = overflow;
1827     }
1828 #endif
1829 
1830     if (ConditionPassed(opcode))
1831     {
1832         bool success = false;
1833         const addr_t sp = ReadCoreReg (SP_REG, &success);
1834         if (!success)
1835             return false;
1836         uint32_t imm32;
1837         switch (encoding) {
1838         case eEncodingA1:
1839             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1840             break;
1841         default:
1842             return false;
1843         }
1844         addr_t sp_offset = imm32;
1845         addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1846 
1847         EmulateInstruction::Context context;
1848         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1849         RegisterInfo dwarf_reg;
1850         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
1851         context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
1852 
1853         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
1854             return false;
1855     }
1856     return true;
1857 }
1858 
1859 // This instruction subtracts an immediate value from the SP value, and writes
1860 // the result to the destination register.
1861 //
1862 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage.
1863 bool
1864 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding)
1865 {
1866 #if 0
1867     // ARM pseudo code...
1868     if (ConditionPassed())
1869     {
1870         EncodingSpecificOperations();
1871         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1872         if d == 15 then        // Can only occur for ARM encoding
1873            ALUWritePC(result); // setflags is always FALSE here
1874         else
1875             R[d] = result;
1876             if setflags then
1877                 APSR.N = result<31>;
1878                 APSR.Z = IsZeroBit(result);
1879                 APSR.C = carry;
1880                 APSR.V = overflow;
1881     }
1882 #endif
1883 
1884     bool success = false;
1885     if (ConditionPassed(opcode))
1886     {
1887         const addr_t sp = ReadCoreReg (SP_REG, &success);
1888         if (!success)
1889             return false;
1890 
1891         uint32_t Rd;
1892         bool setflags;
1893         uint32_t imm32;
1894         switch (encoding) {
1895         case eEncodingT1:
1896             Rd = 13;
1897             setflags = false;
1898             imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1899             break;
1900         case eEncodingT2:
1901             Rd = Bits32(opcode, 11, 8);
1902             setflags = BitIsSet(opcode, 20);
1903             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1904             if (Rd == 15 && setflags)
1905                 return EmulateCMPImm(opcode, eEncodingT2);
1906             if (Rd == 15 && !setflags)
1907                 return false;
1908             break;
1909         case eEncodingT3:
1910             Rd = Bits32(opcode, 11, 8);
1911             setflags = false;
1912             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
1913             if (Rd == 15)
1914                 return false;
1915             break;
1916         case eEncodingA1:
1917             Rd = Bits32(opcode, 15, 12);
1918             setflags = BitIsSet(opcode, 20);
1919             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1920 
1921             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1922             if (Rd == 15 && setflags)
1923                 return EmulateSUBSPcLrEtc (opcode, encoding);
1924             break;
1925         default:
1926             return false;
1927         }
1928         AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
1929 
1930         EmulateInstruction::Context context;
1931         if (Rd == 13)
1932         {
1933             uint64_t imm64 = imm32;  // Need to expand it to 64 bits before attempting to negate it, or the wrong
1934                                      // value gets passed down to context.SetImmediateSigned.
1935             context.type = EmulateInstruction::eContextAdjustStackPointer;
1936             context.SetImmediateSigned (-imm64); // the stack pointer offset
1937         }
1938         else
1939         {
1940             context.type = EmulateInstruction::eContextImmediate;
1941             context.SetNoArgs ();
1942         }
1943 
1944         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
1945             return false;
1946     }
1947     return true;
1948 }
1949 
1950 // A store operation to the stack that also updates the SP.
1951 bool
1952 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding)
1953 {
1954 #if 0
1955     // ARM pseudo code...
1956     if (ConditionPassed())
1957     {
1958         EncodingSpecificOperations();
1959         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1960         address = if index then offset_addr else R[n];
1961         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1962         if wback then R[n] = offset_addr;
1963     }
1964 #endif
1965 
1966     bool success = false;
1967     if (ConditionPassed(opcode))
1968     {
1969         const uint32_t addr_byte_size = GetAddressByteSize();
1970         const addr_t sp = ReadCoreReg (SP_REG, &success);
1971         if (!success)
1972             return false;
1973         uint32_t Rt; // the source register
1974         uint32_t imm12;
1975         uint32_t Rn;  // This function assumes Rn is the SP, but we should verify that.
1976 
1977         bool index;
1978         bool add;
1979         bool wback;
1980         switch (encoding) {
1981         case eEncodingA1:
1982             Rt = Bits32(opcode, 15, 12);
1983             imm12 = Bits32(opcode, 11, 0);
1984             Rn = Bits32 (opcode, 19, 16);
1985 
1986             if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
1987                 return false;
1988 
1989             index = BitIsSet (opcode, 24);
1990             add = BitIsSet (opcode, 23);
1991             wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
1992 
1993             if (wback && ((Rn == 15) || (Rn == Rt)))
1994                 return false;
1995             break;
1996         default:
1997             return false;
1998         }
1999         addr_t offset_addr;
2000         if (add)
2001             offset_addr = sp + imm12;
2002         else
2003             offset_addr = sp - imm12;
2004 
2005         addr_t addr;
2006         if (index)
2007             addr = offset_addr;
2008         else
2009             addr = sp;
2010 
2011         EmulateInstruction::Context context;
2012         context.type = EmulateInstruction::eContextPushRegisterOnStack;
2013         RegisterInfo sp_reg;
2014         RegisterInfo dwarf_reg;
2015 
2016         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2017         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
2018         context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
2019         if (Rt != 15)
2020         {
2021             uint32_t reg_value = ReadCoreReg(Rt, &success);
2022             if (!success)
2023                 return false;
2024             if (!MemUWrite (context, addr, reg_value, addr_byte_size))
2025                 return false;
2026         }
2027         else
2028         {
2029             const uint32_t pc = ReadCoreReg(PC_REG, &success);
2030             if (!success)
2031                 return false;
2032             if (!MemUWrite (context, addr, pc, addr_byte_size))
2033                 return false;
2034         }
2035 
2036 
2037         if (wback)
2038         {
2039             context.type = EmulateInstruction::eContextAdjustStackPointer;
2040             context.SetImmediateSigned (addr - sp);
2041             if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr))
2042                 return false;
2043         }
2044     }
2045     return true;
2046 }
2047 
2048 // Vector Push stores multiple extension registers to the stack.
2049 // It also updates SP to point to the start of the stored data.
2050 bool
2051 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding)
2052 {
2053 #if 0
2054     // ARM pseudo code...
2055     if (ConditionPassed())
2056     {
2057         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2058         address = SP - imm32;
2059         SP = SP - imm32;
2060         if single_regs then
2061             for r = 0 to regs-1
2062                 MemA[address,4] = S[d+r]; address = address+4;
2063         else
2064             for r = 0 to regs-1
2065                 // Store as two word-aligned words in the correct order for current endianness.
2066                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
2067                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
2068                 address = address+8;
2069     }
2070 #endif
2071 
2072     bool success = false;
2073     if (ConditionPassed(opcode))
2074     {
2075         const uint32_t addr_byte_size = GetAddressByteSize();
2076         const addr_t sp = ReadCoreReg (SP_REG, &success);
2077         if (!success)
2078             return false;
2079         bool single_regs;
2080         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2081         uint32_t imm32; // stack offset
2082         uint32_t regs;  // number of registers
2083         switch (encoding) {
2084         case eEncodingT1:
2085         case eEncodingA1:
2086             single_regs = false;
2087             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2088             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2089             // If UInt(imm8) is odd, see "FSTMX".
2090             regs = Bits32(opcode, 7, 0) / 2;
2091             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2092             if (regs == 0 || regs > 16 || (d + regs) > 32)
2093                 return false;
2094             break;
2095         case eEncodingT2:
2096         case eEncodingA2:
2097             single_regs = true;
2098             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2099             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2100             regs = Bits32(opcode, 7, 0);
2101             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2102             if (regs == 0 || regs > 16 || (d + regs) > 32)
2103                 return false;
2104             break;
2105         default:
2106             return false;
2107         }
2108         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2109         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2110         addr_t sp_offset = imm32;
2111         addr_t addr = sp - sp_offset;
2112         uint32_t i;
2113 
2114         EmulateInstruction::Context context;
2115         context.type = EmulateInstruction::eContextPushRegisterOnStack;
2116 
2117         RegisterInfo dwarf_reg;
2118         RegisterInfo sp_reg;
2119         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2120         for (i=0; i<regs; ++i)
2121         {
2122             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2123             context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
2124             // uint64_t to accommodate 64-bit registers.
2125             uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success);
2126             if (!success)
2127                 return false;
2128             if (!MemAWrite (context, addr, reg_value, reg_byte_size))
2129                 return false;
2130             addr += reg_byte_size;
2131         }
2132 
2133         context.type = EmulateInstruction::eContextAdjustStackPointer;
2134         context.SetImmediateSigned (-sp_offset);
2135 
2136         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2137             return false;
2138     }
2139     return true;
2140 }
2141 
2142 // Vector Pop loads multiple extension registers from the stack.
2143 // It also updates SP to point just above the loaded data.
2144 bool
2145 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding)
2146 {
2147 #if 0
2148     // ARM pseudo code...
2149     if (ConditionPassed())
2150     {
2151         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2152         address = SP;
2153         SP = SP + imm32;
2154         if single_regs then
2155             for r = 0 to regs-1
2156                 S[d+r] = MemA[address,4]; address = address+4;
2157         else
2158             for r = 0 to regs-1
2159                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2160                 // Combine the word-aligned words in the correct order for current endianness.
2161                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2162     }
2163 #endif
2164 
2165     bool success = false;
2166     if (ConditionPassed(opcode))
2167     {
2168         const uint32_t addr_byte_size = GetAddressByteSize();
2169         const addr_t sp = ReadCoreReg (SP_REG, &success);
2170         if (!success)
2171             return false;
2172         bool single_regs;
2173         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2174         uint32_t imm32; // stack offset
2175         uint32_t regs;  // number of registers
2176         switch (encoding) {
2177         case eEncodingT1:
2178         case eEncodingA1:
2179             single_regs = false;
2180             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2181             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2182             // If UInt(imm8) is odd, see "FLDMX".
2183             regs = Bits32(opcode, 7, 0) / 2;
2184             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2185             if (regs == 0 || regs > 16 || (d + regs) > 32)
2186                 return false;
2187             break;
2188         case eEncodingT2:
2189         case eEncodingA2:
2190             single_regs = true;
2191             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2192             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2193             regs = Bits32(opcode, 7, 0);
2194             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2195             if (regs == 0 || regs > 16 || (d + regs) > 32)
2196                 return false;
2197             break;
2198         default:
2199             return false;
2200         }
2201         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2202         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2203         addr_t sp_offset = imm32;
2204         addr_t addr = sp;
2205         uint32_t i;
2206         uint64_t data; // uint64_t to accommodate 64-bit registers.
2207 
2208         EmulateInstruction::Context context;
2209         context.type = EmulateInstruction::eContextPopRegisterOffStack;
2210 
2211         RegisterInfo dwarf_reg;
2212         RegisterInfo sp_reg;
2213         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2214         for (i=0; i<regs; ++i)
2215         {
2216             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2217             context.SetRegisterPlusOffset (sp_reg, addr - sp);
2218             data = MemARead(context, addr, reg_byte_size, 0, &success);
2219             if (!success)
2220                 return false;
2221             if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2222                 return false;
2223             addr += reg_byte_size;
2224         }
2225 
2226         context.type = EmulateInstruction::eContextAdjustStackPointer;
2227         context.SetImmediateSigned (sp_offset);
2228 
2229         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2230             return false;
2231     }
2232     return true;
2233 }
2234 
2235 // SVC (previously SWI)
2236 bool
2237 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding)
2238 {
2239 #if 0
2240     // ARM pseudo code...
2241     if (ConditionPassed())
2242     {
2243         EncodingSpecificOperations();
2244         CallSupervisor();
2245     }
2246 #endif
2247 
2248     bool success = false;
2249 
2250     if (ConditionPassed(opcode))
2251     {
2252         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2253         addr_t lr; // next instruction address
2254         if (!success)
2255             return false;
2256         uint32_t imm32; // the immediate constant
2257         uint32_t mode;  // ARM or Thumb mode
2258         switch (encoding) {
2259         case eEncodingT1:
2260             lr = (pc + 2) | 1u; // return address
2261             imm32 = Bits32(opcode, 7, 0);
2262             mode = eModeThumb;
2263             break;
2264         case eEncodingA1:
2265             lr = pc + 4; // return address
2266             imm32 = Bits32(opcode, 23, 0);
2267             mode = eModeARM;
2268             break;
2269         default:
2270             return false;
2271         }
2272 
2273         EmulateInstruction::Context context;
2274         context.type = EmulateInstruction::eContextSupervisorCall;
2275         context.SetISAAndImmediate (mode, imm32);
2276         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
2277             return false;
2278     }
2279     return true;
2280 }
2281 
2282 // If Then makes up to four following instructions (the IT block) conditional.
2283 bool
2284 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding)
2285 {
2286 #if 0
2287     // ARM pseudo code...
2288     EncodingSpecificOperations();
2289     ITSTATE.IT<7:0> = firstcond:mask;
2290 #endif
2291 
2292     m_it_session.InitIT(Bits32(opcode, 7, 0));
2293     return true;
2294 }
2295 
2296 bool
2297 EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding)
2298 {
2299     // NOP, nothing to do...
2300     return true;
2301 }
2302 
2303 // Branch causes a branch to a target address.
2304 bool
2305 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding)
2306 {
2307 #if 0
2308     // ARM pseudo code...
2309     if (ConditionPassed())
2310     {
2311         EncodingSpecificOperations();
2312         BranchWritePC(PC + imm32);
2313     }
2314 #endif
2315 
2316     bool success = false;
2317 
2318     if (ConditionPassed(opcode))
2319     {
2320         EmulateInstruction::Context context;
2321         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2322         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2323         if (!success)
2324             return false;
2325         addr_t target; // target address
2326         int32_t imm32; // PC-relative offset
2327         switch (encoding) {
2328         case eEncodingT1:
2329             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2330             imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2331             target = pc + imm32;
2332             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2333             break;
2334         case eEncodingT2:
2335             imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0) << 1);
2336             target = pc + imm32;
2337             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2338             break;
2339         case eEncodingT3:
2340             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2341             {
2342             if (Bits32(opcode, 25, 23) == 7)
2343                 return false; // See Branches and miscellaneous control on page A6-235.
2344 
2345             uint32_t S = Bit32(opcode, 26);
2346             uint32_t imm6 = Bits32(opcode, 21, 16);
2347             uint32_t J1 = Bit32(opcode, 13);
2348             uint32_t J2 = Bit32(opcode, 11);
2349             uint32_t imm11 = Bits32(opcode, 10, 0);
2350             uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2351             imm32 = llvm::SignExtend32<21>(imm21);
2352             target = pc + imm32;
2353             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2354             break;
2355             }
2356         case eEncodingT4:
2357             {
2358             uint32_t S = Bit32(opcode, 26);
2359             uint32_t imm10 = Bits32(opcode, 25, 16);
2360             uint32_t J1 = Bit32(opcode, 13);
2361             uint32_t J2 = Bit32(opcode, 11);
2362             uint32_t imm11 = Bits32(opcode, 10, 0);
2363             uint32_t I1 = !(J1 ^ S);
2364             uint32_t I2 = !(J2 ^ S);
2365             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2366             imm32 = llvm::SignExtend32<25>(imm25);
2367             target = pc + imm32;
2368             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2369             break;
2370             }
2371         case eEncodingA1:
2372             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2373             target = pc + imm32;
2374             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
2375             break;
2376         default:
2377             return false;
2378         }
2379         if (!BranchWritePC(context, target))
2380             return false;
2381     }
2382     return true;
2383 }
2384 
2385 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
2386 // zero and conditionally branch forward a constant value.  They do not affect the condition flags.
2387 // CBNZ, CBZ
2388 bool
2389 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding)
2390 {
2391 #if 0
2392     // ARM pseudo code...
2393     EncodingSpecificOperations();
2394     if nonzero ^ IsZero(R[n]) then
2395         BranchWritePC(PC + imm32);
2396 #endif
2397 
2398     bool success = false;
2399 
2400     // Read the register value from the operand register Rn.
2401     uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2402     if (!success)
2403         return false;
2404 
2405     EmulateInstruction::Context context;
2406     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2407     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2408     if (!success)
2409         return false;
2410 
2411     addr_t target;  // target address
2412     uint32_t imm32; // PC-relative offset to branch forward
2413     bool nonzero;
2414     switch (encoding) {
2415     case eEncodingT1:
2416         imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2417         nonzero = BitIsSet(opcode, 11);
2418         target = pc + imm32;
2419         context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2420         break;
2421     default:
2422         return false;
2423     }
2424     if (m_ignore_conditions || (nonzero ^ (reg_val == 0)))
2425         if (!BranchWritePC(context, target))
2426             return false;
2427 
2428     return true;
2429 }
2430 
2431 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
2432 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2433 // The branch length is twice the value of the byte returned from the table.
2434 //
2435 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
2436 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2437 // The branch length is twice the value of the halfword returned from the table.
2438 // TBB, TBH
2439 bool
2440 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding)
2441 {
2442 #if 0
2443     // ARM pseudo code...
2444     EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2445     if is_tbh then
2446         halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2447     else
2448         halfwords = UInt(MemU[R[n]+R[m], 1]);
2449     BranchWritePC(PC + 2*halfwords);
2450 #endif
2451 
2452     bool success = false;
2453 
2454     if (ConditionPassed(opcode))
2455     {
2456         uint32_t Rn;     // the base register which contains the address of the table of branch lengths
2457         uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
2458         bool is_tbh;     // true if table branch halfword
2459         switch (encoding) {
2460         case eEncodingT1:
2461             Rn = Bits32(opcode, 19, 16);
2462             Rm = Bits32(opcode, 3, 0);
2463             is_tbh = BitIsSet(opcode, 4);
2464             if (Rn == 13 || BadReg(Rm))
2465                 return false;
2466             if (InITBlock() && !LastInITBlock())
2467                 return false;
2468             break;
2469         default:
2470             return false;
2471         }
2472 
2473         // Read the address of the table from the operand register Rn.
2474         // The PC can be used, in which case the table immediately follows this instruction.
2475         uint32_t base = ReadCoreReg(Rn, &success);
2476         if (!success)
2477             return false;
2478 
2479         // the table index
2480         uint32_t index = ReadCoreReg(Rm, &success);
2481         if (!success)
2482             return false;
2483 
2484         // the offsetted table address
2485         addr_t addr = base + (is_tbh ? index*2 : index);
2486 
2487         // PC-relative offset to branch forward
2488         EmulateInstruction::Context context;
2489         context.type = EmulateInstruction::eContextTableBranchReadMemory;
2490         uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2491         if (!success)
2492             return false;
2493 
2494         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2495         if (!success)
2496             return false;
2497 
2498         // target address
2499         addr_t target = pc + offset;
2500         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2501         context.SetISAAndImmediateSigned (eModeThumb, 4 + offset);
2502 
2503         if (!BranchWritePC(context, target))
2504             return false;
2505     }
2506 
2507     return true;
2508 }
2509 
2510 // This instruction adds an immediate value to a register value, and writes the result to the destination register.
2511 // It can optionally update the condition flags based on the result.
2512 bool
2513 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding)
2514 {
2515 #if 0
2516     if ConditionPassed() then
2517         EncodingSpecificOperations();
2518         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2519         R[d] = result;
2520         if setflags then
2521             APSR.N = result<31>;
2522             APSR.Z = IsZeroBit(result);
2523             APSR.C = carry;
2524             APSR.V = overflow;
2525 #endif
2526 
2527     bool success = false;
2528 
2529     if (ConditionPassed(opcode))
2530     {
2531         uint32_t d;
2532         uint32_t n;
2533         bool setflags;
2534         uint32_t imm32;
2535         uint32_t carry_out;
2536 
2537         //EncodingSpecificOperations();
2538         switch (encoding)
2539         {
2540             case eEncodingT1:
2541                 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32);
2542                 d = Bits32 (opcode, 2, 0);
2543                 n = Bits32 (opcode, 5, 3);
2544                 setflags = !InITBlock();
2545                 imm32 = Bits32 (opcode, 8,6);
2546 
2547                 break;
2548 
2549             case eEncodingT2:
2550                 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32);
2551                 d = Bits32 (opcode, 10, 8);
2552                 n = Bits32 (opcode, 10, 8);
2553                 setflags = !InITBlock();
2554                 imm32 = Bits32 (opcode, 7, 0);
2555 
2556                 break;
2557 
2558             case eEncodingT3:
2559                 // if Rd == '1111' && S == '1' then SEE CMN (immediate);
2560                 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8);
2561                 d = Bits32 (opcode, 11, 8);
2562                 n = Bits32 (opcode, 19, 16);
2563                 setflags = BitIsSet (opcode, 20);
2564                 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out);
2565 
2566                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2567                 if (n == 13)
2568                     return EmulateADDSPImm(opcode, eEncodingT3);
2569 
2570                 // if BadReg(d) || n == 15 then UNPREDICTABLE;
2571                 if (BadReg (d) || (n == 15))
2572                     return false;
2573 
2574                 break;
2575 
2576             case eEncodingT4:
2577             {
2578                 // if Rn == '1111' then SEE ADR;
2579                 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
2580                 d = Bits32 (opcode, 11, 8);
2581                 n = Bits32 (opcode, 19, 16);
2582                 setflags = false;
2583                 uint32_t i = Bit32 (opcode, 26);
2584                 uint32_t imm3 = Bits32 (opcode, 14, 12);
2585                 uint32_t imm8 = Bits32 (opcode, 7, 0);
2586                 imm32 = (i << 11) | (imm3 << 8) | imm8;
2587 
2588                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2589                 if (n == 13)
2590                     return EmulateADDSPImm(opcode, eEncodingT4);
2591 
2592                 // if BadReg(d) then UNPREDICTABLE;
2593                 if (BadReg (d))
2594                     return false;
2595 
2596                 break;
2597             }
2598 
2599             default:
2600                 return false;
2601         }
2602 
2603         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2604         if (!success)
2605             return false;
2606 
2607         //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2608         AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
2609 
2610         RegisterInfo reg_n;
2611         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
2612 
2613         EmulateInstruction::Context context;
2614         context.type = eContextArithmetic;
2615         context.SetRegisterPlusOffset (reg_n, imm32);
2616 
2617         //R[d] = result;
2618         //if setflags then
2619             //APSR.N = result<31>;
2620             //APSR.Z = IsZeroBit(result);
2621             //APSR.C = carry;
2622             //APSR.V = overflow;
2623         if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
2624             return false;
2625 
2626     }
2627     return true;
2628 }
2629 
2630 // This instruction adds an immediate value to a register value, and writes the result to the destination
2631 // register.  It can optionally update the condition flags based on the result.
2632 bool
2633 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding)
2634 {
2635 #if 0
2636     // ARM pseudo code...
2637     if ConditionPassed() then
2638         EncodingSpecificOperations();
2639         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2640         if d == 15 then
2641             ALUWritePC(result); // setflags is always FALSE here
2642         else
2643             R[d] = result;
2644             if setflags then
2645                 APSR.N = result<31>;
2646                 APSR.Z = IsZeroBit(result);
2647                 APSR.C = carry;
2648                 APSR.V = overflow;
2649 #endif
2650 
2651     bool success = false;
2652 
2653     if (ConditionPassed(opcode))
2654     {
2655         uint32_t Rd, Rn;
2656         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
2657         bool setflags;
2658         switch (encoding)
2659         {
2660         case eEncodingA1:
2661             Rd = Bits32(opcode, 15, 12);
2662             Rn = Bits32(opcode, 19, 16);
2663             setflags = BitIsSet(opcode, 20);
2664             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2665             break;
2666         default:
2667             return false;
2668         }
2669 
2670         // Read the first operand.
2671         uint32_t val1 = ReadCoreReg(Rn, &success);
2672         if (!success)
2673             return false;
2674 
2675         AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
2676 
2677         EmulateInstruction::Context context;
2678         if (Rd == 13)
2679             context.type = EmulateInstruction::eContextAdjustStackPointer;
2680         else if (Rd == GetFramePointerRegisterNumber())
2681             context.type = EmulateInstruction::eContextSetFramePointer;
2682         else
2683             context.type = EmulateInstruction::eContextRegisterPlusOffset;
2684 
2685         RegisterInfo dwarf_reg;
2686         GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
2687         context.SetRegisterPlusOffset (dwarf_reg, imm32);
2688 
2689         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2690             return false;
2691     }
2692     return true;
2693 }
2694 
2695 // This instruction adds a register value and an optionally-shifted register value, and writes the result
2696 // to the destination register. It can optionally update the condition flags based on the result.
2697 bool
2698 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding)
2699 {
2700 #if 0
2701     // ARM pseudo code...
2702     if ConditionPassed() then
2703         EncodingSpecificOperations();
2704         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2705         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2706         if d == 15 then
2707             ALUWritePC(result); // setflags is always FALSE here
2708         else
2709             R[d] = result;
2710             if setflags then
2711                 APSR.N = result<31>;
2712                 APSR.Z = IsZeroBit(result);
2713                 APSR.C = carry;
2714                 APSR.V = overflow;
2715 #endif
2716 
2717     bool success = false;
2718 
2719     if (ConditionPassed(opcode))
2720     {
2721         uint32_t Rd, Rn, Rm;
2722         ARM_ShifterType shift_t;
2723         uint32_t shift_n; // the shift applied to the value read from Rm
2724         bool setflags;
2725         switch (encoding)
2726         {
2727         case eEncodingT1:
2728             Rd = Bits32(opcode, 2, 0);
2729             Rn = Bits32(opcode, 5, 3);
2730             Rm = Bits32(opcode, 8, 6);
2731             setflags = !InITBlock();
2732             shift_t = SRType_LSL;
2733             shift_n = 0;
2734             break;
2735         case eEncodingT2:
2736             Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2737             Rm = Bits32(opcode, 6, 3);
2738             setflags = false;
2739             shift_t = SRType_LSL;
2740             shift_n = 0;
2741             if (Rn == 15 && Rm == 15)
2742                 return false;
2743             if (Rd == 15 && InITBlock() && !LastInITBlock())
2744                 return false;
2745             break;
2746         case eEncodingA1:
2747             Rd = Bits32(opcode, 15, 12);
2748             Rn = Bits32(opcode, 19, 16);
2749             Rm = Bits32(opcode, 3, 0);
2750             setflags = BitIsSet(opcode, 20);
2751             shift_n = DecodeImmShiftARM(opcode, shift_t);
2752             break;
2753         default:
2754             return false;
2755         }
2756 
2757         // Read the first operand.
2758         uint32_t val1 = ReadCoreReg(Rn, &success);
2759         if (!success)
2760             return false;
2761 
2762         // Read the second operand.
2763         uint32_t val2 = ReadCoreReg(Rm, &success);
2764         if (!success)
2765             return false;
2766 
2767         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2768         if (!success)
2769             return false;
2770         AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2771 
2772         EmulateInstruction::Context context;
2773         context.type = eContextArithmetic;
2774         RegisterInfo op1_reg;
2775         RegisterInfo op2_reg;
2776         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
2777         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
2778         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
2779 
2780         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2781             return false;
2782     }
2783     return true;
2784 }
2785 
2786 // Compare Negative (immediate) adds a register value and an immediate value.
2787 // It updates the condition flags based on the result, and discards the result.
2788 bool
2789 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding)
2790 {
2791 #if 0
2792     // ARM pseudo code...
2793     if ConditionPassed() then
2794         EncodingSpecificOperations();
2795         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2796         APSR.N = result<31>;
2797         APSR.Z = IsZeroBit(result);
2798         APSR.C = carry;
2799         APSR.V = overflow;
2800 #endif
2801 
2802     bool success = false;
2803 
2804     uint32_t Rn; // the first operand
2805     uint32_t imm32; // the immediate value to be compared with
2806     switch (encoding) {
2807     case eEncodingT1:
2808         Rn = Bits32(opcode, 19, 16);
2809         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2810         if (Rn == 15)
2811             return false;
2812         break;
2813     case eEncodingA1:
2814         Rn = Bits32(opcode, 19, 16);
2815         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2816         break;
2817     default:
2818         return false;
2819     }
2820     // Read the register value from the operand register Rn.
2821     uint32_t reg_val = ReadCoreReg(Rn, &success);
2822     if (!success)
2823         return false;
2824 
2825     AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
2826 
2827     EmulateInstruction::Context context;
2828     context.type = EmulateInstruction::eContextImmediate;
2829     context.SetNoArgs ();
2830     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2831         return false;
2832 
2833     return true;
2834 }
2835 
2836 // Compare Negative (register) adds a register value and an optionally-shifted register value.
2837 // It updates the condition flags based on the result, and discards the result.
2838 bool
2839 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding)
2840 {
2841 #if 0
2842     // ARM pseudo code...
2843     if ConditionPassed() then
2844         EncodingSpecificOperations();
2845         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2846         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2847         APSR.N = result<31>;
2848         APSR.Z = IsZeroBit(result);
2849         APSR.C = carry;
2850         APSR.V = overflow;
2851 #endif
2852 
2853     bool success = false;
2854 
2855     uint32_t Rn; // the first operand
2856     uint32_t Rm; // the second operand
2857     ARM_ShifterType shift_t;
2858     uint32_t shift_n; // the shift applied to the value read from Rm
2859     switch (encoding) {
2860     case eEncodingT1:
2861         Rn = Bits32(opcode, 2, 0);
2862         Rm = Bits32(opcode, 5, 3);
2863         shift_t = SRType_LSL;
2864         shift_n = 0;
2865         break;
2866     case eEncodingT2:
2867         Rn = Bits32(opcode, 19, 16);
2868         Rm = Bits32(opcode, 3, 0);
2869         shift_n = DecodeImmShiftThumb(opcode, shift_t);
2870         // if n == 15 || BadReg(m) then UNPREDICTABLE;
2871         if (Rn == 15 || BadReg(Rm))
2872             return false;
2873         break;
2874     case eEncodingA1:
2875         Rn = Bits32(opcode, 19, 16);
2876         Rm = Bits32(opcode, 3, 0);
2877         shift_n = DecodeImmShiftARM(opcode, shift_t);
2878         break;
2879     default:
2880         return false;
2881     }
2882     // Read the register value from register Rn.
2883     uint32_t val1 = ReadCoreReg(Rn, &success);
2884     if (!success)
2885         return false;
2886 
2887     // Read the register value from register Rm.
2888     uint32_t val2 = ReadCoreReg(Rm, &success);
2889     if (!success)
2890         return false;
2891 
2892     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2893     if (!success)
2894         return false;
2895     AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2896 
2897     EmulateInstruction::Context context;
2898     context.type = EmulateInstruction::eContextImmediate;
2899     context.SetNoArgs();
2900     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2901         return false;
2902 
2903     return true;
2904 }
2905 
2906 // Compare (immediate) subtracts an immediate value from a register value.
2907 // It updates the condition flags based on the result, and discards the result.
2908 bool
2909 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding)
2910 {
2911 #if 0
2912     // ARM pseudo code...
2913     if ConditionPassed() then
2914         EncodingSpecificOperations();
2915         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2916         APSR.N = result<31>;
2917         APSR.Z = IsZeroBit(result);
2918         APSR.C = carry;
2919         APSR.V = overflow;
2920 #endif
2921 
2922     bool success = false;
2923 
2924     uint32_t Rn; // the first operand
2925     uint32_t imm32; // the immediate value to be compared with
2926     switch (encoding) {
2927     case eEncodingT1:
2928         Rn = Bits32(opcode, 10, 8);
2929         imm32 = Bits32(opcode, 7, 0);
2930         break;
2931     case eEncodingT2:
2932         Rn = Bits32(opcode, 19, 16);
2933         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2934         if (Rn == 15)
2935             return false;
2936         break;
2937     case eEncodingA1:
2938         Rn = Bits32(opcode, 19, 16);
2939         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2940         break;
2941     default:
2942         return false;
2943     }
2944     // Read the register value from the operand register Rn.
2945     uint32_t reg_val = ReadCoreReg(Rn, &success);
2946     if (!success)
2947         return false;
2948 
2949     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
2950 
2951     EmulateInstruction::Context context;
2952     context.type = EmulateInstruction::eContextImmediate;
2953     context.SetNoArgs ();
2954     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2955         return false;
2956 
2957     return true;
2958 }
2959 
2960 // Compare (register) subtracts an optionally-shifted register value from a register value.
2961 // It updates the condition flags based on the result, and discards the result.
2962 bool
2963 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding)
2964 {
2965 #if 0
2966     // ARM pseudo code...
2967     if ConditionPassed() then
2968         EncodingSpecificOperations();
2969         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2970         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2971         APSR.N = result<31>;
2972         APSR.Z = IsZeroBit(result);
2973         APSR.C = carry;
2974         APSR.V = overflow;
2975 #endif
2976 
2977     bool success = false;
2978 
2979     uint32_t Rn; // the first operand
2980     uint32_t Rm; // the second operand
2981     ARM_ShifterType shift_t;
2982     uint32_t shift_n; // the shift applied to the value read from Rm
2983     switch (encoding) {
2984     case eEncodingT1:
2985         Rn = Bits32(opcode, 2, 0);
2986         Rm = Bits32(opcode, 5, 3);
2987         shift_t = SRType_LSL;
2988         shift_n = 0;
2989         break;
2990     case eEncodingT2:
2991         Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2992         Rm = Bits32(opcode, 6, 3);
2993         shift_t = SRType_LSL;
2994         shift_n = 0;
2995         if (Rn < 8 && Rm < 8)
2996             return false;
2997         if (Rn == 15 || Rm == 15)
2998             return false;
2999         break;
3000     case eEncodingT3:
3001         Rn = Bits32(opcode, 19, 16);
3002         Rm = Bits32(opcode, 3, 0);
3003         shift_n = DecodeImmShiftThumb(opcode, shift_t);
3004         if (Rn == 15 || BadReg(Rm))
3005             return false;
3006         break;
3007     case eEncodingA1:
3008         Rn = Bits32(opcode, 19, 16);
3009         Rm = Bits32(opcode, 3, 0);
3010         shift_n = DecodeImmShiftARM(opcode, shift_t);
3011         break;
3012     default:
3013         return false;
3014     }
3015     // Read the register value from register Rn.
3016     uint32_t val1 = ReadCoreReg(Rn, &success);
3017     if (!success)
3018         return false;
3019 
3020     // Read the register value from register Rm.
3021     uint32_t val2 = ReadCoreReg(Rm, &success);
3022     if (!success)
3023         return false;
3024 
3025     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
3026     if (!success)
3027         return false;
3028     AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
3029 
3030     EmulateInstruction::Context context;
3031     context.type = EmulateInstruction::eContextImmediate;
3032     context.SetNoArgs();
3033     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
3034         return false;
3035 
3036     return true;
3037 }
3038 
3039 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
3040 // shifting in copies of its sign bit, and writes the result to the destination register.  It can
3041 // optionally update the condition flags based on the result.
3042 bool
3043 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding)
3044 {
3045 #if 0
3046     // ARM pseudo code...
3047     if ConditionPassed() then
3048         EncodingSpecificOperations();
3049         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3050         if d == 15 then         // Can only occur for ARM encoding
3051             ALUWritePC(result); // setflags is always FALSE here
3052         else
3053             R[d] = result;
3054             if setflags then
3055                 APSR.N = result<31>;
3056                 APSR.Z = IsZeroBit(result);
3057                 APSR.C = carry;
3058                 // APSR.V unchanged
3059 #endif
3060 
3061     return EmulateShiftImm (opcode, encoding, SRType_ASR);
3062 }
3063 
3064 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
3065 // shifting in copies of its sign bit, and writes the result to the destination register.
3066 // The variable number of bits is read from the bottom byte of a register. It can optionally update
3067 // the condition flags based on the result.
3068 bool
3069 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding)
3070 {
3071 #if 0
3072     // ARM pseudo code...
3073     if ConditionPassed() then
3074         EncodingSpecificOperations();
3075         shift_n = UInt(R[m]<7:0>);
3076         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
3077         R[d] = result;
3078         if setflags then
3079             APSR.N = result<31>;
3080             APSR.Z = IsZeroBit(result);
3081             APSR.C = carry;
3082             // APSR.V unchanged
3083 #endif
3084 
3085     return EmulateShiftReg (opcode, encoding, SRType_ASR);
3086 }
3087 
3088 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
3089 // shifting in zeros, and writes the result to the destination register.  It can optionally
3090 // update the condition flags based on the result.
3091 bool
3092 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding)
3093 {
3094 #if 0
3095     // ARM pseudo code...
3096     if ConditionPassed() then
3097         EncodingSpecificOperations();
3098         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3099         if d == 15 then         // Can only occur for ARM encoding
3100             ALUWritePC(result); // setflags is always FALSE here
3101         else
3102             R[d] = result;
3103             if setflags then
3104                 APSR.N = result<31>;
3105                 APSR.Z = IsZeroBit(result);
3106                 APSR.C = carry;
3107                 // APSR.V unchanged
3108 #endif
3109 
3110     return EmulateShiftImm (opcode, encoding, SRType_LSL);
3111 }
3112 
3113 // Logical Shift Left (register) shifts a register value left by a variable number of bits,
3114 // shifting in zeros, and writes the result to the destination register.  The variable number
3115 // of bits is read from the bottom byte of a register. It can optionally update the condition
3116 // flags based on the result.
3117 bool
3118 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding)
3119 {
3120 #if 0
3121     // ARM pseudo code...
3122     if ConditionPassed() then
3123         EncodingSpecificOperations();
3124         shift_n = UInt(R[m]<7:0>);
3125         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3126         R[d] = result;
3127         if setflags then
3128             APSR.N = result<31>;
3129             APSR.Z = IsZeroBit(result);
3130             APSR.C = carry;
3131             // APSR.V unchanged
3132 #endif
3133 
3134     return EmulateShiftReg (opcode, encoding, SRType_LSL);
3135 }
3136 
3137 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
3138 // shifting in zeros, and writes the result to the destination register.  It can optionally
3139 // update the condition flags based on the result.
3140 bool
3141 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding)
3142 {
3143 #if 0
3144     // ARM pseudo code...
3145     if ConditionPassed() then
3146         EncodingSpecificOperations();
3147         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3148         if d == 15 then         // Can only occur for ARM encoding
3149             ALUWritePC(result); // setflags is always FALSE here
3150         else
3151             R[d] = result;
3152             if setflags then
3153                 APSR.N = result<31>;
3154                 APSR.Z = IsZeroBit(result);
3155                 APSR.C = carry;
3156                 // APSR.V unchanged
3157 #endif
3158 
3159     return EmulateShiftImm (opcode, encoding, SRType_LSR);
3160 }
3161 
3162 // Logical Shift Right (register) shifts a register value right by a variable number of bits,
3163 // shifting in zeros, and writes the result to the destination register.  The variable number
3164 // of bits is read from the bottom byte of a register. It can optionally update the condition
3165 // flags based on the result.
3166 bool
3167 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding)
3168 {
3169 #if 0
3170     // ARM pseudo code...
3171     if ConditionPassed() then
3172         EncodingSpecificOperations();
3173         shift_n = UInt(R[m]<7:0>);
3174         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3175         R[d] = result;
3176         if setflags then
3177             APSR.N = result<31>;
3178             APSR.Z = IsZeroBit(result);
3179             APSR.C = carry;
3180             // APSR.V unchanged
3181 #endif
3182 
3183     return EmulateShiftReg (opcode, encoding, SRType_LSR);
3184 }
3185 
3186 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
3187 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3188 // It can optionally update the condition flags based on the result.
3189 bool
3190 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding)
3191 {
3192 #if 0
3193     // ARM pseudo code...
3194     if ConditionPassed() then
3195         EncodingSpecificOperations();
3196         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3197         if d == 15 then         // Can only occur for ARM encoding
3198             ALUWritePC(result); // setflags is always FALSE here
3199         else
3200             R[d] = result;
3201             if setflags then
3202                 APSR.N = result<31>;
3203                 APSR.Z = IsZeroBit(result);
3204                 APSR.C = carry;
3205                 // APSR.V unchanged
3206 #endif
3207 
3208     return EmulateShiftImm (opcode, encoding, SRType_ROR);
3209 }
3210 
3211 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
3212 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3213 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
3214 // flags based on the result.
3215 bool
3216 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding)
3217 {
3218 #if 0
3219     // ARM pseudo code...
3220     if ConditionPassed() then
3221         EncodingSpecificOperations();
3222         shift_n = UInt(R[m]<7:0>);
3223         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3224         R[d] = result;
3225         if setflags then
3226             APSR.N = result<31>;
3227             APSR.Z = IsZeroBit(result);
3228             APSR.C = carry;
3229             // APSR.V unchanged
3230 #endif
3231 
3232     return EmulateShiftReg (opcode, encoding, SRType_ROR);
3233 }
3234 
3235 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
3236 // with the carry flag shifted into bit [31].
3237 //
3238 // RRX can optionally update the condition flags based on the result.
3239 // In that case, bit [0] is shifted into the carry flag.
3240 bool
3241 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding)
3242 {
3243 #if 0
3244     // ARM pseudo code...
3245     if ConditionPassed() then
3246         EncodingSpecificOperations();
3247         (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3248         if d == 15 then         // Can only occur for ARM encoding
3249             ALUWritePC(result); // setflags is always FALSE here
3250         else
3251             R[d] = result;
3252             if setflags then
3253                 APSR.N = result<31>;
3254                 APSR.Z = IsZeroBit(result);
3255                 APSR.C = carry;
3256                 // APSR.V unchanged
3257 #endif
3258 
3259     return EmulateShiftImm (opcode, encoding, SRType_RRX);
3260 }
3261 
3262 bool
3263 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3264 {
3265 //    assert(shift_type == SRType_ASR
3266 //           || shift_type == SRType_LSL
3267 //           || shift_type == SRType_LSR
3268 //           || shift_type == SRType_ROR
3269 //           || shift_type == SRType_RRX);
3270 
3271     bool success = false;
3272 
3273     if (ConditionPassed(opcode))
3274     {
3275         uint32_t Rd;    // the destination register
3276         uint32_t Rm;    // the first operand register
3277         uint32_t imm5;  // encoding for the shift amount
3278         uint32_t carry; // the carry bit after the shift operation
3279         bool setflags;
3280 
3281         // Special case handling!
3282         // A8.6.139 ROR (immediate) -- Encoding T1
3283         ARMEncoding use_encoding = encoding;
3284         if (shift_type == SRType_ROR && use_encoding == eEncodingT1)
3285         {
3286             // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
3287             // have the same decoding of bit fields as the other Thumb2 shift operations.
3288             use_encoding = eEncodingT2;
3289         }
3290 
3291         switch (use_encoding) {
3292         case eEncodingT1:
3293             // Due to the above special case handling!
3294             if (shift_type == SRType_ROR)
3295                 return false;
3296 
3297             Rd = Bits32(opcode, 2, 0);
3298             Rm = Bits32(opcode, 5, 3);
3299             setflags = !InITBlock();
3300             imm5 = Bits32(opcode, 10, 6);
3301             break;
3302         case eEncodingT2:
3303             // A8.6.141 RRX
3304             // There's no imm form of RRX instructions.
3305             if (shift_type == SRType_RRX)
3306                 return false;
3307 
3308             Rd = Bits32(opcode, 11, 8);
3309             Rm = Bits32(opcode, 3, 0);
3310             setflags = BitIsSet(opcode, 20);
3311             imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3312             if (BadReg(Rd) || BadReg(Rm))
3313                 return false;
3314             break;
3315         case eEncodingA1:
3316             Rd = Bits32(opcode, 15, 12);
3317             Rm = Bits32(opcode, 3, 0);
3318             setflags = BitIsSet(opcode, 20);
3319             imm5 = Bits32(opcode, 11, 7);
3320             break;
3321         default:
3322             return false;
3323         }
3324 
3325         // A8.6.139 ROR (immediate)
3326         if (shift_type == SRType_ROR && imm5 == 0)
3327             shift_type = SRType_RRX;
3328 
3329         // Get the first operand.
3330         uint32_t value = ReadCoreReg (Rm, &success);
3331         if (!success)
3332             return false;
3333 
3334         // Decode the shift amount if not RRX.
3335         uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3336 
3337         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3338         if (!success)
3339             return false;
3340 
3341         // The context specifies that an immediate is to be moved into Rd.
3342         EmulateInstruction::Context context;
3343         context.type = EmulateInstruction::eContextImmediate;
3344         context.SetNoArgs ();
3345 
3346         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3347             return false;
3348     }
3349     return true;
3350 }
3351 
3352 bool
3353 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3354 {
3355     // assert(shift_type == SRType_ASR
3356     //        || shift_type == SRType_LSL
3357     //        || shift_type == SRType_LSR
3358     //        || shift_type == SRType_ROR);
3359 
3360     bool success = false;
3361 
3362     if (ConditionPassed(opcode))
3363     {
3364         uint32_t Rd;    // the destination register
3365         uint32_t Rn;    // the first operand register
3366         uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
3367         uint32_t carry; // the carry bit after the shift operation
3368         bool setflags;
3369         switch (encoding) {
3370         case eEncodingT1:
3371             Rd = Bits32(opcode, 2, 0);
3372             Rn = Rd;
3373             Rm = Bits32(opcode, 5, 3);
3374             setflags = !InITBlock();
3375             break;
3376         case eEncodingT2:
3377             Rd = Bits32(opcode, 11, 8);
3378             Rn = Bits32(opcode, 19, 16);
3379             Rm = Bits32(opcode, 3, 0);
3380             setflags = BitIsSet(opcode, 20);
3381             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3382                 return false;
3383             break;
3384         case eEncodingA1:
3385             Rd = Bits32(opcode, 15, 12);
3386             Rn = Bits32(opcode, 3, 0);
3387             Rm = Bits32(opcode, 11, 8);
3388             setflags = BitIsSet(opcode, 20);
3389             if (Rd == 15 || Rn == 15 || Rm == 15)
3390                 return false;
3391             break;
3392         default:
3393             return false;
3394         }
3395 
3396         // Get the first operand.
3397         uint32_t value = ReadCoreReg (Rn, &success);
3398         if (!success)
3399             return false;
3400         // Get the Rm register content.
3401         uint32_t val = ReadCoreReg (Rm, &success);
3402         if (!success)
3403             return false;
3404 
3405         // Get the shift amount.
3406         uint32_t amt = Bits32(val, 7, 0);
3407 
3408         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3409         if (!success)
3410             return false;
3411 
3412         // The context specifies that an immediate is to be moved into Rd.
3413         EmulateInstruction::Context context;
3414         context.type = EmulateInstruction::eContextImmediate;
3415         context.SetNoArgs ();
3416 
3417         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3418             return false;
3419     }
3420     return true;
3421 }
3422 
3423 // LDM loads multiple registers from consecutive memory locations, using an
3424 // address from a base register.  Optionally the address just above the highest of those locations
3425 // can be written back to the base register.
3426 bool
3427 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding)
3428 {
3429 #if 0
3430     // ARM pseudo code...
3431     if ConditionPassed()
3432         EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3433         address = R[n];
3434 
3435         for i = 0 to 14
3436             if registers<i> == '1' then
3437                 R[i] = MemA[address, 4]; address = address + 4;
3438         if registers<15> == '1' then
3439             LoadWritePC (MemA[address, 4]);
3440 
3441         if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3442         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3443 
3444 #endif
3445 
3446     bool success = false;
3447     if (ConditionPassed(opcode))
3448     {
3449         uint32_t n;
3450         uint32_t registers = 0;
3451         bool wback;
3452         const uint32_t addr_byte_size = GetAddressByteSize();
3453         switch (encoding)
3454         {
3455             case eEncodingT1:
3456                 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0');
3457                 n = Bits32 (opcode, 10, 8);
3458                 registers = Bits32 (opcode, 7, 0);
3459                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3460                 wback = BitIsClear (registers, n);
3461                 // if BitCount(registers) < 1 then UNPREDICTABLE;
3462                 if (BitCount(registers) < 1)
3463                     return false;
3464                 break;
3465             case eEncodingT2:
3466                 // if W == '1' && Rn == '1101' then SEE POP;
3467                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3468                 n = Bits32 (opcode, 19, 16);
3469                 registers = Bits32 (opcode, 15, 0);
3470                 registers = registers & 0xdfff; // Make sure bit 13 is zero.
3471                 wback = BitIsSet (opcode, 21);
3472 
3473                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3474                 if ((n == 15)
3475                     || (BitCount (registers) < 2)
3476                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3477                     return false;
3478 
3479                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3480                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3481                     return false;
3482 
3483                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3484                 if (wback
3485                     && BitIsSet (registers, n))
3486                     return false;
3487                 break;
3488 
3489             case eEncodingA1:
3490                 n = Bits32 (opcode, 19, 16);
3491                 registers = Bits32 (opcode, 15, 0);
3492                 wback = BitIsSet (opcode, 21);
3493                 if ((n == 15)
3494                     || (BitCount (registers) < 1))
3495                     return false;
3496                 break;
3497             default:
3498                 return false;
3499         }
3500 
3501         int32_t offset = 0;
3502         const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3503         if (!success)
3504             return false;
3505 
3506         EmulateInstruction::Context context;
3507         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3508         RegisterInfo dwarf_reg;
3509         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3510         context.SetRegisterPlusOffset (dwarf_reg, offset);
3511 
3512         for (int i = 0; i < 14; ++i)
3513         {
3514             if (BitIsSet (registers, i))
3515             {
3516                 context.type = EmulateInstruction::eContextRegisterPlusOffset;
3517                 context.SetRegisterPlusOffset (dwarf_reg, offset);
3518                 if (wback && (n == 13)) // Pop Instruction
3519                     context.type = EmulateInstruction::eContextPopRegisterOffStack;
3520 
3521                 // R[i] = MemA [address, 4]; address = address + 4;
3522                 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3523                 if (!success)
3524                     return false;
3525 
3526                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3527                     return false;
3528 
3529                 offset += addr_byte_size;
3530             }
3531         }
3532 
3533         if (BitIsSet (registers, 15))
3534         {
3535             //LoadWritePC (MemA [address, 4]);
3536             context.type = EmulateInstruction::eContextRegisterPlusOffset;
3537             context.SetRegisterPlusOffset (dwarf_reg, offset);
3538             uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3539             if (!success)
3540                 return false;
3541             // In ARMv5T and above, this is an interworking branch.
3542             if (!LoadWritePC(context, data))
3543                 return false;
3544         }
3545 
3546         if (wback && BitIsClear (registers, n))
3547         {
3548             // R[n] = R[n] + 4 * BitCount (registers)
3549             int32_t offset = addr_byte_size * BitCount (registers);
3550             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3551             context.SetRegisterPlusOffset (dwarf_reg, offset);
3552 
3553             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
3554                 return false;
3555         }
3556         if (wback && BitIsSet (registers, n))
3557             // R[n] bits(32) UNKNOWN;
3558             return WriteBits32Unknown (n);
3559     }
3560     return true;
3561 }
3562 
3563 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register.
3564 // The consecutive memory locations end at this address and the address just below the lowest of those locations
3565 // can optionally be written back to the base register.
3566 bool
3567 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding)
3568 {
3569 #if 0
3570     // ARM pseudo code...
3571     if ConditionPassed() then
3572         EncodingSpecificOperations();
3573         address = R[n] - 4*BitCount(registers) + 4;
3574 
3575         for i = 0 to 14
3576             if registers<i> == '1' then
3577                   R[i] = MemA[address,4]; address = address + 4;
3578 
3579         if registers<15> == '1' then
3580             LoadWritePC(MemA[address,4]);
3581 
3582         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3583         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3584 #endif
3585 
3586     bool success = false;
3587 
3588     if (ConditionPassed(opcode))
3589     {
3590         uint32_t n;
3591         uint32_t registers = 0;
3592         bool wback;
3593         const uint32_t addr_byte_size = GetAddressByteSize();
3594 
3595         // EncodingSpecificOperations();
3596         switch (encoding)
3597         {
3598             case eEncodingA1:
3599                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3600                 n = Bits32 (opcode, 19, 16);
3601                 registers = Bits32 (opcode, 15, 0);
3602                 wback = BitIsSet (opcode, 21);
3603 
3604                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3605                 if ((n == 15) || (BitCount (registers) < 1))
3606                     return false;
3607 
3608                 break;
3609 
3610             default:
3611                 return false;
3612         }
3613         // address = R[n] - 4*BitCount(registers) + 4;
3614 
3615         int32_t offset = 0;
3616         addr_t Rn = ReadCoreReg (n, &success);
3617 
3618         if (!success)
3619             return false;
3620 
3621         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size;
3622 
3623         EmulateInstruction::Context context;
3624         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3625         RegisterInfo dwarf_reg;
3626         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3627         context.SetRegisterPlusOffset (dwarf_reg, offset);
3628 
3629         // for i = 0 to 14
3630         for (int i = 0; i < 14; ++i)
3631         {
3632             // if registers<i> == '1' then
3633             if (BitIsSet (registers, i))
3634             {
3635                   // R[i] = MemA[address,4]; address = address + 4;
3636                   context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3637                   uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3638                   if (!success)
3639                       return false;
3640                   if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3641                       return false;
3642                   offset += addr_byte_size;
3643             }
3644         }
3645 
3646         // if registers<15> == '1' then
3647         //     LoadWritePC(MemA[address,4]);
3648         if (BitIsSet (registers, 15))
3649         {
3650             context.SetRegisterPlusOffset (dwarf_reg, offset);
3651             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3652             if (!success)
3653                 return false;
3654             // In ARMv5T and above, this is an interworking branch.
3655             if (!LoadWritePC(context, data))
3656                 return false;
3657         }
3658 
3659         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3660         if (wback && BitIsClear (registers, n))
3661         {
3662             if (!success)
3663                 return false;
3664 
3665             offset = (addr_byte_size * BitCount (registers)) * -1;
3666             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3667             context.SetImmediateSigned (offset);
3668             addr_t addr = Rn + offset;
3669             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3670                 return false;
3671         }
3672 
3673         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3674         if (wback && BitIsSet (registers, n))
3675             return WriteBits32Unknown (n);
3676     }
3677     return true;
3678 }
3679 
3680 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
3681 // consecutive memory locations end just below this address, and the address of the lowest of those locations can
3682 // be optionally written back to the base register.
3683 bool
3684 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding)
3685 {
3686 #if 0
3687     // ARM pseudo code...
3688     if ConditionPassed() then
3689         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3690         address = R[n] - 4*BitCount(registers);
3691 
3692         for i = 0 to 14
3693             if registers<i> == '1' then
3694                   R[i] = MemA[address,4]; address = address + 4;
3695         if registers<15> == '1' then
3696                   LoadWritePC(MemA[address,4]);
3697 
3698         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3699         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3700 #endif
3701 
3702     bool success = false;
3703 
3704     if (ConditionPassed(opcode))
3705     {
3706         uint32_t n;
3707         uint32_t registers = 0;
3708         bool wback;
3709         const uint32_t addr_byte_size = GetAddressByteSize();
3710         switch (encoding)
3711         {
3712             case eEncodingT1:
3713                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3714                 n = Bits32 (opcode, 19, 16);
3715                 registers = Bits32 (opcode, 15, 0);
3716                 registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
3717                 wback = BitIsSet (opcode, 21);
3718 
3719                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3720                 if ((n == 15)
3721                     || (BitCount (registers) < 2)
3722                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3723                     return false;
3724 
3725                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3726                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3727                     return false;
3728 
3729                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3730                 if (wback && BitIsSet (registers, n))
3731                     return false;
3732 
3733                 break;
3734 
3735             case eEncodingA1:
3736                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3737                 n = Bits32 (opcode, 19, 16);
3738                 registers = Bits32 (opcode, 15, 0);
3739                 wback = BitIsSet (opcode, 21);
3740 
3741                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3742                 if ((n == 15) || (BitCount (registers) < 1))
3743                     return false;
3744 
3745                 break;
3746 
3747             default:
3748                 return false;
3749         }
3750 
3751         // address = R[n] - 4*BitCount(registers);
3752 
3753         int32_t offset = 0;
3754         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3755 
3756         if (!success)
3757             return false;
3758 
3759         addr_t address = Rn - (addr_byte_size * BitCount (registers));
3760         EmulateInstruction::Context context;
3761         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3762         RegisterInfo dwarf_reg;
3763         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3764         context.SetRegisterPlusOffset (dwarf_reg, Rn - address);
3765 
3766         for (int i = 0; i < 14; ++i)
3767         {
3768             if (BitIsSet (registers, i))
3769             {
3770                 // R[i] = MemA[address,4]; address = address + 4;
3771                 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3772                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3773                 if (!success)
3774                     return false;
3775 
3776                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3777                     return false;
3778 
3779                 offset += addr_byte_size;
3780             }
3781         }
3782 
3783         // if registers<15> == '1' then
3784         //     LoadWritePC(MemA[address,4]);
3785         if (BitIsSet (registers, 15))
3786         {
3787             context.SetRegisterPlusOffset (dwarf_reg, offset);
3788             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3789             if (!success)
3790                 return false;
3791             // In ARMv5T and above, this is an interworking branch.
3792             if (!LoadWritePC(context, data))
3793                 return false;
3794         }
3795 
3796         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3797         if (wback && BitIsClear (registers, n))
3798         {
3799             if (!success)
3800                 return false;
3801 
3802             offset = (addr_byte_size * BitCount (registers)) * -1;
3803             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3804             context.SetImmediateSigned (offset);
3805             addr_t addr = Rn + offset;
3806             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3807                 return false;
3808         }
3809 
3810         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3811         if (wback && BitIsSet (registers, n))
3812             return WriteBits32Unknown (n);
3813     }
3814     return true;
3815 }
3816 
3817 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
3818 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can
3819 // optinoally be written back to the base register.
3820 bool
3821 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding)
3822 {
3823 #if 0
3824     if ConditionPassed() then
3825         EncodingSpecificOperations();
3826         address = R[n] + 4;
3827 
3828         for i = 0 to 14
3829             if registers<i> == '1' then
3830                   R[i] = MemA[address,4]; address = address + 4;
3831         if registers<15> == '1' then
3832             LoadWritePC(MemA[address,4]);
3833 
3834         if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3835         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3836 #endif
3837 
3838     bool success = false;
3839 
3840     if (ConditionPassed(opcode))
3841     {
3842         uint32_t n;
3843         uint32_t registers = 0;
3844         bool wback;
3845         const uint32_t addr_byte_size = GetAddressByteSize();
3846         switch (encoding)
3847         {
3848             case eEncodingA1:
3849                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3850                 n = Bits32 (opcode, 19, 16);
3851                 registers = Bits32 (opcode, 15, 0);
3852                 wback = BitIsSet (opcode, 21);
3853 
3854                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3855                 if ((n == 15) || (BitCount (registers) < 1))
3856                     return false;
3857 
3858                 break;
3859             default:
3860                 return false;
3861         }
3862         // address = R[n] + 4;
3863 
3864         int32_t offset = 0;
3865         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3866 
3867         if (!success)
3868             return false;
3869 
3870         addr_t address = Rn + addr_byte_size;
3871 
3872         EmulateInstruction::Context context;
3873         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3874         RegisterInfo dwarf_reg;
3875         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3876         context.SetRegisterPlusOffset (dwarf_reg, offset);
3877 
3878         for (int i = 0; i < 14; ++i)
3879         {
3880             if (BitIsSet (registers, i))
3881             {
3882                 // R[i] = MemA[address,4]; address = address + 4;
3883 
3884                 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size);
3885                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3886                 if (!success)
3887                     return false;
3888 
3889                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3890                     return false;
3891 
3892                 offset += addr_byte_size;
3893             }
3894         }
3895 
3896         // if registers<15> == '1' then
3897         //     LoadWritePC(MemA[address,4]);
3898         if (BitIsSet (registers, 15))
3899         {
3900             context.SetRegisterPlusOffset (dwarf_reg, offset);
3901             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3902             if (!success)
3903                 return false;
3904             // In ARMv5T and above, this is an interworking branch.
3905             if (!LoadWritePC(context, data))
3906                 return false;
3907         }
3908 
3909         // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3910         if (wback && BitIsClear (registers, n))
3911         {
3912             if (!success)
3913                 return false;
3914 
3915             offset = addr_byte_size * BitCount (registers);
3916             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3917             context.SetImmediateSigned (offset);
3918             addr_t addr = Rn + offset;
3919             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3920                 return false;
3921         }
3922 
3923         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3924         if (wback && BitIsSet (registers, n))
3925             return WriteBits32Unknown (n);
3926     }
3927     return true;
3928 }
3929 
3930 // Load Register (immediate) calculates an address from a base register value and
3931 // an immediate offset, loads a word from memory, and writes to a register.
3932 // LDR (immediate, Thumb)
3933 bool
3934 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding)
3935 {
3936 #if 0
3937     // ARM pseudo code...
3938     if (ConditionPassed())
3939     {
3940         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3941         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3942         address = if index then offset_addr else R[n];
3943         data = MemU[address,4];
3944         if wback then R[n] = offset_addr;
3945         if t == 15 then
3946             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3947         elsif UnalignedSupport() || address<1:0> = '00' then
3948             R[t] = data;
3949         else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3950     }
3951 #endif
3952 
3953     bool success = false;
3954 
3955     if (ConditionPassed(opcode))
3956     {
3957         uint32_t Rt; // the destination register
3958         uint32_t Rn; // the base register
3959         uint32_t imm32; // the immediate offset used to form the address
3960         addr_t offset_addr; // the offset address
3961         addr_t address; // the calculated address
3962         uint32_t data; // the literal data value from memory load
3963         bool add, index, wback;
3964         switch (encoding) {
3965             case eEncodingT1:
3966                 Rt = Bits32(opcode, 2, 0);
3967                 Rn = Bits32(opcode, 5, 3);
3968                 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3969                 // index = TRUE; add = TRUE; wback = FALSE
3970                 add = true;
3971                 index = true;
3972                 wback = false;
3973 
3974                 break;
3975 
3976             case eEncodingT2:
3977                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
3978                 Rt = Bits32 (opcode, 10, 8);
3979                 Rn = 13;
3980                 imm32 = Bits32 (opcode, 7, 0) << 2;
3981 
3982                 // index = TRUE; add = TRUE; wback = FALSE;
3983                 index = true;
3984                 add = true;
3985                 wback = false;
3986 
3987                 break;
3988 
3989             case eEncodingT3:
3990                 // if Rn == '1111' then SEE LDR (literal);
3991                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
3992                 Rt = Bits32 (opcode, 15, 12);
3993                 Rn = Bits32 (opcode, 19, 16);
3994                 imm32 = Bits32 (opcode, 11, 0);
3995 
3996                 // index = TRUE; add = TRUE; wback = FALSE;
3997                 index = true;
3998                 add = true;
3999                 wback = false;
4000 
4001                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
4002                 if ((Rt == 15) && InITBlock() && !LastInITBlock())
4003                     return false;
4004 
4005                 break;
4006 
4007             case eEncodingT4:
4008                 // if Rn == '1111' then SEE LDR (literal);
4009                 // if P == '1' && U == '1' && W == '0' then SEE LDRT;
4010                 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
4011                 // if P == '0' && W == '0' then UNDEFINED;
4012                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
4013                     return false;
4014 
4015                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4016                 Rt = Bits32 (opcode, 15, 12);
4017                 Rn = Bits32 (opcode, 19, 16);
4018                 imm32 = Bits32 (opcode, 7, 0);
4019 
4020                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4021                 index = BitIsSet (opcode, 10);
4022                 add = BitIsSet (opcode, 9);
4023                 wback = BitIsSet (opcode, 8);
4024 
4025                 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
4026                 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock()))
4027                     return false;
4028 
4029                 break;
4030 
4031             default:
4032                 return false;
4033         }
4034         uint32_t base = ReadCoreReg (Rn, &success);
4035         if (!success)
4036             return false;
4037         if (add)
4038             offset_addr = base + imm32;
4039         else
4040             offset_addr = base - imm32;
4041 
4042         address = (index ? offset_addr : base);
4043 
4044         RegisterInfo base_reg;
4045         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
4046         if (wback)
4047         {
4048             EmulateInstruction::Context ctx;
4049             if (Rn == 13)
4050             {
4051                 ctx.type = eContextAdjustStackPointer;
4052                 ctx.SetImmediateSigned((int32_t) (offset_addr - base));
4053             }
4054             else if (Rn == GetFramePointerRegisterNumber())
4055             {
4056                 ctx.type = eContextSetFramePointer;
4057                 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
4058             }
4059             else
4060             {
4061                 ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
4062                 ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
4063             }
4064 
4065 
4066             if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
4067                 return false;
4068         }
4069 
4070         // Prepare to write to the Rt register.
4071         EmulateInstruction::Context context;
4072         context.type = EmulateInstruction::eContextRegisterLoad;
4073         context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
4074 
4075         // Read memory from the address.
4076         data = MemURead(context, address, 4, 0, &success);
4077         if (!success)
4078             return false;
4079 
4080         if (Rt == 15)
4081         {
4082             if (Bits32(address, 1, 0) == 0)
4083             {
4084                 if (!LoadWritePC(context, data))
4085                     return false;
4086             }
4087             else
4088                 return false;
4089         }
4090         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
4091         {
4092             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
4093                 return false;
4094         }
4095         else
4096             WriteBits32Unknown (Rt);
4097     }
4098     return true;
4099 }
4100 
4101 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
4102 // from a base register.  The consecutive memory locations start at this address, and the address just above the last
4103 // of those locations can optionally be written back to the base register.
4104 bool
4105 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding)
4106 {
4107 #if 0
4108     if ConditionPassed() then
4109         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4110         address = R[n];
4111 
4112         for i = 0 to 14
4113             if registers<i> == '1' then
4114                 if i == n && wback && i != LowestSetBit(registers) then
4115                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4116                 else
4117                     MemA[address,4] = R[i];
4118                 address = address + 4;
4119 
4120         if registers<15> == '1' then // Only possible for encoding A1
4121             MemA[address,4] = PCStoreValue();
4122         if wback then R[n] = R[n] + 4*BitCount(registers);
4123 #endif
4124 
4125     bool success = false;
4126 
4127     if (ConditionPassed(opcode))
4128     {
4129         uint32_t n;
4130         uint32_t registers = 0;
4131         bool wback;
4132         const uint32_t addr_byte_size = GetAddressByteSize();
4133 
4134         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4135         switch (encoding)
4136         {
4137             case eEncodingT1:
4138                 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4139                 n = Bits32 (opcode, 10, 8);
4140                 registers = Bits32 (opcode, 7, 0);
4141                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
4142                 wback = true;
4143 
4144                 // if BitCount(registers) < 1 then UNPREDICTABLE;
4145                 if (BitCount (registers) < 1)
4146                     return false;
4147 
4148                 break;
4149 
4150             case eEncodingT2:
4151                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4152                 n = Bits32 (opcode, 19, 16);
4153                 registers = Bits32 (opcode, 15, 0);
4154                 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4155                 wback = BitIsSet (opcode, 21);
4156 
4157                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4158                 if ((n == 15) || (BitCount (registers) < 2))
4159                     return false;
4160 
4161                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4162                 if (wback && BitIsSet (registers, n))
4163                     return false;
4164 
4165                 break;
4166 
4167             case eEncodingA1:
4168                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4169                 n = Bits32 (opcode, 19, 16);
4170                 registers = Bits32 (opcode, 15, 0);
4171                 wback = BitIsSet (opcode, 21);
4172 
4173                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4174                 if ((n == 15) || (BitCount (registers) < 1))
4175                     return false;
4176 
4177                 break;
4178 
4179             default:
4180                 return false;
4181         }
4182 
4183         // address = R[n];
4184         int32_t offset = 0;
4185         const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4186         if (!success)
4187             return false;
4188 
4189         EmulateInstruction::Context context;
4190         context.type = EmulateInstruction::eContextRegisterStore;
4191         RegisterInfo base_reg;
4192         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4193 
4194         // for i = 0 to 14
4195         uint32_t lowest_set_bit = 14;
4196         for (uint32_t i = 0; i < 14; ++i)
4197         {
4198             // if registers<i> == '1' then
4199             if (BitIsSet (registers, i))
4200             {
4201                   if (i < lowest_set_bit)
4202                       lowest_set_bit = i;
4203                   // if i == n && wback && i != LowestSetBit(registers) then
4204                   if ((i == n) && wback && (i != lowest_set_bit))
4205                       // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4206                       WriteBits32UnknownToMemory (address + offset);
4207                   else
4208                   {
4209                      // MemA[address,4] = R[i];
4210                       uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4211                       if (!success)
4212                           return false;
4213 
4214                       RegisterInfo data_reg;
4215                       GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4216                       context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4217                       if (!MemAWrite (context, address + offset, data, addr_byte_size))
4218                           return false;
4219                   }
4220 
4221                   // address = address + 4;
4222                   offset += addr_byte_size;
4223             }
4224         }
4225 
4226         // if registers<15> == '1' then // Only possible for encoding A1
4227         //     MemA[address,4] = PCStoreValue();
4228         if (BitIsSet (registers, 15))
4229         {
4230             RegisterInfo pc_reg;
4231             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4232             context.SetRegisterPlusOffset (pc_reg, 8);
4233             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4234             if (!success)
4235                 return false;
4236 
4237             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4238                 return false;
4239         }
4240 
4241         // if wback then R[n] = R[n] + 4*BitCount(registers);
4242         if (wback)
4243         {
4244             offset = addr_byte_size * BitCount (registers);
4245             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4246             context.SetImmediateSigned (offset);
4247             addr_t data = address + offset;
4248             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4249                 return false;
4250         }
4251     }
4252     return true;
4253 }
4254 
4255 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
4256 // from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
4257 // of those locations can optionally be written back to the base register.
4258 bool
4259 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding)
4260 {
4261 #if 0
4262     if ConditionPassed() then
4263         EncodingSpecificOperations();
4264         address = R[n] - 4*BitCount(registers) + 4;
4265 
4266         for i = 0 to 14
4267             if registers<i> == '1' then
4268                 if i == n && wback && i != LowestSetBit(registers) then
4269                     MemA[address,4] = bits(32) UNKNOWN;
4270                 else
4271                     MemA[address,4] = R[i];
4272                 address = address + 4;
4273 
4274         if registers<15> == '1' then
4275             MemA[address,4] = PCStoreValue();
4276 
4277         if wback then R[n] = R[n] - 4*BitCount(registers);
4278 #endif
4279 
4280     bool success = false;
4281 
4282     if (ConditionPassed(opcode))
4283     {
4284         uint32_t n;
4285         uint32_t registers = 0;
4286         bool wback;
4287         const uint32_t addr_byte_size = GetAddressByteSize();
4288 
4289         // EncodingSpecificOperations();
4290         switch (encoding)
4291         {
4292             case eEncodingA1:
4293                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4294                 n = Bits32 (opcode, 19, 16);
4295                 registers = Bits32 (opcode, 15, 0);
4296                 wback = BitIsSet (opcode, 21);
4297 
4298                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4299                 if ((n == 15) || (BitCount (registers) < 1))
4300                     return false;
4301                 break;
4302             default:
4303                 return false;
4304         }
4305 
4306         // address = R[n] - 4*BitCount(registers) + 4;
4307         int32_t offset = 0;
4308         addr_t Rn = ReadCoreReg (n, &success);
4309         if (!success)
4310             return false;
4311 
4312         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4;
4313 
4314         EmulateInstruction::Context context;
4315         context.type = EmulateInstruction::eContextRegisterStore;
4316         RegisterInfo base_reg;
4317         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4318 
4319         // for i = 0 to 14
4320         uint32_t lowest_bit_set = 14;
4321         for (uint32_t i = 0; i < 14; ++i)
4322         {
4323             // if registers<i> == '1' then
4324             if (BitIsSet (registers, i))
4325             {
4326                 if (i < lowest_bit_set)
4327                     lowest_bit_set = i;
4328                 //if i == n && wback && i != LowestSetBit(registers) then
4329                 if ((i == n) && wback && (i != lowest_bit_set))
4330                     // MemA[address,4] = bits(32) UNKNOWN;
4331                     WriteBits32UnknownToMemory (address + offset);
4332                 else
4333                 {
4334                     // MemA[address,4] = R[i];
4335                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4336                     if (!success)
4337                         return false;
4338 
4339                     RegisterInfo data_reg;
4340                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4341                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4342                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4343                         return false;
4344                 }
4345 
4346                 // address = address + 4;
4347                 offset += addr_byte_size;
4348             }
4349         }
4350 
4351         // if registers<15> == '1' then
4352         //    MemA[address,4] = PCStoreValue();
4353         if (BitIsSet (registers, 15))
4354         {
4355             RegisterInfo pc_reg;
4356             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4357             context.SetRegisterPlusOffset (pc_reg, 8);
4358             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4359             if (!success)
4360                 return false;
4361 
4362             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4363                 return false;
4364         }
4365 
4366         // if wback then R[n] = R[n] - 4*BitCount(registers);
4367         if (wback)
4368         {
4369             offset = (addr_byte_size * BitCount (registers)) * -1;
4370             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4371             context.SetImmediateSigned (offset);
4372             addr_t data = Rn + offset;
4373             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4374                 return false;
4375         }
4376     }
4377     return true;
4378 }
4379 
4380 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
4381 // from a base register.  The consecutive memory locations end just below this address, and the address of the first of
4382 // those locations can optionally be written back to the base register.
4383 bool
4384 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding)
4385 {
4386 #if 0
4387     if ConditionPassed() then
4388         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4389         address = R[n] - 4*BitCount(registers);
4390 
4391         for i = 0 to 14
4392             if registers<i> == '1' then
4393                 if i == n && wback && i != LowestSetBit(registers) then
4394                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4395                 else
4396                     MemA[address,4] = R[i];
4397                 address = address + 4;
4398 
4399         if registers<15> == '1' then // Only possible for encoding A1
4400             MemA[address,4] = PCStoreValue();
4401 
4402         if wback then R[n] = R[n] - 4*BitCount(registers);
4403 #endif
4404 
4405 
4406     bool success = false;
4407 
4408     if (ConditionPassed(opcode))
4409     {
4410         uint32_t n;
4411         uint32_t registers = 0;
4412         bool wback;
4413         const uint32_t addr_byte_size = GetAddressByteSize();
4414 
4415         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4416         switch (encoding)
4417         {
4418             case eEncodingT1:
4419                 // if W == '1' && Rn == '1101' then SEE PUSH;
4420                 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
4421                 {
4422                     // See PUSH
4423                 }
4424                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4425                 n = Bits32 (opcode, 19, 16);
4426                 registers = Bits32 (opcode, 15, 0);
4427                 registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
4428                 wback = BitIsSet (opcode, 21);
4429                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4430                 if ((n == 15) || BitCount (registers) < 2)
4431                     return false;
4432                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4433                 if (wback && BitIsSet (registers, n))
4434                     return false;
4435                 break;
4436 
4437             case eEncodingA1:
4438                 // if W == '1' && Rn == '1101' && BitCount(register_list) >= 2 then SEE PUSH;
4439                 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
4440                 {
4441                     // See Push
4442                 }
4443                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4444                 n = Bits32 (opcode, 19, 16);
4445                 registers = Bits32 (opcode, 15, 0);
4446                 wback = BitIsSet (opcode, 21);
4447                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4448                 if ((n == 15) || BitCount (registers) < 1)
4449                     return false;
4450                 break;
4451 
4452             default:
4453                 return false;
4454         }
4455 
4456         // address = R[n] - 4*BitCount(registers);
4457 
4458         int32_t offset = 0;
4459         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4460         if (!success)
4461         return false;
4462 
4463         addr_t address = Rn - (addr_byte_size * BitCount (registers));
4464 
4465         EmulateInstruction::Context context;
4466         context.type = EmulateInstruction::eContextRegisterStore;
4467         RegisterInfo base_reg;
4468         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4469 
4470         // for i = 0 to 14
4471         uint32_t lowest_set_bit = 14;
4472         for (uint32_t i = 0; i < 14; ++i)
4473         {
4474             // if registers<i> == '1' then
4475             if (BitIsSet (registers, i))
4476             {
4477                 if (i < lowest_set_bit)
4478                     lowest_set_bit = i;
4479                 // if i == n && wback && i != LowestSetBit(registers) then
4480                 if ((i == n) && wback && (i != lowest_set_bit))
4481                     // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4482                     WriteBits32UnknownToMemory (address + offset);
4483                 else
4484                 {
4485                     // MemA[address,4] = R[i];
4486                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4487                     if (!success)
4488                         return false;
4489 
4490                     RegisterInfo data_reg;
4491                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4492                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4493                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4494                         return false;
4495                 }
4496 
4497                 // address = address + 4;
4498                 offset += addr_byte_size;
4499             }
4500         }
4501 
4502         // if registers<15> == '1' then // Only possible for encoding A1
4503         //     MemA[address,4] = PCStoreValue();
4504         if (BitIsSet (registers, 15))
4505         {
4506             RegisterInfo pc_reg;
4507             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4508             context.SetRegisterPlusOffset (pc_reg, 8);
4509             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4510             if (!success)
4511                 return false;
4512 
4513             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4514                 return false;
4515         }
4516 
4517         // if wback then R[n] = R[n] - 4*BitCount(registers);
4518         if (wback)
4519         {
4520             offset = (addr_byte_size * BitCount (registers)) * -1;
4521             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4522             context.SetImmediateSigned (offset);
4523             addr_t data = Rn + offset;
4524             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4525                 return false;
4526         }
4527     }
4528     return true;
4529 }
4530 
4531 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
4532 // from a base register.  The consecutive memory locations start just above this address, and the address of the last
4533 // of those locations can optionally be written back to the base register.
4534 bool
4535 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding)
4536 {
4537 #if 0
4538     if ConditionPassed() then
4539         EncodingSpecificOperations();
4540         address = R[n] + 4;
4541 
4542         for i = 0 to 14
4543             if registers<i> == '1' then
4544                 if i == n && wback && i != LowestSetBit(registers) then
4545                     MemA[address,4] = bits(32) UNKNOWN;
4546                 else
4547                     MemA[address,4] = R[i];
4548                 address = address + 4;
4549 
4550         if registers<15> == '1' then
4551             MemA[address,4] = PCStoreValue();
4552 
4553         if wback then R[n] = R[n] + 4*BitCount(registers);
4554 #endif
4555 
4556     bool success = false;
4557 
4558     if (ConditionPassed(opcode))
4559     {
4560         uint32_t n;
4561         uint32_t registers = 0;
4562         bool wback;
4563         const uint32_t addr_byte_size = GetAddressByteSize();
4564 
4565         // EncodingSpecificOperations();
4566         switch (encoding)
4567         {
4568             case eEncodingA1:
4569                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4570                 n = Bits32 (opcode, 19, 16);
4571                 registers = Bits32 (opcode, 15, 0);
4572                 wback = BitIsSet (opcode, 21);
4573 
4574                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4575                 if ((n == 15) && (BitCount (registers) < 1))
4576                     return false;
4577                 break;
4578             default:
4579                 return false;
4580         }
4581         // address = R[n] + 4;
4582 
4583         int32_t offset = 0;
4584         addr_t Rn = ReadCoreReg (n, &success);
4585         if (!success)
4586             return false;
4587 
4588         addr_t address = Rn + addr_byte_size;
4589 
4590         EmulateInstruction::Context context;
4591         context.type = EmulateInstruction::eContextRegisterStore;
4592         RegisterInfo base_reg;
4593         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4594 
4595         uint32_t lowest_set_bit = 14;
4596         // for i = 0 to 14
4597         for (uint32_t i = 0; i < 14; ++i)
4598         {
4599             // if registers<i> == '1' then
4600             if (BitIsSet (registers, i))
4601             {
4602                 if (i < lowest_set_bit)
4603                     lowest_set_bit = i;
4604                 // if i == n && wback && i != LowestSetBit(registers) then
4605                 if ((i == n) && wback && (i != lowest_set_bit))
4606                     // MemA[address,4] = bits(32) UNKNOWN;
4607                     WriteBits32UnknownToMemory (address + offset);
4608                 // else
4609                 else
4610                 {
4611                     // MemA[address,4] = R[i];
4612                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4613                     if (!success)
4614                         return false;
4615 
4616                     RegisterInfo data_reg;
4617                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4618                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size);
4619                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4620                         return false;
4621                 }
4622 
4623                 // address = address + 4;
4624                 offset += addr_byte_size;
4625             }
4626         }
4627 
4628         // if registers<15> == '1' then
4629             // MemA[address,4] = PCStoreValue();
4630         if (BitIsSet (registers, 15))
4631         {
4632             RegisterInfo pc_reg;
4633             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4634             context.SetRegisterPlusOffset (pc_reg, 8);
4635             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4636             if (!success)
4637             return false;
4638 
4639             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4640                 return false;
4641         }
4642 
4643         // if wback then R[n] = R[n] + 4*BitCount(registers);
4644         if (wback)
4645         {
4646             offset = addr_byte_size * BitCount (registers);
4647             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4648             context.SetImmediateSigned (offset);
4649             addr_t data = Rn + offset;
4650             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4651                 return false;
4652         }
4653     }
4654     return true;
4655 }
4656 
4657 // STR (store immediate) calculates an address from a base register value and an immediate offset, and stores a word
4658 // from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
4659 bool
4660 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding)
4661 {
4662 #if 0
4663     if ConditionPassed() then
4664         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4665         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4666         address = if index then offset_addr else R[n];
4667         if UnalignedSupport() || address<1:0> == '00' then
4668             MemU[address,4] = R[t];
4669         else // Can only occur before ARMv7
4670             MemU[address,4] = bits(32) UNKNOWN;
4671         if wback then R[n] = offset_addr;
4672 #endif
4673 
4674     bool success = false;
4675 
4676     if (ConditionPassed(opcode))
4677     {
4678         const uint32_t addr_byte_size = GetAddressByteSize();
4679 
4680         uint32_t t;
4681         uint32_t n;
4682         uint32_t imm32;
4683         bool index;
4684         bool add;
4685         bool wback;
4686         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4687         switch (encoding)
4688         {
4689             case eEncodingT1:
4690                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
4691                 t = Bits32 (opcode, 2, 0);
4692                 n = Bits32 (opcode, 5, 3);
4693                 imm32 = Bits32 (opcode, 10, 6) << 2;
4694 
4695                 // index = TRUE; add = TRUE; wback = FALSE;
4696                 index = true;
4697                 add = false;
4698                 wback = false;
4699                 break;
4700 
4701             case eEncodingT2:
4702                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4703                 t = Bits32 (opcode, 10, 8);
4704                 n = 13;
4705                 imm32 = Bits32 (opcode, 7, 0) << 2;
4706 
4707                 // index = TRUE; add = TRUE; wback = FALSE;
4708                 index = true;
4709                 add = true;
4710                 wback = false;
4711                 break;
4712 
4713             case eEncodingT3:
4714                 // if Rn == '1111' then UNDEFINED;
4715                 if (Bits32 (opcode, 19, 16) == 15)
4716                     return false;
4717 
4718                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4719                 t = Bits32 (opcode, 15, 12);
4720                 n = Bits32 (opcode, 19, 16);
4721                 imm32 = Bits32 (opcode, 11, 0);
4722 
4723                 // index = TRUE; add = TRUE; wback = FALSE;
4724                 index = true;
4725                 add = true;
4726                 wback = false;
4727 
4728                 // if t == 15 then UNPREDICTABLE;
4729                 if (t == 15)
4730                     return false;
4731                 break;
4732 
4733             case eEncodingT4:
4734                 // if P == '1' && U == '1' && W == '0' then SEE STRT;
4735                 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH;
4736                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4737                 if ((Bits32 (opcode, 19, 16) == 15)
4738                       || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
4739                     return false;
4740 
4741                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4742                 t = Bits32 (opcode, 15, 12);
4743                 n = Bits32 (opcode, 19, 16);
4744                 imm32 = Bits32 (opcode, 7, 0);
4745 
4746                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4747                 index = BitIsSet (opcode, 10);
4748                 add = BitIsSet (opcode, 9);
4749                 wback = BitIsSet (opcode, 8);
4750 
4751                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
4752                 if ((t == 15) || (wback && (n == t)))
4753                     return false;
4754                 break;
4755 
4756             default:
4757                 return false;
4758         }
4759 
4760         addr_t offset_addr;
4761         addr_t address;
4762 
4763         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4764         uint32_t base_address = ReadCoreReg (n, &success);
4765         if (!success)
4766             return false;
4767 
4768         if (add)
4769             offset_addr = base_address + imm32;
4770         else
4771             offset_addr = base_address - imm32;
4772 
4773         // address = if index then offset_addr else R[n];
4774         if (index)
4775             address = offset_addr;
4776         else
4777             address = base_address;
4778 
4779         EmulateInstruction::Context context;
4780         context.type = eContextRegisterStore;
4781         RegisterInfo base_reg;
4782         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4783 
4784         // if UnalignedSupport() || address<1:0> == '00' then
4785         if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
4786         {
4787             // MemU[address,4] = R[t];
4788             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4789             if (!success)
4790                 return false;
4791 
4792             RegisterInfo data_reg;
4793             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4794             int32_t offset = address - base_address;
4795             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4796             if (!MemUWrite (context, address, data, addr_byte_size))
4797                 return false;
4798         }
4799         else
4800         {
4801             // MemU[address,4] = bits(32) UNKNOWN;
4802             WriteBits32UnknownToMemory (address);
4803         }
4804 
4805         // if wback then R[n] = offset_addr;
4806         if (wback)
4807         {
4808             context.type = eContextRegisterLoad;
4809             context.SetAddress (offset_addr);
4810             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4811                 return false;
4812         }
4813     }
4814     return true;
4815 }
4816 
4817 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a
4818 // word from a register to memory.   The offset register value can optionally be shifted.
4819 bool
4820 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding)
4821 {
4822 #if 0
4823     if ConditionPassed() then
4824         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4825         offset = Shift(R[m], shift_t, shift_n, APSR.C);
4826         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4827         address = if index then offset_addr else R[n];
4828         if t == 15 then // Only possible for encoding A1
4829             data = PCStoreValue();
4830         else
4831             data = R[t];
4832         if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4833             MemU[address,4] = data;
4834         else // Can only occur before ARMv7
4835             MemU[address,4] = bits(32) UNKNOWN;
4836         if wback then R[n] = offset_addr;
4837 #endif
4838 
4839     bool success = false;
4840 
4841     if (ConditionPassed(opcode))
4842     {
4843         const uint32_t addr_byte_size = GetAddressByteSize();
4844 
4845         uint32_t t;
4846         uint32_t n;
4847         uint32_t m;
4848         ARM_ShifterType shift_t;
4849         uint32_t shift_n;
4850         bool index;
4851         bool add;
4852         bool wback;
4853 
4854         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4855         switch (encoding)
4856         {
4857             case eEncodingT1:
4858                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4859                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4860                 t = Bits32 (opcode, 2, 0);
4861                 n = Bits32 (opcode, 5, 3);
4862                 m = Bits32 (opcode, 8, 6);
4863 
4864                 // index = TRUE; add = TRUE; wback = FALSE;
4865                 index = true;
4866                 add = true;
4867                 wback = false;
4868 
4869                 // (shift_t, shift_n) = (SRType_LSL, 0);
4870                 shift_t = SRType_LSL;
4871                 shift_n = 0;
4872                 break;
4873 
4874             case eEncodingT2:
4875                 // if Rn == '1111' then UNDEFINED;
4876                 if (Bits32 (opcode, 19, 16) == 15)
4877                     return false;
4878 
4879                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4880                 t = Bits32 (opcode, 15, 12);
4881                 n = Bits32 (opcode, 19, 16);
4882                 m = Bits32 (opcode, 3, 0);
4883 
4884                 // index = TRUE; add = TRUE; wback = FALSE;
4885                 index = true;
4886                 add = true;
4887                 wback = false;
4888 
4889                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4890                 shift_t = SRType_LSL;
4891                 shift_n = Bits32 (opcode, 5, 4);
4892 
4893                 // if t == 15 || BadReg(m) then UNPREDICTABLE;
4894                 if ((t == 15) || (BadReg (m)))
4895                     return false;
4896                 break;
4897 
4898             case eEncodingA1:
4899             {
4900                 // if P == '0' && W == '1' then SEE STRT;
4901                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4902                 t = Bits32 (opcode, 15, 12);
4903                 n = Bits32 (opcode, 19, 16);
4904                 m = Bits32 (opcode, 3, 0);
4905 
4906                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
4907                 index = BitIsSet (opcode, 24);
4908                 add = BitIsSet (opcode, 23);
4909                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
4910 
4911                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
4912                 uint32_t typ = Bits32 (opcode, 6, 5);
4913                 uint32_t imm5 = Bits32 (opcode, 11, 7);
4914                 shift_n = DecodeImmShift(typ, imm5, shift_t);
4915 
4916                 // if m == 15 then UNPREDICTABLE;
4917                 if (m == 15)
4918                     return false;
4919 
4920                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
4921                 if (wback && ((n == 15) || (n == t)))
4922                     return false;
4923 
4924                 break;
4925             }
4926             default:
4927                 return false;
4928         }
4929 
4930         addr_t offset_addr;
4931         addr_t address;
4932         int32_t offset = 0;
4933 
4934         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4935         if (!success)
4936             return false;
4937 
4938         uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
4939         if (!success)
4940             return false;
4941 
4942         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4943         offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success);
4944         if (!success)
4945             return false;
4946 
4947         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4948         if (add)
4949             offset_addr = base_address + offset;
4950         else
4951             offset_addr = base_address - offset;
4952 
4953         // address = if index then offset_addr else R[n];
4954         if (index)
4955             address = offset_addr;
4956         else
4957             address = base_address;
4958 
4959         uint32_t data;
4960         // if t == 15 then // Only possible for encoding A1
4961         if (t == 15)
4962             // data = PCStoreValue();
4963             data = ReadCoreReg (PC_REG, &success);
4964         else
4965             // data = R[t];
4966             data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4967 
4968         if (!success)
4969             return false;
4970 
4971         EmulateInstruction::Context context;
4972         context.type = eContextRegisterStore;
4973 
4974         // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4975         if (UnalignedSupport ()
4976             || (BitIsClear (address, 1) && BitIsClear (address, 0))
4977             || CurrentInstrSet() == eModeARM)
4978         {
4979             // MemU[address,4] = data;
4980 
4981             RegisterInfo base_reg;
4982             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 +  n, base_reg);
4983 
4984             RegisterInfo data_reg;
4985             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4986 
4987             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4988             if (!MemUWrite (context, address, data, addr_byte_size))
4989                 return false;
4990 
4991         }
4992         else
4993             // MemU[address,4] = bits(32) UNKNOWN;
4994             WriteBits32UnknownToMemory (address);
4995 
4996         // if wback then R[n] = offset_addr;
4997         if (wback)
4998         {
4999             context.type = eContextRegisterLoad;
5000             context.SetAddress (offset_addr);
5001             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5002                 return false;
5003         }
5004 
5005     }
5006     return true;
5007 }
5008 
5009 bool
5010 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding)
5011 {
5012 #if 0
5013     if ConditionPassed() then
5014         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5015         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5016         address = if index then offset_addr else R[n];
5017         MemU[address,1] = R[t]<7:0>;
5018         if wback then R[n] = offset_addr;
5019 #endif
5020 
5021 
5022     bool success = false;
5023 
5024     if (ConditionPassed(opcode))
5025     {
5026         uint32_t t;
5027         uint32_t n;
5028         uint32_t imm32;
5029         bool index;
5030         bool add;
5031         bool wback;
5032         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5033         switch (encoding)
5034         {
5035             case eEncodingT1:
5036                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
5037                 t = Bits32 (opcode, 2, 0);
5038                 n = Bits32 (opcode, 5, 3);
5039                 imm32 = Bits32 (opcode, 10, 6);
5040 
5041                 // index = TRUE; add = TRUE; wback = FALSE;
5042                 index = true;
5043                 add = true;
5044                 wback = false;
5045                 break;
5046 
5047             case eEncodingT2:
5048                 // if Rn == '1111' then UNDEFINED;
5049                 if (Bits32 (opcode, 19, 16) == 15)
5050                     return false;
5051 
5052                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5053                 t = Bits32 (opcode, 15, 12);
5054                 n = Bits32 (opcode, 19, 16);
5055                 imm32 = Bits32 (opcode, 11, 0);
5056 
5057                 // index = TRUE; add = TRUE; wback = FALSE;
5058                 index = true;
5059                 add = true;
5060                 wback = false;
5061 
5062                 // if BadReg(t) then UNPREDICTABLE;
5063                 if (BadReg (t))
5064                     return false;
5065                 break;
5066 
5067             case eEncodingT3:
5068                 // if P == '1' && U == '1' && W == '0' then SEE STRBT;
5069                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
5070                 if (Bits32 (opcode, 19, 16) == 15)
5071                     return false;
5072 
5073                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
5074                 t = Bits32 (opcode, 15, 12);
5075                 n = Bits32 (opcode, 19, 16);
5076                 imm32 = Bits32 (opcode, 7, 0);
5077 
5078                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
5079                 index = BitIsSet (opcode, 10);
5080                 add = BitIsSet (opcode, 9);
5081                 wback = BitIsSet (opcode, 8);
5082 
5083                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
5084                 if ((BadReg (t)) || (wback && (n == t)))
5085                     return false;
5086                 break;
5087 
5088             default:
5089                 return false;
5090         }
5091 
5092         addr_t offset_addr;
5093         addr_t address;
5094         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5095         if (!success)
5096             return false;
5097 
5098         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5099         if (add)
5100             offset_addr = base_address + imm32;
5101         else
5102             offset_addr = base_address - imm32;
5103 
5104         // address = if index then offset_addr else R[n];
5105         if (index)
5106             address = offset_addr;
5107         else
5108             address = base_address;
5109 
5110         // MemU[address,1] = R[t]<7:0>
5111         RegisterInfo base_reg;
5112         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5113 
5114         RegisterInfo data_reg;
5115         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5116 
5117         EmulateInstruction::Context context;
5118         context.type = eContextRegisterStore;
5119         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
5120 
5121         uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5122         if (!success)
5123             return false;
5124 
5125         data = Bits32 (data, 7, 0);
5126 
5127         if (!MemUWrite (context, address, data, 1))
5128             return false;
5129 
5130         // if wback then R[n] = offset_addr;
5131         if (wback)
5132         {
5133             context.type = eContextRegisterLoad;
5134             context.SetAddress (offset_addr);
5135             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5136                 return false;
5137         }
5138 
5139     }
5140 
5141     return true;
5142 }
5143 
5144 // STRH (register) calculates an address from a base register value and an offset register value, and stores a
5145 // halfword from a register to memory.  The offset register value can be shifted left by 0, 1, 2, or 3 bits.
5146 bool
5147 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding)
5148 {
5149 #if 0
5150     if ConditionPassed() then
5151         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5152         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5153         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5154         address = if index then offset_addr else R[n];
5155         if UnalignedSupport() || address<0> == '0' then
5156             MemU[address,2] = R[t]<15:0>;
5157         else // Can only occur before ARMv7
5158             MemU[address,2] = bits(16) UNKNOWN;
5159         if wback then R[n] = offset_addr;
5160 #endif
5161 
5162     bool success = false;
5163 
5164     if (ConditionPassed(opcode))
5165     {
5166         uint32_t t;
5167         uint32_t n;
5168         uint32_t m;
5169         bool index;
5170         bool add;
5171         bool wback;
5172         ARM_ShifterType shift_t;
5173         uint32_t shift_n;
5174 
5175         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5176         switch (encoding)
5177         {
5178             case eEncodingT1:
5179                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5180                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5181                 t = Bits32 (opcode, 2, 0);
5182                 n = Bits32 (opcode, 5, 3);
5183                 m = Bits32 (opcode, 8, 6);
5184 
5185                 // index = TRUE; add = TRUE; wback = FALSE;
5186                 index = true;
5187                 add = true;
5188                 wback = false;
5189 
5190                 // (shift_t, shift_n) = (SRType_LSL, 0);
5191                 shift_t = SRType_LSL;
5192                 shift_n = 0;
5193 
5194                 break;
5195 
5196             case eEncodingT2:
5197                 // if Rn == '1111' then UNDEFINED;
5198                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5199                 t = Bits32 (opcode, 15, 12);
5200                 n = Bits32 (opcode, 19, 16);
5201                 m = Bits32 (opcode, 3, 0);
5202                 if (n == 15)
5203                     return false;
5204 
5205                 // index = TRUE; add = TRUE; wback = FALSE;
5206                 index = true;
5207                 add = true;
5208                 wback = false;
5209 
5210                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5211                 shift_t = SRType_LSL;
5212                 shift_n = Bits32 (opcode, 5, 4);
5213 
5214                 // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5215                 if (BadReg (t) || BadReg (m))
5216                     return false;
5217 
5218                 break;
5219 
5220             case eEncodingA1:
5221                 // if P == '0' && W == '1' then SEE STRHT;
5222                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5223                 t = Bits32 (opcode, 15, 12);
5224                 n = Bits32 (opcode, 19, 16);
5225                 m = Bits32 (opcode, 3, 0);
5226 
5227                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5228                 index = BitIsSet (opcode, 24);
5229                 add = BitIsSet (opcode, 23);
5230                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5231 
5232                 // (shift_t, shift_n) = (SRType_LSL, 0);
5233                 shift_t = SRType_LSL;
5234                 shift_n = 0;
5235 
5236                 // if t == 15 || m == 15 then UNPREDICTABLE;
5237                 if ((t == 15) || (m == 15))
5238                     return false;
5239 
5240                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5241                 if (wback && ((n == 15) || (n == t)))
5242                     return false;
5243 
5244                 break;
5245 
5246             default:
5247                 return false;
5248         }
5249 
5250         uint32_t Rm = ReadCoreReg (m, &success);
5251         if (!success)
5252             return false;
5253 
5254         uint32_t Rn = ReadCoreReg (n, &success);
5255         if (!success)
5256             return false;
5257 
5258         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5259         uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
5260         if (!success)
5261             return false;
5262 
5263         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5264         addr_t offset_addr;
5265         if (add)
5266             offset_addr = Rn + offset;
5267         else
5268             offset_addr = Rn - offset;
5269 
5270         // address = if index then offset_addr else R[n];
5271         addr_t address;
5272         if (index)
5273             address = offset_addr;
5274         else
5275             address = Rn;
5276 
5277         EmulateInstruction::Context context;
5278         context.type = eContextRegisterStore;
5279         RegisterInfo base_reg;
5280         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5281         RegisterInfo offset_reg;
5282         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5283 
5284         // if UnalignedSupport() || address<0> == '0' then
5285         if (UnalignedSupport() || BitIsClear (address, 0))
5286         {
5287             // MemU[address,2] = R[t]<15:0>;
5288             uint32_t Rt = ReadCoreReg (t, &success);
5289             if (!success)
5290                 return false;
5291 
5292             EmulateInstruction::Context context;
5293             context.type = eContextRegisterStore;
5294             RegisterInfo base_reg;
5295             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5296             RegisterInfo offset_reg;
5297             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5298             RegisterInfo data_reg;
5299             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5300             context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
5301 
5302             if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2))
5303                 return false;
5304         }
5305         else // Can only occur before ARMv7
5306         {
5307             // MemU[address,2] = bits(16) UNKNOWN;
5308         }
5309 
5310         // if wback then R[n] = offset_addr;
5311         if (wback)
5312         {
5313             context.type = eContextAdjustBaseRegister;
5314             context.SetAddress (offset_addr);
5315             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5316                 return false;
5317         }
5318     }
5319 
5320     return true;
5321 }
5322 
5323 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value,
5324 // and writes the result to the destination register.  It can optionally update the condition flags
5325 // based on the result.
5326 bool
5327 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding)
5328 {
5329 #if 0
5330     // ARM pseudo code...
5331     if ConditionPassed() then
5332         EncodingSpecificOperations();
5333         (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5334         if d == 15 then         // Can only occur for ARM encoding
5335             ALUWritePC(result); // setflags is always FALSE here
5336         else
5337             R[d] = result;
5338             if setflags then
5339                 APSR.N = result<31>;
5340                 APSR.Z = IsZeroBit(result);
5341                 APSR.C = carry;
5342                 APSR.V = overflow;
5343 #endif
5344 
5345     bool success = false;
5346 
5347     if (ConditionPassed(opcode))
5348     {
5349         uint32_t Rd, Rn;
5350         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
5351         bool setflags;
5352         switch (encoding)
5353         {
5354         case eEncodingT1:
5355             Rd = Bits32(opcode, 11, 8);
5356             Rn = Bits32(opcode, 19, 16);
5357             setflags = BitIsSet(opcode, 20);
5358             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5359             if (BadReg(Rd) || BadReg(Rn))
5360                 return false;
5361             break;
5362         case eEncodingA1:
5363             Rd = Bits32(opcode, 15, 12);
5364             Rn = Bits32(opcode, 19, 16);
5365             setflags = BitIsSet(opcode, 20);
5366             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5367 
5368             if (Rd == 15 && setflags)
5369                 return EmulateSUBSPcLrEtc (opcode, encoding);
5370             break;
5371         default:
5372             return false;
5373         }
5374 
5375         // Read the first operand.
5376         int32_t val1 = ReadCoreReg(Rn, &success);
5377         if (!success)
5378             return false;
5379 
5380         AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5381 
5382         EmulateInstruction::Context context;
5383         context.type = EmulateInstruction::eContextImmediate;
5384         context.SetNoArgs ();
5385 
5386         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5387             return false;
5388     }
5389     return true;
5390 }
5391 
5392 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted
5393 // register value, and writes the result to the destination register.  It can optionally update the
5394 // condition flags based on the result.
5395 bool
5396 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding)
5397 {
5398 #if 0
5399     // ARM pseudo code...
5400     if ConditionPassed() then
5401         EncodingSpecificOperations();
5402         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5403         (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5404         if d == 15 then         // Can only occur for ARM encoding
5405             ALUWritePC(result); // setflags is always FALSE here
5406         else
5407             R[d] = result;
5408             if setflags then
5409                 APSR.N = result<31>;
5410                 APSR.Z = IsZeroBit(result);
5411                 APSR.C = carry;
5412                 APSR.V = overflow;
5413 #endif
5414 
5415     bool success = false;
5416 
5417     if (ConditionPassed(opcode))
5418     {
5419         uint32_t Rd, Rn, Rm;
5420         ARM_ShifterType shift_t;
5421         uint32_t shift_n; // the shift applied to the value read from Rm
5422         bool setflags;
5423         switch (encoding)
5424         {
5425         case eEncodingT1:
5426             Rd = Rn = Bits32(opcode, 2, 0);
5427             Rm = Bits32(opcode, 5, 3);
5428             setflags = !InITBlock();
5429             shift_t = SRType_LSL;
5430             shift_n = 0;
5431             break;
5432         case eEncodingT2:
5433             Rd = Bits32(opcode, 11, 8);
5434             Rn = Bits32(opcode, 19, 16);
5435             Rm = Bits32(opcode, 3, 0);
5436             setflags = BitIsSet(opcode, 20);
5437             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5438             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5439                 return false;
5440             break;
5441         case eEncodingA1:
5442             Rd = Bits32(opcode, 15, 12);
5443             Rn = Bits32(opcode, 19, 16);
5444             Rm = Bits32(opcode, 3, 0);
5445             setflags = BitIsSet(opcode, 20);
5446             shift_n = DecodeImmShiftARM(opcode, shift_t);
5447 
5448             if (Rd == 15 && setflags)
5449                 return EmulateSUBSPcLrEtc (opcode, encoding);
5450             break;
5451         default:
5452             return false;
5453         }
5454 
5455         // Read the first operand.
5456         int32_t val1 = ReadCoreReg(Rn, &success);
5457         if (!success)
5458             return false;
5459 
5460         // Read the second operand.
5461         int32_t val2 = ReadCoreReg(Rm, &success);
5462         if (!success)
5463             return false;
5464 
5465         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5466         if (!success)
5467             return false;
5468         AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5469 
5470         EmulateInstruction::Context context;
5471         context.type = EmulateInstruction::eContextImmediate;
5472         context.SetNoArgs ();
5473 
5474         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5475             return false;
5476     }
5477     return true;
5478 }
5479 
5480 // This instruction adds an immediate value to the PC value to form a PC-relative address,
5481 // and writes the result to the destination register.
5482 bool
5483 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding)
5484 {
5485 #if 0
5486     // ARM pseudo code...
5487     if ConditionPassed() then
5488         EncodingSpecificOperations();
5489         result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5490         if d == 15 then         // Can only occur for ARM encodings
5491             ALUWritePC(result);
5492         else
5493             R[d] = result;
5494 #endif
5495 
5496     bool success = false;
5497 
5498     if (ConditionPassed(opcode))
5499     {
5500         uint32_t Rd;
5501         uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5502         bool add;
5503         switch (encoding)
5504         {
5505         case eEncodingT1:
5506             Rd = Bits32(opcode, 10, 8);
5507             imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5508             add = true;
5509             break;
5510         case eEncodingT2:
5511         case eEncodingT3:
5512             Rd = Bits32(opcode, 11, 8);
5513             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5514             add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5515             if (BadReg(Rd))
5516                 return false;
5517             break;
5518         case eEncodingA1:
5519         case eEncodingA2:
5520             Rd = Bits32(opcode, 15, 12);
5521             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5522             add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5523             break;
5524         default:
5525             return false;
5526         }
5527 
5528         // Read the PC value.
5529         uint32_t pc = ReadCoreReg(PC_REG, &success);
5530         if (!success)
5531             return false;
5532 
5533         uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5534 
5535         EmulateInstruction::Context context;
5536         context.type = EmulateInstruction::eContextImmediate;
5537         context.SetNoArgs ();
5538 
5539         if (!WriteCoreReg(context, result, Rd))
5540             return false;
5541     }
5542     return true;
5543 }
5544 
5545 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result
5546 // to the destination register.  It can optionally update the condition flags based on the result.
5547 bool
5548 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding)
5549 {
5550 #if 0
5551     // ARM pseudo code...
5552     if ConditionPassed() then
5553         EncodingSpecificOperations();
5554         result = R[n] AND imm32;
5555         if d == 15 then         // Can only occur for ARM encoding
5556             ALUWritePC(result); // setflags is always FALSE here
5557         else
5558             R[d] = result;
5559             if setflags then
5560                 APSR.N = result<31>;
5561                 APSR.Z = IsZeroBit(result);
5562                 APSR.C = carry;
5563                 // APSR.V unchanged
5564 #endif
5565 
5566     bool success = false;
5567 
5568     if (ConditionPassed(opcode))
5569     {
5570         uint32_t Rd, Rn;
5571         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
5572         bool setflags;
5573         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5574         switch (encoding)
5575         {
5576         case eEncodingT1:
5577             Rd = Bits32(opcode, 11, 8);
5578             Rn = Bits32(opcode, 19, 16);
5579             setflags = BitIsSet(opcode, 20);
5580             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5581             // if Rd == '1111' && S == '1' then SEE TST (immediate);
5582             if (Rd == 15 && setflags)
5583                 return EmulateTSTImm(opcode, eEncodingT1);
5584             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
5585                 return false;
5586             break;
5587         case eEncodingA1:
5588             Rd = Bits32(opcode, 15, 12);
5589             Rn = Bits32(opcode, 19, 16);
5590             setflags = BitIsSet(opcode, 20);
5591             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5592 
5593             if (Rd == 15 && setflags)
5594                 return EmulateSUBSPcLrEtc (opcode, encoding);
5595             break;
5596         default:
5597             return false;
5598         }
5599 
5600         // Read the first operand.
5601         uint32_t val1 = ReadCoreReg(Rn, &success);
5602         if (!success)
5603             return false;
5604 
5605         uint32_t result = val1 & imm32;
5606 
5607         EmulateInstruction::Context context;
5608         context.type = EmulateInstruction::eContextImmediate;
5609         context.SetNoArgs ();
5610 
5611         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5612             return false;
5613     }
5614     return true;
5615 }
5616 
5617 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value,
5618 // and writes the result to the destination register.  It can optionally update the condition flags
5619 // based on the result.
5620 bool
5621 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding)
5622 {
5623 #if 0
5624     // ARM pseudo code...
5625     if ConditionPassed() then
5626         EncodingSpecificOperations();
5627         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5628         result = R[n] AND shifted;
5629         if d == 15 then         // Can only occur for ARM encoding
5630             ALUWritePC(result); // setflags is always FALSE here
5631         else
5632             R[d] = result;
5633             if setflags then
5634                 APSR.N = result<31>;
5635                 APSR.Z = IsZeroBit(result);
5636                 APSR.C = carry;
5637                 // APSR.V unchanged
5638 #endif
5639 
5640     bool success = false;
5641 
5642     if (ConditionPassed(opcode))
5643     {
5644         uint32_t Rd, Rn, Rm;
5645         ARM_ShifterType shift_t;
5646         uint32_t shift_n; // the shift applied to the value read from Rm
5647         bool setflags;
5648         uint32_t carry;
5649         switch (encoding)
5650         {
5651         case eEncodingT1:
5652             Rd = Rn = Bits32(opcode, 2, 0);
5653             Rm = Bits32(opcode, 5, 3);
5654             setflags = !InITBlock();
5655             shift_t = SRType_LSL;
5656             shift_n = 0;
5657             break;
5658         case eEncodingT2:
5659             Rd = Bits32(opcode, 11, 8);
5660             Rn = Bits32(opcode, 19, 16);
5661             Rm = Bits32(opcode, 3, 0);
5662             setflags = BitIsSet(opcode, 20);
5663             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5664             // if Rd == '1111' && S == '1' then SEE TST (register);
5665             if (Rd == 15 && setflags)
5666                 return EmulateTSTReg(opcode, eEncodingT2);
5667             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
5668                 return false;
5669             break;
5670         case eEncodingA1:
5671             Rd = Bits32(opcode, 15, 12);
5672             Rn = Bits32(opcode, 19, 16);
5673             Rm = Bits32(opcode, 3, 0);
5674             setflags = BitIsSet(opcode, 20);
5675             shift_n = DecodeImmShiftARM(opcode, shift_t);
5676 
5677             if (Rd == 15 && setflags)
5678                 return EmulateSUBSPcLrEtc (opcode, encoding);
5679             break;
5680         default:
5681             return false;
5682         }
5683 
5684         // Read the first operand.
5685         uint32_t val1 = ReadCoreReg(Rn, &success);
5686         if (!success)
5687             return false;
5688 
5689         // Read the second operand.
5690         uint32_t val2 = ReadCoreReg(Rm, &success);
5691         if (!success)
5692             return false;
5693 
5694         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5695         if (!success)
5696             return false;
5697         uint32_t result = val1 & shifted;
5698 
5699         EmulateInstruction::Context context;
5700         context.type = EmulateInstruction::eContextImmediate;
5701         context.SetNoArgs ();
5702 
5703         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5704             return false;
5705     }
5706     return true;
5707 }
5708 
5709 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an
5710 // immediate value, and writes the result to the destination register.  It can optionally update the
5711 // condition flags based on the result.
5712 bool
5713 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding)
5714 {
5715 #if 0
5716     // ARM pseudo code...
5717     if ConditionPassed() then
5718         EncodingSpecificOperations();
5719         result = R[n] AND NOT(imm32);
5720         if d == 15 then         // Can only occur for ARM encoding
5721             ALUWritePC(result); // setflags is always FALSE here
5722         else
5723             R[d] = result;
5724             if setflags then
5725                 APSR.N = result<31>;
5726                 APSR.Z = IsZeroBit(result);
5727                 APSR.C = carry;
5728                 // APSR.V unchanged
5729 #endif
5730 
5731     bool success = false;
5732 
5733     if (ConditionPassed(opcode))
5734     {
5735         uint32_t Rd, Rn;
5736         uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn
5737         bool setflags;
5738         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5739         switch (encoding)
5740         {
5741         case eEncodingT1:
5742             Rd = Bits32(opcode, 11, 8);
5743             Rn = Bits32(opcode, 19, 16);
5744             setflags = BitIsSet(opcode, 20);
5745             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5746             if (BadReg(Rd) || BadReg(Rn))
5747                 return false;
5748             break;
5749         case eEncodingA1:
5750             Rd = Bits32(opcode, 15, 12);
5751             Rn = Bits32(opcode, 19, 16);
5752             setflags = BitIsSet(opcode, 20);
5753             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5754 
5755             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5756             if (Rd == 15 && setflags)
5757                 return EmulateSUBSPcLrEtc (opcode, encoding);
5758             break;
5759         default:
5760             return false;
5761         }
5762 
5763         // Read the first operand.
5764         uint32_t val1 = ReadCoreReg(Rn, &success);
5765         if (!success)
5766             return false;
5767 
5768         uint32_t result = val1 & ~imm32;
5769 
5770         EmulateInstruction::Context context;
5771         context.type = EmulateInstruction::eContextImmediate;
5772         context.SetNoArgs ();
5773 
5774         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5775             return false;
5776     }
5777     return true;
5778 }
5779 
5780 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an
5781 // optionally-shifted register value, and writes the result to the destination register.
5782 // It can optionally update the condition flags based on the result.
5783 bool
5784 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding)
5785 {
5786 #if 0
5787     // ARM pseudo code...
5788     if ConditionPassed() then
5789         EncodingSpecificOperations();
5790         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5791         result = R[n] AND NOT(shifted);
5792         if d == 15 then         // Can only occur for ARM encoding
5793             ALUWritePC(result); // setflags is always FALSE here
5794         else
5795             R[d] = result;
5796             if setflags then
5797                 APSR.N = result<31>;
5798                 APSR.Z = IsZeroBit(result);
5799                 APSR.C = carry;
5800                 // APSR.V unchanged
5801 #endif
5802 
5803     bool success = false;
5804 
5805     if (ConditionPassed(opcode))
5806     {
5807         uint32_t Rd, Rn, Rm;
5808         ARM_ShifterType shift_t;
5809         uint32_t shift_n; // the shift applied to the value read from Rm
5810         bool setflags;
5811         uint32_t carry;
5812         switch (encoding)
5813         {
5814         case eEncodingT1:
5815             Rd = Rn = Bits32(opcode, 2, 0);
5816             Rm = Bits32(opcode, 5, 3);
5817             setflags = !InITBlock();
5818             shift_t = SRType_LSL;
5819             shift_n = 0;
5820             break;
5821         case eEncodingT2:
5822             Rd = Bits32(opcode, 11, 8);
5823             Rn = Bits32(opcode, 19, 16);
5824             Rm = Bits32(opcode, 3, 0);
5825             setflags = BitIsSet(opcode, 20);
5826             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5827             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5828                 return false;
5829             break;
5830         case eEncodingA1:
5831             Rd = Bits32(opcode, 15, 12);
5832             Rn = Bits32(opcode, 19, 16);
5833             Rm = Bits32(opcode, 3, 0);
5834             setflags = BitIsSet(opcode, 20);
5835             shift_n = DecodeImmShiftARM(opcode, shift_t);
5836 
5837             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5838             if (Rd == 15 && setflags)
5839                 return EmulateSUBSPcLrEtc (opcode, encoding);
5840             break;
5841         default:
5842             return false;
5843         }
5844 
5845         // Read the first operand.
5846         uint32_t val1 = ReadCoreReg(Rn, &success);
5847         if (!success)
5848             return false;
5849 
5850         // Read the second operand.
5851         uint32_t val2 = ReadCoreReg(Rm, &success);
5852         if (!success)
5853             return false;
5854 
5855         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5856         if (!success)
5857             return false;
5858         uint32_t result = val1 & ~shifted;
5859 
5860         EmulateInstruction::Context context;
5861         context.type = EmulateInstruction::eContextImmediate;
5862         context.SetNoArgs ();
5863 
5864         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5865             return false;
5866     }
5867     return true;
5868 }
5869 
5870 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
5871 // from memory, and writes it to a register.  It can use offset, post-indexed, or pre-indexed addressing.
5872 bool
5873 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding)
5874 {
5875 #if 0
5876     if ConditionPassed() then
5877         EncodingSpecificOperations();
5878         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5879         address = if index then offset_addr else R[n];
5880         data = MemU[address,4];
5881         if wback then R[n] = offset_addr;
5882         if t == 15 then
5883             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5884         elsif UnalignedSupport() || address<1:0> = '00' then
5885             R[t] = data;
5886         else // Can only apply before ARMv7
5887             R[t] = ROR(data, 8*UInt(address<1:0>));
5888 #endif
5889 
5890     bool success = false;
5891 
5892     if (ConditionPassed(opcode))
5893     {
5894         const uint32_t addr_byte_size = GetAddressByteSize();
5895 
5896         uint32_t t;
5897         uint32_t n;
5898         uint32_t imm32;
5899         bool index;
5900         bool add;
5901         bool wback;
5902 
5903         switch (encoding)
5904         {
5905             case eEncodingA1:
5906                 // if Rn == '1111' then SEE LDR (literal);
5907                 // if P == '0' && W == '1' then SEE LDRT;
5908                 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP;
5909                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5910                 t = Bits32 (opcode, 15, 12);
5911                 n = Bits32 (opcode, 19, 16);
5912                 imm32 = Bits32 (opcode, 11, 0);
5913 
5914                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5915                 index = BitIsSet (opcode, 24);
5916                 add = BitIsSet (opcode, 23);
5917                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5918 
5919                 // if wback && n == t then UNPREDICTABLE;
5920                 if (wback && (n == t))
5921                     return false;
5922 
5923                 break;
5924 
5925             default:
5926                 return false;
5927         }
5928 
5929         addr_t address;
5930         addr_t offset_addr;
5931         addr_t base_address = ReadCoreReg (n, &success);
5932         if (!success)
5933             return false;
5934 
5935         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5936         if (add)
5937             offset_addr = base_address + imm32;
5938         else
5939             offset_addr = base_address - imm32;
5940 
5941         // address = if index then offset_addr else R[n];
5942         if (index)
5943             address = offset_addr;
5944         else
5945             address = base_address;
5946 
5947         // data = MemU[address,4];
5948 
5949         RegisterInfo base_reg;
5950         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5951 
5952         EmulateInstruction::Context context;
5953         context.type = eContextRegisterLoad;
5954         context.SetRegisterPlusOffset (base_reg, address - base_address);
5955 
5956         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5957         if (!success)
5958             return false;
5959 
5960         // if wback then R[n] = offset_addr;
5961         if (wback)
5962         {
5963             context.type = eContextAdjustBaseRegister;
5964             context.SetAddress (offset_addr);
5965             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5966                 return false;
5967         }
5968 
5969         // if t == 15 then
5970         if (t == 15)
5971         {
5972             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5973             if (BitIsClear (address, 1) && BitIsClear (address, 0))
5974             {
5975                 // LoadWritePC (data);
5976                 context.type = eContextRegisterLoad;
5977                 context.SetRegisterPlusOffset (base_reg, address - base_address);
5978                 LoadWritePC (context, data);
5979             }
5980             else
5981                   return false;
5982         }
5983         // elsif UnalignedSupport() || address<1:0> = '00' then
5984         else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5985         {
5986             // R[t] = data;
5987             context.type = eContextRegisterLoad;
5988             context.SetRegisterPlusOffset (base_reg, address - base_address);
5989             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5990                 return false;
5991         }
5992         // else // Can only apply before ARMv7
5993         else
5994         {
5995             // R[t] = ROR(data, 8*UInt(address<1:0>));
5996             data = ROR (data, Bits32 (address, 1, 0), &success);
5997             if (!success)
5998                 return false;
5999             context.type = eContextRegisterLoad;
6000             context.SetImmediate (data);
6001             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6002                 return false;
6003         }
6004 
6005     }
6006     return true;
6007 }
6008 
6009 // LDR (register) calculates an address from a base register value and an offset register value, loads a word
6010 // from memory, and writes it to a register.  The offset register value can optionally be shifted.
6011 bool
6012 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding)
6013 {
6014 #if 0
6015     if ConditionPassed() then
6016         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6017         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6018         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6019         address = if index then offset_addr else R[n];
6020         data = MemU[address,4];
6021         if wback then R[n] = offset_addr;
6022         if t == 15 then
6023             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6024         elsif UnalignedSupport() || address<1:0> = '00' then
6025             R[t] = data;
6026         else // Can only apply before ARMv7
6027             if CurrentInstrSet() == InstrSet_ARM then
6028                 R[t] = ROR(data, 8*UInt(address<1:0>));
6029             else
6030                 R[t] = bits(32) UNKNOWN;
6031 #endif
6032 
6033     bool success = false;
6034 
6035     if (ConditionPassed(opcode))
6036     {
6037         const uint32_t addr_byte_size = GetAddressByteSize();
6038 
6039         uint32_t t;
6040         uint32_t n;
6041         uint32_t m;
6042         bool index;
6043         bool add;
6044         bool wback;
6045         ARM_ShifterType shift_t;
6046         uint32_t shift_n;
6047 
6048         switch (encoding)
6049         {
6050             case eEncodingT1:
6051                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6052                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6053                 t = Bits32 (opcode, 2, 0);
6054                 n = Bits32 (opcode, 5, 3);
6055                 m = Bits32 (opcode, 8, 6);
6056 
6057                 // index = TRUE; add = TRUE; wback = FALSE;
6058                 index = true;
6059                 add = true;
6060                 wback = false;
6061 
6062                 // (shift_t, shift_n) = (SRType_LSL, 0);
6063                 shift_t = SRType_LSL;
6064                 shift_n = 0;
6065 
6066                 break;
6067 
6068             case eEncodingT2:
6069                 // if Rn == '1111' then SEE LDR (literal);
6070                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6071                 t = Bits32 (opcode, 15, 12);
6072                 n = Bits32 (opcode, 19, 16);
6073                 m = Bits32 (opcode, 3, 0);
6074 
6075                 // index = TRUE; add = TRUE; wback = FALSE;
6076                 index = true;
6077                 add = true;
6078                 wback = false;
6079 
6080                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6081                 shift_t = SRType_LSL;
6082                 shift_n = Bits32 (opcode, 5, 4);
6083 
6084                 // if BadReg(m) then UNPREDICTABLE;
6085                 if (BadReg (m))
6086                     return false;
6087 
6088                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
6089                 if ((t == 15) && InITBlock() && !LastInITBlock())
6090                     return false;
6091 
6092                 break;
6093 
6094             case eEncodingA1:
6095             {
6096                 // if P == '0' && W == '1' then SEE LDRT;
6097                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6098                 t = Bits32 (opcode, 15, 12);
6099                 n = Bits32 (opcode, 19, 16);
6100                 m = Bits32 (opcode, 3, 0);
6101 
6102                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6103                 index = BitIsSet (opcode, 24);
6104                 add = BitIsSet (opcode, 23);
6105                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6106 
6107                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6108                 uint32_t type = Bits32 (opcode, 6, 5);
6109                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6110                 shift_n = DecodeImmShift (type, imm5, shift_t);
6111 
6112                 // if m == 15 then UNPREDICTABLE;
6113                 if (m == 15)
6114                     return false;
6115 
6116                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6117                 if (wback && ((n == 15) || (n == t)))
6118                     return false;
6119             }
6120                 break;
6121 
6122 
6123             default:
6124                 return false;
6125         }
6126 
6127         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6128         if (!success)
6129             return false;
6130 
6131         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6132         if (!success)
6133             return false;
6134 
6135         addr_t offset_addr;
6136         addr_t address;
6137 
6138         // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an application level alias for the CPSR".
6139         addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success);
6140         if (!success)
6141             return false;
6142 
6143         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6144         if (add)
6145             offset_addr = Rn + offset;
6146         else
6147             offset_addr = Rn - offset;
6148 
6149         // address = if index then offset_addr else R[n];
6150             if (index)
6151                 address = offset_addr;
6152             else
6153                 address = Rn;
6154 
6155         // data = MemU[address,4];
6156         RegisterInfo base_reg;
6157         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6158 
6159         EmulateInstruction::Context context;
6160         context.type = eContextRegisterLoad;
6161         context.SetRegisterPlusOffset (base_reg, address - Rn);
6162 
6163         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
6164         if (!success)
6165             return false;
6166 
6167         // if wback then R[n] = offset_addr;
6168         if (wback)
6169         {
6170             context.type = eContextAdjustBaseRegister;
6171             context.SetAddress (offset_addr);
6172             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6173                 return false;
6174         }
6175 
6176         // if t == 15 then
6177         if (t == 15)
6178         {
6179             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6180             if (BitIsClear (address, 1) && BitIsClear (address, 0))
6181             {
6182                 context.type = eContextRegisterLoad;
6183                 context.SetRegisterPlusOffset (base_reg, address - Rn);
6184                 LoadWritePC (context, data);
6185             }
6186             else
6187                 return false;
6188         }
6189         // elsif UnalignedSupport() || address<1:0> = '00' then
6190         else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
6191         {
6192             // R[t] = data;
6193             context.type = eContextRegisterLoad;
6194             context.SetRegisterPlusOffset (base_reg, address - Rn);
6195             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6196                 return false;
6197         }
6198         else // Can only apply before ARMv7
6199         {
6200             // if CurrentInstrSet() == InstrSet_ARM then
6201             if (CurrentInstrSet () == eModeARM)
6202             {
6203                 // R[t] = ROR(data, 8*UInt(address<1:0>));
6204                 data = ROR (data, Bits32 (address, 1, 0), &success);
6205                 if (!success)
6206                     return false;
6207                 context.type = eContextRegisterLoad;
6208                 context.SetImmediate (data);
6209                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6210                     return false;
6211             }
6212             else
6213             {
6214                 // R[t] = bits(32) UNKNOWN;
6215                 WriteBits32Unknown (t);
6216             }
6217         }
6218     }
6219     return true;
6220 }
6221 
6222 // LDRB (immediate, Thumb)
6223 bool
6224 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6225 {
6226 #if 0
6227     if ConditionPassed() then
6228         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6229         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6230         address = if index then offset_addr else R[n];
6231         R[t] = ZeroExtend(MemU[address,1], 32);
6232         if wback then R[n] = offset_addr;
6233 #endif
6234 
6235     bool success = false;
6236 
6237     if (ConditionPassed(opcode))
6238     {
6239         uint32_t t;
6240         uint32_t n;
6241         uint32_t imm32;
6242         bool index;
6243         bool add;
6244         bool wback;
6245 
6246         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6247         switch (encoding)
6248         {
6249             case eEncodingT1:
6250                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6251                 t = Bits32 (opcode, 2, 0);
6252                 n = Bits32 (opcode, 5, 3);
6253                 imm32 = Bits32 (opcode, 10, 6);
6254 
6255                 // index = TRUE; add = TRUE; wback = FALSE;
6256                 index = true;
6257                 add = true;
6258                 wback= false;
6259 
6260                 break;
6261 
6262             case eEncodingT2:
6263                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6264                 t = Bits32 (opcode, 15, 12);
6265                 n = Bits32 (opcode, 19, 16);
6266                 imm32 = Bits32 (opcode, 11, 0);
6267 
6268                 // index = TRUE; add = TRUE; wback = FALSE;
6269                 index = true;
6270                 add = true;
6271                 wback = false;
6272 
6273                 // if Rt == '1111' then SEE PLD;
6274                 if (t == 15)
6275                     return false; // PLD is not implemented yet
6276 
6277                 // if Rn == '1111' then SEE LDRB (literal);
6278                 if (n == 15)
6279                     return EmulateLDRBLiteral(opcode, eEncodingT1);
6280 
6281                 // if t == 13 then UNPREDICTABLE;
6282                 if (t == 13)
6283                     return false;
6284 
6285                 break;
6286 
6287             case eEncodingT3:
6288                 // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6289                 // if P == '0' && W == '0' then UNDEFINED;
6290                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6291                     return false;
6292 
6293                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6294                 t = Bits32 (opcode, 15, 12);
6295                 n = Bits32 (opcode, 19, 16);
6296                 imm32 = Bits32 (opcode, 7, 0);
6297 
6298                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6299                 index = BitIsSet (opcode, 10);
6300                 add = BitIsSet (opcode, 9);
6301                 wback = BitIsSet (opcode, 8);
6302 
6303                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6304                 if (t == 15)
6305                     return false; // PLD is not implemented yet
6306 
6307                 // if Rn == '1111' then SEE LDRB (literal);
6308                 if (n == 15)
6309                     return EmulateLDRBLiteral(opcode, eEncodingT1);
6310 
6311                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6312                 if (BadReg (t) || (wback && (n == t)))
6313                     return false;
6314 
6315                 break;
6316 
6317             default:
6318                 return false;
6319         }
6320 
6321         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6322         if (!success)
6323             return false;
6324 
6325         addr_t address;
6326         addr_t offset_addr;
6327 
6328         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6329         if (add)
6330             offset_addr = Rn + imm32;
6331         else
6332             offset_addr = Rn - imm32;
6333 
6334         // address = if index then offset_addr else R[n];
6335         if (index)
6336             address = offset_addr;
6337         else
6338             address = Rn;
6339 
6340         // R[t] = ZeroExtend(MemU[address,1], 32);
6341         RegisterInfo base_reg;
6342         RegisterInfo data_reg;
6343         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6344         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6345 
6346         EmulateInstruction::Context context;
6347         context.type = eContextRegisterLoad;
6348         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
6349 
6350         uint64_t data = MemURead (context, address, 1, 0, &success);
6351         if (!success)
6352             return false;
6353 
6354         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6355             return false;
6356 
6357         // if wback then R[n] = offset_addr;
6358         if (wback)
6359         {
6360             context.type = eContextAdjustBaseRegister;
6361             context.SetAddress (offset_addr);
6362             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6363                 return false;
6364         }
6365     }
6366     return true;
6367 }
6368 
6369 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6370 // zero-extends it to form a 32-bit word and writes it to a register.
6371 bool
6372 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6373 {
6374 #if 0
6375     if ConditionPassed() then
6376         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6377         base = Align(PC,4);
6378         address = if add then (base + imm32) else (base - imm32);
6379         R[t] = ZeroExtend(MemU[address,1], 32);
6380 #endif
6381 
6382     bool success = false;
6383 
6384     if (ConditionPassed(opcode))
6385     {
6386         uint32_t t;
6387         uint32_t imm32;
6388         bool add;
6389         switch (encoding)
6390         {
6391             case eEncodingT1:
6392                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6393                 t = Bits32 (opcode, 15, 12);
6394                 imm32 = Bits32 (opcode, 11, 0);
6395                 add = BitIsSet (opcode, 23);
6396 
6397                 // if Rt == '1111' then SEE PLD;
6398                 if (t == 15)
6399                     return false; // PLD is not implemented yet
6400 
6401                 // if t == 13 then UNPREDICTABLE;
6402                 if (t == 13)
6403                     return false;
6404 
6405                 break;
6406 
6407             case eEncodingA1:
6408                 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6409                 t = Bits32 (opcode, 15, 12);
6410                 imm32 = Bits32 (opcode, 11, 0);
6411                 add = BitIsSet (opcode, 23);
6412 
6413                 // if t == 15 then UNPREDICTABLE;
6414                 if (t == 15)
6415                     return false;
6416                 break;
6417 
6418             default:
6419                 return false;
6420         }
6421 
6422         // base = Align(PC,4);
6423         uint32_t pc_val = ReadCoreReg (PC_REG, &success);
6424         if (!success)
6425             return false;
6426 
6427         uint32_t base = AlignPC (pc_val);
6428 
6429         addr_t address;
6430         // address = if add then (base + imm32) else (base - imm32);
6431         if (add)
6432             address = base + imm32;
6433         else
6434             address = base - imm32;
6435 
6436         // R[t] = ZeroExtend(MemU[address,1], 32);
6437         EmulateInstruction::Context context;
6438         context.type = eContextRelativeBranchImmediate;
6439         context.SetImmediate (address - base);
6440 
6441         uint64_t data = MemURead (context, address, 1, 0, &success);
6442         if (!success)
6443             return false;
6444 
6445         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6446             return false;
6447     }
6448     return true;
6449 }
6450 
6451 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from
6452 // memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6453 // optionally be shifted.
6454 bool
6455 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding)
6456 {
6457 #if 0
6458     if ConditionPassed() then
6459         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6460         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6461         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6462         address = if index then offset_addr else R[n];
6463         R[t] = ZeroExtend(MemU[address,1],32);
6464         if wback then R[n] = offset_addr;
6465 #endif
6466 
6467     bool success = false;
6468 
6469     if (ConditionPassed(opcode))
6470     {
6471         uint32_t t;
6472         uint32_t n;
6473         uint32_t m;
6474         bool index;
6475         bool add;
6476         bool wback;
6477         ARM_ShifterType shift_t;
6478         uint32_t shift_n;
6479 
6480         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6481         switch (encoding)
6482         {
6483             case eEncodingT1:
6484                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6485                 t = Bits32 (opcode, 2, 0);
6486                 n = Bits32 (opcode, 5, 3);
6487                 m = Bits32 (opcode, 8, 6);
6488 
6489                 // index = TRUE; add = TRUE; wback = FALSE;
6490                 index = true;
6491                 add = true;
6492                 wback = false;
6493 
6494                 // (shift_t, shift_n) = (SRType_LSL, 0);
6495                 shift_t = SRType_LSL;
6496                 shift_n = 0;
6497                 break;
6498 
6499             case eEncodingT2:
6500                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6501                 t = Bits32 (opcode, 15, 12);
6502                 n = Bits32 (opcode, 19, 16);
6503                 m = Bits32 (opcode, 3, 0);
6504 
6505                 // index = TRUE; add = TRUE; wback = FALSE;
6506                 index = true;
6507                 add = true;
6508                 wback = false;
6509 
6510                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6511                 shift_t = SRType_LSL;
6512                 shift_n = Bits32 (opcode, 5, 4);
6513 
6514                 // if Rt == '1111' then SEE PLD;
6515                 if (t == 15)
6516                     return false; // PLD is not implemented yet
6517 
6518                 // if Rn == '1111' then SEE LDRB (literal);
6519                 if (n == 15)
6520                     return EmulateLDRBLiteral(opcode, eEncodingT1);
6521 
6522                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6523                 if ((t == 13) || BadReg (m))
6524                     return false;
6525                 break;
6526 
6527             case eEncodingA1:
6528             {
6529                 // if P == '0' && W == '1' then SEE LDRBT;
6530                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6531                 t = Bits32 (opcode, 15, 12);
6532                 n = Bits32 (opcode, 19, 16);
6533                 m = Bits32 (opcode, 3, 0);
6534 
6535                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6536                 index = BitIsSet (opcode, 24);
6537                 add = BitIsSet (opcode, 23);
6538                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6539 
6540                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6541                 uint32_t type = Bits32 (opcode, 6, 5);
6542                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6543                 shift_n = DecodeImmShift (type, imm5, shift_t);
6544 
6545                 // if t == 15 || m == 15 then UNPREDICTABLE;
6546                 if ((t == 15) || (m == 15))
6547                     return false;
6548 
6549                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6550                 if (wback && ((n == 15) || (n == t)))
6551                     return false;
6552             }
6553                 break;
6554 
6555             default:
6556                 return false;
6557         }
6558 
6559         addr_t offset_addr;
6560         addr_t address;
6561 
6562         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6563         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6564         if (!success)
6565             return false;
6566 
6567         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6568         if (!success)
6569             return false;
6570 
6571         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6572         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6573         if (!success)
6574             return false;
6575 
6576         if (add)
6577             offset_addr = Rn + offset;
6578         else
6579             offset_addr = Rn - offset;
6580 
6581         // address = if index then offset_addr else R[n];
6582         if (index)
6583             address = offset_addr;
6584         else
6585             address = Rn;
6586 
6587         // R[t] = ZeroExtend(MemU[address,1],32);
6588         RegisterInfo base_reg;
6589         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6590 
6591         EmulateInstruction::Context context;
6592         context.type = eContextRegisterLoad;
6593         context.SetRegisterPlusOffset (base_reg, address - Rn);
6594 
6595         uint64_t data = MemURead (context, address, 1, 0, &success);
6596         if (!success)
6597             return false;
6598 
6599         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6600             return false;
6601 
6602         // if wback then R[n] = offset_addr;
6603         if (wback)
6604         {
6605             context.type = eContextAdjustBaseRegister;
6606             context.SetAddress (offset_addr);
6607             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6608                 return false;
6609         }
6610     }
6611     return true;
6612 }
6613 
6614 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a
6615 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register.  It can use offset,
6616 // post-indexed, or pre-indexed addressing.
6617 bool
6618 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding)
6619 {
6620 #if 0
6621     if ConditionPassed() then
6622         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6623         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6624         address = if index then offset_addr else R[n];
6625         data = MemU[address,2];
6626         if wback then R[n] = offset_addr;
6627         if UnalignedSupport() || address<0> = '0' then
6628             R[t] = ZeroExtend(data, 32);
6629         else // Can only apply before ARMv7
6630             R[t] = bits(32) UNKNOWN;
6631 #endif
6632 
6633 
6634     bool success = false;
6635 
6636     if (ConditionPassed(opcode))
6637     {
6638         uint32_t t;
6639         uint32_t n;
6640         uint32_t imm32;
6641         bool index;
6642         bool add;
6643         bool wback;
6644 
6645         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6646         switch (encoding)
6647         {
6648             case eEncodingT1:
6649                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
6650                 t = Bits32 (opcode, 2, 0);
6651                 n = Bits32 (opcode, 5, 3);
6652                 imm32 = Bits32 (opcode, 10, 6) << 1;
6653 
6654                 // index = TRUE; add = TRUE; wback = FALSE;
6655                 index = true;
6656                 add = true;
6657                 wback = false;
6658 
6659                 break;
6660 
6661             case eEncodingT2:
6662                 // if Rt == '1111' then SEE "Unallocated memory hints";
6663                 // if Rn == '1111' then SEE LDRH (literal);
6664                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6665                 t = Bits32 (opcode, 15, 12);
6666                 n = Bits32 (opcode, 19, 16);
6667                 imm32 = Bits32 (opcode, 11, 0);
6668 
6669                 // index = TRUE; add = TRUE; wback = FALSE;
6670                 index = true;
6671                 add = true;
6672                 wback = false;
6673 
6674                 // if t == 13 then UNPREDICTABLE;
6675                 if (t == 13)
6676                     return false;
6677                 break;
6678 
6679             case eEncodingT3:
6680                 // if Rn == '1111' then SEE LDRH (literal);
6681                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
6682                 // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
6683                 // if P == '0' && W == '0' then UNDEFINED;
6684                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6685                     return false;
6686 
6687                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6688                 t = Bits32 (opcode, 15, 12);
6689                 n = Bits32 (opcode, 19, 16);
6690                 imm32 = Bits32 (opcode, 7, 0);
6691 
6692                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6693                 index = BitIsSet (opcode, 10);
6694                 add = BitIsSet (opcode, 9);
6695                 wback = BitIsSet (opcode, 8);
6696 
6697                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6698                 if (BadReg (t) || (wback && (n == t)))
6699                     return false;
6700                 break;
6701 
6702             default:
6703                 return false;
6704         }
6705 
6706         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6707         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6708         if (!success)
6709             return false;
6710 
6711         addr_t offset_addr;
6712         addr_t address;
6713 
6714         if (add)
6715             offset_addr = Rn + imm32;
6716         else
6717             offset_addr = Rn - imm32;
6718 
6719         // address = if index then offset_addr else R[n];
6720         if (index)
6721             address = offset_addr;
6722         else
6723             address = Rn;
6724 
6725         // data = MemU[address,2];
6726         RegisterInfo base_reg;
6727         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6728 
6729         EmulateInstruction::Context context;
6730         context.type = eContextRegisterLoad;
6731         context.SetRegisterPlusOffset (base_reg, address - Rn);
6732 
6733         uint64_t data = MemURead (context, address, 2, 0, &success);
6734         if (!success)
6735             return false;
6736 
6737         // if wback then R[n] = offset_addr;
6738         if (wback)
6739         {
6740             context.type = eContextAdjustBaseRegister;
6741             context.SetAddress (offset_addr);
6742             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6743                 return false;
6744         }
6745 
6746         // if UnalignedSupport() || address<0> = '0' then
6747         if (UnalignedSupport () || BitIsClear (address, 0))
6748         {
6749             // R[t] = ZeroExtend(data, 32);
6750             context.type = eContextRegisterLoad;
6751             context.SetRegisterPlusOffset (base_reg, address - Rn);
6752             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6753                 return false;
6754         }
6755         else // Can only apply before ARMv7
6756         {
6757             // R[t] = bits(32) UNKNOWN;
6758             WriteBits32Unknown (t);
6759         }
6760     }
6761     return true;
6762 }
6763 
6764 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory,
6765 // zero-extends it to form a 32-bit word, and writes it to a register.
6766 bool
6767 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding)
6768 {
6769 #if 0
6770     if ConditionPassed() then
6771         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6772         base = Align(PC,4);
6773         address = if add then (base + imm32) else (base - imm32);
6774         data = MemU[address,2];
6775         if UnalignedSupport() || address<0> = '0' then
6776             R[t] = ZeroExtend(data, 32);
6777         else // Can only apply before ARMv7
6778             R[t] = bits(32) UNKNOWN;
6779 #endif
6780 
6781     bool success = false;
6782 
6783     if (ConditionPassed(opcode))
6784     {
6785         uint32_t t;
6786         uint32_t imm32;
6787         bool add;
6788 
6789         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6790         switch (encoding)
6791         {
6792             case eEncodingT1:
6793                 // if Rt == '1111' then SEE "Unallocated memory hints";
6794                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6795                 t = Bits32 (opcode, 15, 12);
6796                 imm32 = Bits32 (opcode, 11, 0);
6797                 add = BitIsSet (opcode, 23);
6798 
6799                 // if t == 13 then UNPREDICTABLE;
6800                 if (t == 13)
6801                     return false;
6802 
6803                 break;
6804 
6805             case eEncodingA1:
6806             {
6807                 uint32_t imm4H = Bits32 (opcode, 11, 8);
6808                 uint32_t imm4L = Bits32 (opcode, 3, 0);
6809 
6810                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6811                 t = Bits32 (opcode, 15, 12);
6812                 imm32 = (imm4H << 4) | imm4L;
6813                 add = BitIsSet (opcode, 23);
6814 
6815                 // if t == 15 then UNPREDICTABLE;
6816                 if (t == 15)
6817                     return false;
6818                 break;
6819             }
6820 
6821             default:
6822                 return false;
6823         }
6824 
6825         // base = Align(PC,4);
6826         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6827         if (!success)
6828             return false;
6829 
6830         addr_t base = AlignPC (pc_value);
6831         addr_t address;
6832 
6833         // address = if add then (base + imm32) else (base - imm32);
6834         if (add)
6835             address = base + imm32;
6836         else
6837             address = base - imm32;
6838 
6839         // data = MemU[address,2];
6840         RegisterInfo base_reg;
6841         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
6842 
6843         EmulateInstruction::Context context;
6844         context.type = eContextRegisterLoad;
6845         context.SetRegisterPlusOffset (base_reg, address - base);
6846 
6847         uint64_t data = MemURead (context, address, 2, 0, &success);
6848         if (!success)
6849             return false;
6850 
6851 
6852         // if UnalignedSupport() || address<0> = '0' then
6853         if (UnalignedSupport () || BitIsClear (address, 0))
6854         {
6855             // R[t] = ZeroExtend(data, 32);
6856             context.type = eContextRegisterLoad;
6857             context.SetRegisterPlusOffset (base_reg, address - base);
6858             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6859                 return false;
6860 
6861         }
6862         else // Can only apply before ARMv7
6863         {
6864             // R[t] = bits(32) UNKNOWN;
6865             WriteBits32Unknown (t);
6866         }
6867     }
6868     return true;
6869 }
6870 
6871 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword
6872 // from memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6873 // be shifted left by 0, 1, 2, or 3 bits.
6874 bool
6875 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding)
6876 {
6877 #if 0
6878     if ConditionPassed() then
6879         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6880         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6881         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6882         address = if index then offset_addr else R[n];
6883         data = MemU[address,2];
6884         if wback then R[n] = offset_addr;
6885         if UnalignedSupport() || address<0> = '0' then
6886             R[t] = ZeroExtend(data, 32);
6887         else // Can only apply before ARMv7
6888             R[t] = bits(32) UNKNOWN;
6889 #endif
6890 
6891     bool success = false;
6892 
6893     if (ConditionPassed(opcode))
6894     {
6895         uint32_t t;
6896         uint32_t n;
6897         uint32_t m;
6898         bool index;
6899         bool add;
6900         bool wback;
6901         ARM_ShifterType shift_t;
6902         uint32_t shift_n;
6903 
6904         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6905         switch (encoding)
6906         {
6907             case eEncodingT1:
6908                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6909                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6910                 t = Bits32 (opcode, 2, 0);
6911                 n = Bits32 (opcode, 5, 3);
6912                 m = Bits32 (opcode, 8, 6);
6913 
6914                 // index = TRUE; add = TRUE; wback = FALSE;
6915                 index = true;
6916                 add = true;
6917                 wback = false;
6918 
6919                 // (shift_t, shift_n) = (SRType_LSL, 0);
6920                 shift_t = SRType_LSL;
6921                 shift_n = 0;
6922 
6923                 break;
6924 
6925             case eEncodingT2:
6926                 // if Rn == '1111' then SEE LDRH (literal);
6927                 // if Rt == '1111' then SEE "Unallocated memory hints";
6928                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6929                 t = Bits32 (opcode, 15, 12);
6930                 n = Bits32 (opcode, 19, 16);
6931                 m = Bits32 (opcode, 3, 0);
6932 
6933                 // index = TRUE; add = TRUE; wback = FALSE;
6934                 index = true;
6935                 add = true;
6936                 wback = false;
6937 
6938                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6939                 shift_t = SRType_LSL;
6940                 shift_n = Bits32 (opcode, 5, 4);
6941 
6942                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6943                 if ((t == 13) || BadReg (m))
6944                     return false;
6945                 break;
6946 
6947             case eEncodingA1:
6948                 // if P == '0' && W == '1' then SEE LDRHT;
6949                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6950                 t = Bits32 (opcode, 15, 12);
6951                 n = Bits32 (opcode, 19, 16);
6952                 m = Bits32 (opcode, 3, 0);
6953 
6954                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6955                 index = BitIsSet (opcode, 24);
6956                 add = BitIsSet (opcode, 23);
6957                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6958 
6959                 // (shift_t, shift_n) = (SRType_LSL, 0);
6960                 shift_t = SRType_LSL;
6961                 shift_n = 0;
6962 
6963                 // if t == 15 || m == 15 then UNPREDICTABLE;
6964                 if ((t == 15) || (m == 15))
6965                     return false;
6966 
6967                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6968                 if (wback && ((n == 15) || (n == t)))
6969                     return false;
6970 
6971                 break;
6972 
6973             default:
6974                 return false;
6975         }
6976 
6977         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6978 
6979         uint64_t Rm  = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6980         if (!success)
6981             return false;
6982 
6983         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6984         if (!success)
6985             return false;
6986 
6987         addr_t offset_addr;
6988         addr_t address;
6989 
6990         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6991         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6992         if (!success)
6993             return false;
6994 
6995         if (add)
6996             offset_addr = Rn + offset;
6997         else
6998             offset_addr = Rn - offset;
6999 
7000         // address = if index then offset_addr else R[n];
7001         if (index)
7002             address = offset_addr;
7003         else
7004             address = Rn;
7005 
7006         // data = MemU[address,2];
7007         RegisterInfo base_reg;
7008         RegisterInfo offset_reg;
7009         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7010         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7011 
7012         EmulateInstruction::Context context;
7013         context.type = eContextRegisterLoad;
7014         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7015         uint64_t data = MemURead (context, address, 2, 0, &success);
7016         if (!success)
7017             return false;
7018 
7019         // if wback then R[n] = offset_addr;
7020         if (wback)
7021         {
7022             context.type = eContextAdjustBaseRegister;
7023             context.SetAddress (offset_addr);
7024             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7025                 return false;
7026         }
7027 
7028         // if UnalignedSupport() || address<0> = '0' then
7029         if (UnalignedSupport() || BitIsClear (address, 0))
7030         {
7031             // R[t] = ZeroExtend(data, 32);
7032             context.type = eContextRegisterLoad;
7033             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7034             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
7035                 return false;
7036         }
7037         else // Can only apply before ARMv7
7038         {
7039             // R[t] = bits(32) UNKNOWN;
7040             WriteBits32Unknown (t);
7041         }
7042     }
7043     return true;
7044 }
7045 
7046 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from
7047 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed,
7048 // or pre-indexed addressing.
7049 bool
7050 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding)
7051 {
7052 #if 0
7053     if ConditionPassed() then
7054         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7055         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7056         address = if index then offset_addr else R[n];
7057         R[t] = SignExtend(MemU[address,1], 32);
7058         if wback then R[n] = offset_addr;
7059 #endif
7060 
7061     bool success = false;
7062 
7063     if (ConditionPassed(opcode))
7064     {
7065         uint32_t t;
7066         uint32_t n;
7067         uint32_t imm32;
7068         bool index;
7069         bool add;
7070         bool wback;
7071 
7072         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7073         switch (encoding)
7074         {
7075             case eEncodingT1:
7076                 // if Rt == '1111' then SEE PLI;
7077                 // if Rn == '1111' then SEE LDRSB (literal);
7078                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7079                 t = Bits32 (opcode, 15, 12);
7080                 n = Bits32 (opcode, 19, 16);
7081                 imm32 = Bits32 (opcode, 11, 0);
7082 
7083                 // index = TRUE; add = TRUE; wback = FALSE;
7084                 index = true;
7085                 add = true;
7086                 wback = false;
7087 
7088                 // if t == 13 then UNPREDICTABLE;
7089                 if (t == 13)
7090                     return false;
7091 
7092                 break;
7093 
7094             case eEncodingT2:
7095                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
7096                 // if Rn == '1111' then SEE LDRSB (literal);
7097                 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
7098                 // if P == '0' && W == '0' then UNDEFINED;
7099                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7100                     return false;
7101 
7102                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7103                 t = Bits32 (opcode, 15, 12);
7104                 n = Bits32 (opcode, 19, 16);
7105                 imm32 = Bits32 (opcode, 7, 0);
7106 
7107                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7108                 index = BitIsSet (opcode, 10);
7109                 add = BitIsSet (opcode, 9);
7110                 wback = BitIsSet (opcode, 8);
7111 
7112                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7113                   if (((t == 13) || ((t == 15)
7114                                      && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8))))
7115                       || (wback && (n == t)))
7116                     return false;
7117 
7118                 break;
7119 
7120             case eEncodingA1:
7121             {
7122                 // if Rn == '1111' then SEE LDRSB (literal);
7123                 // if P == '0' && W == '1' then SEE LDRSBT;
7124                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7125                 t = Bits32 (opcode, 15, 12);
7126                 n = Bits32 (opcode, 19, 16);
7127 
7128                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7129                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7130                 imm32 = (imm4H << 4) | imm4L;
7131 
7132                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7133                 index = BitIsSet (opcode, 24);
7134                 add = BitIsSet (opcode, 23);
7135                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
7136 
7137                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7138                 if ((t == 15) || (wback && (n == t)))
7139                     return false;
7140 
7141                 break;
7142             }
7143 
7144             default:
7145                 return false;
7146         }
7147 
7148         uint64_t Rn = ReadCoreReg (n, &success);
7149         if (!success)
7150             return false;
7151 
7152         addr_t offset_addr;
7153         addr_t address;
7154 
7155         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7156         if (add)
7157             offset_addr = Rn + imm32;
7158         else
7159             offset_addr = Rn - imm32;
7160 
7161         // address = if index then offset_addr else R[n];
7162         if (index)
7163             address = offset_addr;
7164         else
7165             address = Rn;
7166 
7167         // R[t] = SignExtend(MemU[address,1], 32);
7168         RegisterInfo base_reg;
7169         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7170 
7171         EmulateInstruction::Context context;
7172         context.type = eContextRegisterLoad;
7173         context.SetRegisterPlusOffset (base_reg, address - Rn);
7174 
7175         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7176         if (!success)
7177             return false;
7178 
7179         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7180         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7181             return false;
7182 
7183         // if wback then R[n] = offset_addr;
7184         if (wback)
7185         {
7186             context.type = eContextAdjustBaseRegister;
7187             context.SetAddress (offset_addr);
7188             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7189                 return false;
7190         }
7191     }
7192 
7193     return true;
7194 }
7195 
7196 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
7197 // sign-extends it to form a 32-bit word, and writes tit to a register.
7198 bool
7199 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding)
7200 {
7201 #if 0
7202     if ConditionPassed() then
7203         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7204         base = Align(PC,4);
7205         address = if add then (base + imm32) else (base - imm32);
7206         R[t] = SignExtend(MemU[address,1], 32);
7207 #endif
7208 
7209     bool success = false;
7210 
7211     if (ConditionPassed(opcode))
7212     {
7213         uint32_t t;
7214         uint32_t imm32;
7215         bool add;
7216 
7217         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7218         switch (encoding)
7219         {
7220             case eEncodingT1:
7221                 // if Rt == '1111' then SEE PLI;
7222                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7223                 t = Bits32 (opcode, 15, 12);
7224                 imm32 = Bits32 (opcode, 11, 0);
7225                 add = BitIsSet (opcode, 23);
7226 
7227                 // if t == 13 then UNPREDICTABLE;
7228                 if (t == 13)
7229                     return false;
7230 
7231                 break;
7232 
7233             case eEncodingA1:
7234             {
7235                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7236                 t = Bits32 (opcode, 15, 12);
7237                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7238                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7239                 imm32 = (imm4H << 4) | imm4L;
7240                 add = BitIsSet (opcode, 23);
7241 
7242                 // if t == 15 then UNPREDICTABLE;
7243                 if (t == 15)
7244                     return false;
7245 
7246                 break;
7247             }
7248 
7249             default:
7250                 return false;
7251         }
7252 
7253         // base = Align(PC,4);
7254         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7255         if (!success)
7256             return false;
7257         uint64_t base = AlignPC (pc_value);
7258 
7259         // address = if add then (base + imm32) else (base - imm32);
7260         addr_t address;
7261         if (add)
7262             address = base + imm32;
7263         else
7264             address = base - imm32;
7265 
7266         // R[t] = SignExtend(MemU[address,1], 32);
7267         RegisterInfo base_reg;
7268         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7269 
7270         EmulateInstruction::Context context;
7271         context.type = eContextRegisterLoad;
7272         context.SetRegisterPlusOffset (base_reg, address - base);
7273 
7274         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7275         if (!success)
7276             return false;
7277 
7278         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7279         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7280             return false;
7281     }
7282     return true;
7283 }
7284 
7285 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from
7286 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7287 // shifted left by 0, 1, 2, or 3 bits.
7288 bool
7289 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding)
7290 {
7291 #if 0
7292     if ConditionPassed() then
7293         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7294         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7295         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7296         address = if index then offset_addr else R[n];
7297         R[t] = SignExtend(MemU[address,1], 32);
7298         if wback then R[n] = offset_addr;
7299 #endif
7300 
7301     bool success = false;
7302 
7303     if (ConditionPassed(opcode))
7304     {
7305         uint32_t t;
7306         uint32_t n;
7307         uint32_t m;
7308         bool index;
7309         bool add;
7310         bool wback;
7311         ARM_ShifterType shift_t;
7312         uint32_t shift_n;
7313 
7314         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7315         switch (encoding)
7316         {
7317             case eEncodingT1:
7318                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7319                 t = Bits32 (opcode, 2, 0);
7320                 n = Bits32 (opcode, 5, 3);
7321                 m = Bits32 (opcode, 8, 6);
7322 
7323                 // index = TRUE; add = TRUE; wback = FALSE;
7324                 index = true;
7325                 add = true;
7326                 wback = false;
7327 
7328                 // (shift_t, shift_n) = (SRType_LSL, 0);
7329                 shift_t = SRType_LSL;
7330                 shift_n = 0;
7331 
7332                 break;
7333 
7334             case eEncodingT2:
7335                 // if Rt == '1111' then SEE PLI;
7336                 // if Rn == '1111' then SEE LDRSB (literal);
7337                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7338                 t = Bits32 (opcode, 15, 12);
7339                 n = Bits32 (opcode, 19, 16);
7340                 m = Bits32 (opcode, 3, 0);
7341 
7342                 // index = TRUE; add = TRUE; wback = FALSE;
7343                 index = true;
7344                 add = true;
7345                 wback = false;
7346 
7347                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7348                 shift_t = SRType_LSL;
7349                 shift_n = Bits32 (opcode, 5, 4);
7350 
7351                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7352                 if ((t == 13) || BadReg (m))
7353                     return false;
7354                 break;
7355 
7356             case eEncodingA1:
7357                 // if P == '0' && W == '1' then SEE LDRSBT;
7358                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7359                 t = Bits32 (opcode, 15, 12);
7360                 n = Bits32 (opcode, 19, 16);
7361                 m = Bits32 (opcode, 3, 0);
7362 
7363                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7364                 index = BitIsSet (opcode, 24);
7365                 add = BitIsSet (opcode, 23);
7366                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7367 
7368                 // (shift_t, shift_n) = (SRType_LSL, 0);
7369                 shift_t = SRType_LSL;
7370                 shift_n = 0;
7371 
7372                 // if t == 15 || m == 15 then UNPREDICTABLE;
7373                 if ((t == 15) || (m == 15))
7374                     return false;
7375 
7376                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7377                 if (wback && ((n == 15) || (n == t)))
7378                     return false;
7379                 break;
7380 
7381             default:
7382                 return false;
7383         }
7384 
7385         uint64_t Rm =  ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7386         if (!success)
7387             return false;
7388 
7389         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7390         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7391         if (!success)
7392             return false;
7393 
7394         addr_t offset_addr;
7395         addr_t address;
7396 
7397         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7398         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7399         if (!success)
7400             return false;
7401 
7402         if (add)
7403             offset_addr = Rn + offset;
7404         else
7405             offset_addr = Rn - offset;
7406 
7407         // address = if index then offset_addr else R[n];
7408         if (index)
7409             address = offset_addr;
7410         else
7411             address = Rn;
7412 
7413         // R[t] = SignExtend(MemU[address,1], 32);
7414         RegisterInfo base_reg;
7415         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7416         RegisterInfo offset_reg;
7417         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7418 
7419         EmulateInstruction::Context context;
7420         context.type = eContextRegisterLoad;
7421         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7422 
7423         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7424         if (!success)
7425             return false;
7426 
7427         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7428         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7429             return false;
7430 
7431         // if wback then R[n] = offset_addr;
7432         if (wback)
7433         {
7434             context.type = eContextAdjustBaseRegister;
7435             context.SetAddress (offset_addr);
7436             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7437                 return false;
7438         }
7439     }
7440     return true;
7441 }
7442 
7443 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from
7444 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed, or
7445 // pre-indexed addressing.
7446 bool
7447 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding)
7448 {
7449 #if 0
7450     if ConditionPassed() then
7451         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7452         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7453         address = if index then offset_addr else R[n];
7454         data = MemU[address,2];
7455         if wback then R[n] = offset_addr;
7456         if UnalignedSupport() || address<0> = '0' then
7457             R[t] = SignExtend(data, 32);
7458         else // Can only apply before ARMv7
7459             R[t] = bits(32) UNKNOWN;
7460 #endif
7461 
7462     bool success = false;
7463 
7464     if (ConditionPassed(opcode))
7465     {
7466         uint32_t t;
7467         uint32_t n;
7468         uint32_t imm32;
7469         bool index;
7470         bool add;
7471         bool wback;
7472 
7473         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7474         switch (encoding)
7475         {
7476             case eEncodingT1:
7477                 // if Rn == '1111' then SEE LDRSH (literal);
7478                 // if Rt == '1111' then SEE "Unallocated memory hints";
7479                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7480                 t = Bits32 (opcode, 15, 12);
7481                 n = Bits32 (opcode, 19, 16);
7482                 imm32 = Bits32 (opcode, 11, 0);
7483 
7484                 // index = TRUE; add = TRUE; wback = FALSE;
7485                 index = true;
7486                 add = true;
7487                 wback = false;
7488 
7489                 // if t == 13 then UNPREDICTABLE;
7490                 if (t == 13)
7491                     return false;
7492 
7493                 break;
7494 
7495             case eEncodingT2:
7496                 // if Rn == '1111' then SEE LDRSH (literal);
7497                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
7498                 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7499                 // if P == '0' && W == '0' then UNDEFINED;
7500                   if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7501                   return false;
7502 
7503                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7504                 t = Bits32 (opcode, 15, 12);
7505                 n = Bits32 (opcode, 19, 16);
7506                 imm32 = Bits32 (opcode, 7, 0);
7507 
7508                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7509                 index = BitIsSet (opcode, 10);
7510                 add = BitIsSet (opcode, 9);
7511                 wback = BitIsSet (opcode, 8);
7512 
7513                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7514                 if (BadReg (t) || (wback && (n == t)))
7515                     return false;
7516 
7517                 break;
7518 
7519             case eEncodingA1:
7520             {
7521                 // if Rn == '1111' then SEE LDRSH (literal);
7522                 // if P == '0' && W == '1' then SEE LDRSHT;
7523                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7524                 t = Bits32 (opcode, 15, 12);
7525                 n = Bits32 (opcode, 19, 16);
7526                 uint32_t imm4H = Bits32 (opcode, 11,8);
7527                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7528                 imm32 = (imm4H << 4) | imm4L;
7529 
7530                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7531                 index = BitIsSet (opcode, 24);
7532                 add = BitIsSet (opcode, 23);
7533                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7534 
7535                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7536                 if ((t == 15) || (wback && (n == t)))
7537                     return false;
7538 
7539                 break;
7540             }
7541 
7542             default:
7543                 return false;
7544         }
7545 
7546         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7547         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7548         if (!success)
7549             return false;
7550 
7551         addr_t offset_addr;
7552         if (add)
7553             offset_addr = Rn + imm32;
7554         else
7555             offset_addr = Rn - imm32;
7556 
7557         // address = if index then offset_addr else R[n];
7558         addr_t address;
7559         if (index)
7560             address = offset_addr;
7561         else
7562             address = Rn;
7563 
7564         // data = MemU[address,2];
7565         RegisterInfo base_reg;
7566         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7567 
7568         EmulateInstruction::Context context;
7569         context.type = eContextRegisterLoad;
7570         context.SetRegisterPlusOffset (base_reg, address - Rn);
7571 
7572         uint64_t data = MemURead (context, address, 2, 0, &success);
7573         if (!success)
7574             return false;
7575 
7576         // if wback then R[n] = offset_addr;
7577         if (wback)
7578         {
7579             context.type = eContextAdjustBaseRegister;
7580             context.SetAddress (offset_addr);
7581             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7582                 return false;
7583         }
7584 
7585         // if UnalignedSupport() || address<0> = '0' then
7586         if (UnalignedSupport() || BitIsClear (address, 0))
7587         {
7588             // R[t] = SignExtend(data, 32);
7589             int64_t signed_data = llvm::SignExtend64<16>(data);
7590             context.type = eContextRegisterLoad;
7591             context.SetRegisterPlusOffset (base_reg, address - Rn);
7592             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7593                 return false;
7594         }
7595         else // Can only apply before ARMv7
7596         {
7597             // R[t] = bits(32) UNKNOWN;
7598             WriteBits32Unknown (t);
7599         }
7600     }
7601     return true;
7602 }
7603 
7604 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory,
7605 // sign-extends it to from a 32-bit word, and writes it to a register.
7606 bool
7607 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding)
7608 {
7609 #if 0
7610     if ConditionPassed() then
7611         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7612         base = Align(PC,4);
7613         address = if add then (base + imm32) else (base - imm32);
7614         data = MemU[address,2];
7615         if UnalignedSupport() || address<0> = '0' then
7616             R[t] = SignExtend(data, 32);
7617         else // Can only apply before ARMv7
7618             R[t] = bits(32) UNKNOWN;
7619 #endif
7620 
7621     bool success = false;
7622 
7623     if (ConditionPassed(opcode))
7624     {
7625         uint32_t t;
7626         uint32_t imm32;
7627         bool add;
7628 
7629         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7630         switch (encoding)
7631         {
7632             case eEncodingT1:
7633                 // if Rt == '1111' then SEE "Unallocated memory hints";
7634                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7635                 t = Bits32  (opcode, 15, 12);
7636                 imm32 = Bits32 (opcode, 11, 0);
7637                 add = BitIsSet (opcode, 23);
7638 
7639                 // if t == 13 then UNPREDICTABLE;
7640                 if (t == 13)
7641                     return false;
7642 
7643                 break;
7644 
7645             case eEncodingA1:
7646             {
7647                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7648                 t = Bits32 (opcode, 15, 12);
7649                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7650                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7651                 imm32 = (imm4H << 4) | imm4L;
7652                 add = BitIsSet (opcode, 23);
7653 
7654                 // if t == 15 then UNPREDICTABLE;
7655                 if (t == 15)
7656                     return false;
7657 
7658                 break;
7659             }
7660             default:
7661                 return false;
7662         }
7663 
7664         // base = Align(PC,4);
7665         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7666         if (!success)
7667             return false;
7668 
7669         uint64_t base = AlignPC (pc_value);
7670 
7671         addr_t address;
7672         // address = if add then (base + imm32) else (base - imm32);
7673         if (add)
7674             address = base + imm32;
7675         else
7676             address = base - imm32;
7677 
7678         // data = MemU[address,2];
7679         RegisterInfo base_reg;
7680         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7681 
7682         EmulateInstruction::Context context;
7683         context.type = eContextRegisterLoad;
7684         context.SetRegisterPlusOffset (base_reg, imm32);
7685 
7686         uint64_t data = MemURead (context, address, 2, 0, &success);
7687         if (!success)
7688             return false;
7689 
7690         // if UnalignedSupport() || address<0> = '0' then
7691         if (UnalignedSupport() || BitIsClear (address, 0))
7692         {
7693             // R[t] = SignExtend(data, 32);
7694             int64_t signed_data = llvm::SignExtend64<16>(data);
7695             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7696                 return false;
7697         }
7698         else // Can only apply before ARMv7
7699         {
7700             // R[t] = bits(32) UNKNOWN;
7701             WriteBits32Unknown (t);
7702         }
7703     }
7704     return true;
7705 }
7706 
7707 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword
7708 // from memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7709 // shifted left by 0, 1, 2, or 3 bits.
7710 bool
7711 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding)
7712 {
7713 #if 0
7714     if ConditionPassed() then
7715         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7716         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7717         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7718         address = if index then offset_addr else R[n];
7719         data = MemU[address,2];
7720         if wback then R[n] = offset_addr;
7721         if UnalignedSupport() || address<0> = '0' then
7722             R[t] = SignExtend(data, 32);
7723         else // Can only apply before ARMv7
7724             R[t] = bits(32) UNKNOWN;
7725 #endif
7726 
7727     bool success = false;
7728 
7729     if (ConditionPassed(opcode))
7730     {
7731         uint32_t t;
7732         uint32_t n;
7733         uint32_t m;
7734         bool index;
7735         bool add;
7736         bool wback;
7737         ARM_ShifterType shift_t;
7738         uint32_t shift_n;
7739 
7740         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7741         switch (encoding)
7742         {
7743             case eEncodingT1:
7744                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
7745                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7746                 t = Bits32 (opcode, 2, 0);
7747                 n = Bits32 (opcode, 5, 3);
7748                 m = Bits32 (opcode, 8, 6);
7749 
7750                 // index = TRUE; add = TRUE; wback = FALSE;
7751                 index = true;
7752                 add = true;
7753                 wback = false;
7754 
7755                 // (shift_t, shift_n) = (SRType_LSL, 0);
7756                 shift_t = SRType_LSL;
7757                 shift_n = 0;
7758 
7759                 break;
7760 
7761             case eEncodingT2:
7762                 // if Rn == '1111' then SEE LDRSH (literal);
7763                 // if Rt == '1111' then SEE "Unallocated memory hints";
7764                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7765                 t = Bits32 (opcode, 15, 12);
7766                 n = Bits32 (opcode, 19, 16);
7767                 m = Bits32 (opcode, 3, 0);
7768 
7769                 // index = TRUE; add = TRUE; wback = FALSE;
7770                 index = true;
7771                 add = true;
7772                 wback = false;
7773 
7774                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7775                 shift_t = SRType_LSL;
7776                 shift_n = Bits32 (opcode, 5, 4);
7777 
7778                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7779                 if ((t == 13) || BadReg (m))
7780                     return false;
7781 
7782                 break;
7783 
7784             case eEncodingA1:
7785                 // if P == '0' && W == '1' then SEE LDRSHT;
7786                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7787                 t = Bits32 (opcode, 15, 12);
7788                 n = Bits32 (opcode, 19, 16);
7789                 m = Bits32 (opcode, 3, 0);
7790 
7791                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7792                 index = BitIsSet (opcode, 24);
7793                 add = BitIsSet (opcode, 23);
7794                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7795 
7796                 // (shift_t, shift_n) = (SRType_LSL, 0);
7797                 shift_t = SRType_LSL;
7798                 shift_n = 0;
7799 
7800                 // if t == 15 || m == 15 then UNPREDICTABLE;
7801                 if ((t == 15) || (m == 15))
7802                     return false;
7803 
7804                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7805                 if (wback && ((n == 15) || (n == t)))
7806                     return false;
7807 
7808                 break;
7809 
7810             default:
7811                 return false;
7812         }
7813 
7814         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7815         if (!success)
7816             return false;
7817 
7818         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7819         if (!success)
7820             return false;
7821 
7822         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7823         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7824         if (!success)
7825             return false;
7826 
7827         addr_t offset_addr;
7828         addr_t address;
7829 
7830         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7831         if (add)
7832             offset_addr = Rn + offset;
7833         else
7834             offset_addr = Rn - offset;
7835 
7836         // address = if index then offset_addr else R[n];
7837         if (index)
7838             address = offset_addr;
7839         else
7840             address = Rn;
7841 
7842         // data = MemU[address,2];
7843         RegisterInfo base_reg;
7844         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7845 
7846         RegisterInfo offset_reg;
7847         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7848 
7849         EmulateInstruction::Context context;
7850         context.type = eContextRegisterLoad;
7851         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7852 
7853         uint64_t data = MemURead (context, address, 2, 0, &success);
7854         if (!success)
7855             return false;
7856 
7857         // if wback then R[n] = offset_addr;
7858         if (wback)
7859         {
7860             context.type = eContextAdjustBaseRegister;
7861             context.SetAddress (offset_addr);
7862             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7863                 return false;
7864         }
7865 
7866         // if UnalignedSupport() || address<0> = '0' then
7867         if (UnalignedSupport() || BitIsClear (address, 0))
7868         {
7869             // R[t] = SignExtend(data, 32);
7870             context.type = eContextRegisterLoad;
7871             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7872 
7873             int64_t signed_data = llvm::SignExtend64<16>(data);
7874             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7875                 return false;
7876         }
7877         else // Can only apply before ARMv7
7878         {
7879             // R[t] = bits(32) UNKNOWN;
7880             WriteBits32Unknown (t);
7881         }
7882     }
7883     return true;
7884 }
7885 
7886 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7887 // register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7888 bool
7889 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding)
7890 {
7891 #if 0
7892     if ConditionPassed() then
7893         EncodingSpecificOperations();
7894         rotated = ROR(R[m], rotation);
7895         R[d] = SignExtend(rotated<7:0>, 32);
7896 #endif
7897 
7898     bool success = false;
7899 
7900     if (ConditionPassed(opcode))
7901     {
7902         uint32_t d;
7903         uint32_t m;
7904         uint32_t rotation;
7905 
7906         // EncodingSpecificOperations();
7907         switch (encoding)
7908         {
7909             case eEncodingT1:
7910                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7911                 d = Bits32 (opcode, 2, 0);
7912                 m = Bits32 (opcode, 5, 3);
7913                 rotation = 0;
7914 
7915                 break;
7916 
7917             case eEncodingT2:
7918                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7919                 d = Bits32 (opcode, 11, 8);
7920                 m = Bits32 (opcode, 3, 0);
7921                 rotation = Bits32 (opcode, 5, 4) << 3;
7922 
7923                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7924                 if (BadReg (d) || BadReg (m))
7925                     return false;
7926 
7927                 break;
7928 
7929             case eEncodingA1:
7930                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7931                 d = Bits32 (opcode, 15, 12);
7932                 m = Bits32 (opcode, 3, 0);
7933                 rotation = Bits32 (opcode, 11, 10) << 3;
7934 
7935                 // if d == 15 || m == 15 then UNPREDICTABLE;
7936                 if ((d == 15) || (m == 15))
7937                     return false;
7938 
7939                 break;
7940 
7941             default:
7942                 return false;
7943         }
7944 
7945         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7946         if (!success)
7947             return false;
7948 
7949         // rotated = ROR(R[m], rotation);
7950         uint64_t rotated = ROR (Rm, rotation, &success);
7951         if (!success)
7952             return false;
7953 
7954         // R[d] = SignExtend(rotated<7:0>, 32);
7955         int64_t data = llvm::SignExtend64<8>(rotated);
7956 
7957         RegisterInfo source_reg;
7958         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7959 
7960         EmulateInstruction::Context context;
7961         context.type = eContextRegisterLoad;
7962         context.SetRegister (source_reg);
7963 
7964         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7965             return false;
7966     }
7967     return true;
7968 }
7969 
7970 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7971 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7972 bool
7973 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding)
7974 {
7975 #if 0
7976     if ConditionPassed() then
7977         EncodingSpecificOperations();
7978         rotated = ROR(R[m], rotation);
7979         R[d] = SignExtend(rotated<15:0>, 32);
7980 #endif
7981 
7982     bool success = false;
7983 
7984     if (ConditionPassed(opcode))
7985     {
7986         uint32_t d;
7987         uint32_t m;
7988         uint32_t rotation;
7989 
7990         // EncodingSpecificOperations();
7991         switch (encoding)
7992         {
7993             case eEncodingT1:
7994                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7995                 d = Bits32 (opcode, 2, 0);
7996                 m = Bits32 (opcode, 5, 3);
7997                 rotation = 0;
7998 
7999                 break;
8000 
8001             case eEncodingT2:
8002                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8003                 d = Bits32 (opcode, 11, 8);
8004                 m = Bits32 (opcode, 3, 0);
8005                 rotation = Bits32 (opcode, 5, 4) << 3;
8006 
8007                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8008                 if (BadReg (d) || BadReg (m))
8009                     return false;
8010 
8011                 break;
8012 
8013             case eEncodingA1:
8014                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8015                 d = Bits32 (opcode, 15, 12);
8016                 m = Bits32 (opcode, 3, 0);
8017                 rotation = Bits32 (opcode, 11, 10) << 3;
8018 
8019                 // if d == 15 || m == 15 then UNPREDICTABLE;
8020                 if ((d == 15) || (m == 15))
8021                     return false;
8022 
8023                 break;
8024 
8025             default:
8026                 return false;
8027         }
8028 
8029         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8030         if (!success)
8031             return false;
8032 
8033         // rotated = ROR(R[m], rotation);
8034         uint64_t rotated = ROR (Rm, rotation, &success);
8035         if (!success)
8036             return false;
8037 
8038         // R[d] = SignExtend(rotated<15:0>, 32);
8039         RegisterInfo source_reg;
8040         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8041 
8042         EmulateInstruction::Context context;
8043         context.type = eContextRegisterLoad;
8044         context.SetRegister (source_reg);
8045 
8046         int64_t data = llvm::SignExtend64<16> (rotated);
8047         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
8048             return false;
8049     }
8050 
8051     return true;
8052 }
8053 
8054 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination
8055 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
8056 bool
8057 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding)
8058 {
8059 #if 0
8060     if ConditionPassed() then
8061         EncodingSpecificOperations();
8062         rotated = ROR(R[m], rotation);
8063         R[d] = ZeroExtend(rotated<7:0>, 32);
8064 #endif
8065 
8066     bool success = false;
8067 
8068     if (ConditionPassed(opcode))
8069     {
8070         uint32_t d;
8071         uint32_t m;
8072         uint32_t rotation;
8073 
8074         // EncodingSpecificOperations();
8075         switch (encoding)
8076         {
8077             case eEncodingT1:
8078                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8079                 d = Bits32 (opcode, 2, 0);
8080                 m = Bits32 (opcode, 5, 3);
8081                 rotation = 0;
8082 
8083                 break;
8084 
8085             case eEncodingT2:
8086                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8087                 d = Bits32 (opcode, 11, 8);
8088                 m = Bits32 (opcode, 3, 0);
8089                   rotation = Bits32 (opcode, 5, 4) << 3;
8090 
8091                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8092                 if (BadReg (d) || BadReg (m))
8093                   return false;
8094 
8095                 break;
8096 
8097             case eEncodingA1:
8098                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8099                 d = Bits32 (opcode, 15, 12);
8100                 m = Bits32 (opcode, 3, 0);
8101                 rotation = Bits32 (opcode, 11, 10) << 3;
8102 
8103                 // if d == 15 || m == 15 then UNPREDICTABLE;
8104                 if ((d == 15) || (m == 15))
8105                     return false;
8106 
8107                 break;
8108 
8109             default:
8110                 return false;
8111         }
8112 
8113         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8114         if (!success)
8115             return false;
8116 
8117         // rotated = ROR(R[m], rotation);
8118         uint64_t rotated = ROR (Rm, rotation, &success);
8119         if (!success)
8120             return false;
8121 
8122         // R[d] = ZeroExtend(rotated<7:0>, 32);
8123         RegisterInfo source_reg;
8124         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8125 
8126         EmulateInstruction::Context context;
8127         context.type = eContextRegisterLoad;
8128         context.SetRegister (source_reg);
8129 
8130         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0)))
8131             return false;
8132     }
8133     return true;
8134 }
8135 
8136 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination
8137 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
8138 bool
8139 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding)
8140 {
8141 #if 0
8142     if ConditionPassed() then
8143         EncodingSpecificOperations();
8144         rotated = ROR(R[m], rotation);
8145         R[d] = ZeroExtend(rotated<15:0>, 32);
8146 #endif
8147 
8148     bool success = false;
8149 
8150     if (ConditionPassed(opcode))
8151     {
8152         uint32_t d;
8153         uint32_t m;
8154         uint32_t rotation;
8155 
8156         switch (encoding)
8157         {
8158             case eEncodingT1:
8159                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8160                 d = Bits32 (opcode, 2, 0);
8161                 m = Bits32 (opcode, 5, 3);
8162                 rotation = 0;
8163 
8164                 break;
8165 
8166             case eEncodingT2:
8167                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8168                 d = Bits32 (opcode, 11, 8);
8169                 m = Bits32 (opcode, 3, 0);
8170                 rotation = Bits32 (opcode, 5, 4) << 3;
8171 
8172                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8173                 if (BadReg (d) || BadReg (m))
8174                   return false;
8175 
8176                 break;
8177 
8178             case eEncodingA1:
8179                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8180                 d = Bits32 (opcode, 15, 12);
8181                 m = Bits32 (opcode, 3, 0);
8182                 rotation = Bits32 (opcode, 11, 10) << 3;
8183 
8184                 // if d == 15 || m == 15 then UNPREDICTABLE;
8185                 if ((d == 15) || (m == 15))
8186                     return false;
8187 
8188                 break;
8189 
8190             default:
8191                 return false;
8192         }
8193 
8194         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8195         if (!success)
8196             return false;
8197 
8198         // rotated = ROR(R[m], rotation);
8199         uint64_t rotated = ROR (Rm, rotation, &success);
8200         if (!success)
8201             return false;
8202 
8203         // R[d] = ZeroExtend(rotated<15:0>, 32);
8204         RegisterInfo source_reg;
8205         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8206 
8207         EmulateInstruction::Context context;
8208         context.type = eContextRegisterLoad;
8209         context.SetRegister (source_reg);
8210 
8211         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0)))
8212             return false;
8213     }
8214     return true;
8215 }
8216 
8217 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following
8218 // word respectively.
8219 bool
8220 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding)
8221 {
8222 #if 0
8223     if ConditionPassed() then
8224         EncodingSpecificOperations();
8225         if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8226             UNPREDICTABLE;
8227         else
8228             address = if increment then R[n] else R[n]-8;
8229             if wordhigher then address = address+4;
8230             CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8231             BranchWritePC(MemA[address,4]);
8232             if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8233 #endif
8234 
8235     bool success = false;
8236 
8237     if (ConditionPassed(opcode))
8238     {
8239         uint32_t n;
8240         bool wback;
8241         bool increment;
8242         bool wordhigher;
8243 
8244         // EncodingSpecificOperations();
8245         switch (encoding)
8246         {
8247             case eEncodingT1:
8248                 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE;
8249                 n = Bits32 (opcode, 19, 16);
8250                 wback = BitIsSet (opcode, 21);
8251                 increment = false;
8252                 wordhigher = false;
8253 
8254                 // if n == 15 then UNPREDICTABLE;
8255                 if (n == 15)
8256                     return false;
8257 
8258                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8259                 if (InITBlock() && !LastInITBlock())
8260                     return false;
8261 
8262                 break;
8263 
8264             case eEncodingT2:
8265                 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8266                 n = Bits32 (opcode, 19, 16);
8267                 wback = BitIsSet (opcode, 21);
8268                 increment = true;
8269                 wordhigher = false;
8270 
8271                 // if n == 15 then UNPREDICTABLE;
8272                 if (n == 15)
8273                     return false;
8274 
8275                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8276                 if (InITBlock() && !LastInITBlock())
8277                     return false;
8278 
8279                 break;
8280 
8281             case eEncodingA1:
8282                 // n = UInt(Rn);
8283                 n = Bits32 (opcode, 19, 16);
8284 
8285                 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8286                 wback = BitIsSet (opcode, 21);
8287                 increment = BitIsSet (opcode, 23);
8288                 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23));
8289 
8290                 // if n == 15 then UNPREDICTABLE;
8291                 if (n == 15)
8292                     return false;
8293 
8294                 break;
8295 
8296             default:
8297                 return false;
8298         }
8299 
8300         // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8301         if (!CurrentModeIsPrivileged ())
8302             // UNPREDICTABLE;
8303             return false;
8304         else
8305         {
8306             uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8307             if (!success)
8308                 return false;
8309 
8310             addr_t address;
8311             // address = if increment then R[n] else R[n]-8;
8312             if (increment)
8313                 address = Rn;
8314             else
8315                 address = Rn - 8;
8316 
8317             // if wordhigher then address = address+4;
8318             if (wordhigher)
8319                 address = address + 4;
8320 
8321             // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8322             RegisterInfo base_reg;
8323             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8324 
8325             EmulateInstruction::Context context;
8326             context.type = eContextReturnFromException;
8327             context.SetRegisterPlusOffset (base_reg, address - Rn);
8328 
8329             uint64_t data = MemARead (context, address + 4, 4, 0, &success);
8330             if (!success)
8331                 return false;
8332 
8333             CPSRWriteByInstr (data, 15, true);
8334 
8335             // BranchWritePC(MemA[address,4]);
8336             uint64_t data2 = MemARead (context, address, 4, 0, &success);
8337             if (!success)
8338                 return false;
8339 
8340             BranchWritePC (context, data2);
8341 
8342             // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8343             if (wback)
8344             {
8345                 context.type = eContextAdjustBaseRegister;
8346                 if (increment)
8347                 {
8348                     context.SetOffset (8);
8349                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8))
8350                         return false;
8351                 }
8352                 else
8353                 {
8354                     context.SetOffset (-8);
8355                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8))
8356                         return false;
8357                 }
8358             } // if wback
8359         }
8360     } // if ConditionPassed()
8361     return true;
8362 }
8363 
8364 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
8365 // and writes the result to the destination register.  It can optionally update the condition flags based on
8366 // the result.
8367 bool
8368 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding)
8369 {
8370 #if 0
8371     // ARM pseudo code...
8372     if ConditionPassed() then
8373         EncodingSpecificOperations();
8374         result = R[n] EOR imm32;
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;
8391         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8392         bool setflags;
8393         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8394         switch (encoding)
8395         {
8396         case eEncodingT1:
8397             Rd = Bits32(opcode, 11, 8);
8398             Rn = Bits32(opcode, 19, 16);
8399             setflags = BitIsSet(opcode, 20);
8400             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8401             // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8402             if (Rd == 15 && setflags)
8403                 return EmulateTEQImm (opcode, eEncodingT1);
8404             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8405                 return false;
8406             break;
8407         case eEncodingA1:
8408             Rd = Bits32(opcode, 15, 12);
8409             Rn = Bits32(opcode, 19, 16);
8410             setflags = BitIsSet(opcode, 20);
8411             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8412 
8413             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8414             if (Rd == 15 && setflags)
8415                 return EmulateSUBSPcLrEtc (opcode, encoding);
8416             break;
8417         default:
8418             return false;
8419         }
8420 
8421         // Read the first operand.
8422         uint32_t val1 = ReadCoreReg(Rn, &success);
8423         if (!success)
8424             return false;
8425 
8426         uint32_t result = val1 ^ imm32;
8427 
8428         EmulateInstruction::Context context;
8429         context.type = EmulateInstruction::eContextImmediate;
8430         context.SetNoArgs ();
8431 
8432         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8433             return false;
8434     }
8435     return true;
8436 }
8437 
8438 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an
8439 // optionally-shifted register value, and writes the result to the destination register.
8440 // It can optionally update the condition flags based on the result.
8441 bool
8442 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding)
8443 {
8444 #if 0
8445     // ARM pseudo code...
8446     if ConditionPassed() then
8447         EncodingSpecificOperations();
8448         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8449         result = R[n] EOR shifted;
8450         if d == 15 then         // Can only occur for ARM encoding
8451             ALUWritePC(result); // setflags is always FALSE here
8452         else
8453             R[d] = result;
8454             if setflags then
8455                 APSR.N = result<31>;
8456                 APSR.Z = IsZeroBit(result);
8457                 APSR.C = carry;
8458                 // APSR.V unchanged
8459 #endif
8460 
8461     bool success = false;
8462 
8463     if (ConditionPassed(opcode))
8464     {
8465         uint32_t Rd, Rn, Rm;
8466         ARM_ShifterType shift_t;
8467         uint32_t shift_n; // the shift applied to the value read from Rm
8468         bool setflags;
8469         uint32_t carry;
8470         switch (encoding)
8471         {
8472         case eEncodingT1:
8473             Rd = Rn = Bits32(opcode, 2, 0);
8474             Rm = Bits32(opcode, 5, 3);
8475             setflags = !InITBlock();
8476             shift_t = SRType_LSL;
8477             shift_n = 0;
8478             break;
8479         case eEncodingT2:
8480             Rd = Bits32(opcode, 11, 8);
8481             Rn = Bits32(opcode, 19, 16);
8482             Rm = Bits32(opcode, 3, 0);
8483             setflags = BitIsSet(opcode, 20);
8484             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8485             // if Rd == '1111' && S == '1' then SEE TEQ (register);
8486             if (Rd == 15 && setflags)
8487                 return EmulateTEQReg (opcode, eEncodingT1);
8488             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8489                 return false;
8490             break;
8491         case eEncodingA1:
8492             Rd = Bits32(opcode, 15, 12);
8493             Rn = Bits32(opcode, 19, 16);
8494             Rm = Bits32(opcode, 3, 0);
8495             setflags = BitIsSet(opcode, 20);
8496             shift_n = DecodeImmShiftARM(opcode, shift_t);
8497 
8498             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8499             if (Rd == 15 && setflags)
8500                 return EmulateSUBSPcLrEtc (opcode, encoding);
8501             break;
8502         default:
8503             return false;
8504         }
8505 
8506         // Read the first operand.
8507         uint32_t val1 = ReadCoreReg(Rn, &success);
8508         if (!success)
8509             return false;
8510 
8511         // Read the second operand.
8512         uint32_t val2 = ReadCoreReg(Rm, &success);
8513         if (!success)
8514             return false;
8515 
8516         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8517         if (!success)
8518             return false;
8519         uint32_t result = val1 ^ shifted;
8520 
8521         EmulateInstruction::Context context;
8522         context.type = EmulateInstruction::eContextImmediate;
8523         context.SetNoArgs ();
8524 
8525         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8526             return false;
8527     }
8528     return true;
8529 }
8530 
8531 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and
8532 // writes the result to the destination register.  It can optionally update the condition flags based
8533 // on the result.
8534 bool
8535 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding)
8536 {
8537 #if 0
8538     // ARM pseudo code...
8539     if ConditionPassed() then
8540         EncodingSpecificOperations();
8541         result = R[n] OR imm32;
8542         if d == 15 then         // Can only occur for ARM encoding
8543             ALUWritePC(result); // setflags is always FALSE here
8544         else
8545             R[d] = result;
8546             if setflags then
8547                 APSR.N = result<31>;
8548                 APSR.Z = IsZeroBit(result);
8549                 APSR.C = carry;
8550                 // APSR.V unchanged
8551 #endif
8552 
8553     bool success = false;
8554 
8555     if (ConditionPassed(opcode))
8556     {
8557         uint32_t Rd, Rn;
8558         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8559         bool setflags;
8560         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8561         switch (encoding)
8562         {
8563         case eEncodingT1:
8564             Rd = Bits32(opcode, 11, 8);
8565             Rn = Bits32(opcode, 19, 16);
8566             setflags = BitIsSet(opcode, 20);
8567             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8568             // if Rn == '1111' then SEE MOV (immediate);
8569             if (Rn == 15)
8570                 return EmulateMOVRdImm (opcode, eEncodingT2);
8571             if (BadReg(Rd) || Rn == 13)
8572                 return false;
8573             break;
8574         case eEncodingA1:
8575             Rd = Bits32(opcode, 15, 12);
8576             Rn = Bits32(opcode, 19, 16);
8577             setflags = BitIsSet(opcode, 20);
8578             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8579 
8580             if (Rd == 15 && setflags)
8581                 return EmulateSUBSPcLrEtc (opcode, encoding);
8582             break;
8583         default:
8584             return false;
8585         }
8586 
8587         // Read the first operand.
8588         uint32_t val1 = ReadCoreReg(Rn, &success);
8589         if (!success)
8590             return false;
8591 
8592         uint32_t result = val1 | imm32;
8593 
8594         EmulateInstruction::Context context;
8595         context.type = EmulateInstruction::eContextImmediate;
8596         context.SetNoArgs ();
8597 
8598         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8599             return false;
8600     }
8601     return true;
8602 }
8603 
8604 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register
8605 // value, and writes the result to the destination register.  It can optionally update the condition flags based
8606 // on the result.
8607 bool
8608 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding)
8609 {
8610 #if 0
8611     // ARM pseudo code...
8612     if ConditionPassed() then
8613         EncodingSpecificOperations();
8614         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8615         result = R[n] OR shifted;
8616         if d == 15 then         // Can only occur for ARM encoding
8617             ALUWritePC(result); // setflags is always FALSE here
8618         else
8619             R[d] = result;
8620             if setflags then
8621                 APSR.N = result<31>;
8622                 APSR.Z = IsZeroBit(result);
8623                 APSR.C = carry;
8624                 // APSR.V unchanged
8625 #endif
8626 
8627     bool success = false;
8628 
8629     if (ConditionPassed(opcode))
8630     {
8631         uint32_t Rd, Rn, Rm;
8632         ARM_ShifterType shift_t;
8633         uint32_t shift_n; // the shift applied to the value read from Rm
8634         bool setflags;
8635         uint32_t carry;
8636         switch (encoding)
8637         {
8638         case eEncodingT1:
8639             Rd = Rn = Bits32(opcode, 2, 0);
8640             Rm = Bits32(opcode, 5, 3);
8641             setflags = !InITBlock();
8642             shift_t = SRType_LSL;
8643             shift_n = 0;
8644             break;
8645         case eEncodingT2:
8646             Rd = Bits32(opcode, 11, 8);
8647             Rn = Bits32(opcode, 19, 16);
8648             Rm = Bits32(opcode, 3, 0);
8649             setflags = BitIsSet(opcode, 20);
8650             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8651             // if Rn == '1111' then SEE MOV (register);
8652             if (Rn == 15)
8653                 return EmulateMOVRdRm (opcode, eEncodingT3);
8654             if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
8655                 return false;
8656             break;
8657         case eEncodingA1:
8658             Rd = Bits32(opcode, 15, 12);
8659             Rn = Bits32(opcode, 19, 16);
8660             Rm = Bits32(opcode, 3, 0);
8661             setflags = BitIsSet(opcode, 20);
8662             shift_n = DecodeImmShiftARM(opcode, shift_t);
8663 
8664             if (Rd == 15 && setflags)
8665                 return EmulateSUBSPcLrEtc (opcode, encoding);
8666             break;
8667         default:
8668             return false;
8669         }
8670 
8671         // Read the first operand.
8672         uint32_t val1 = ReadCoreReg(Rn, &success);
8673         if (!success)
8674             return false;
8675 
8676         // Read the second operand.
8677         uint32_t val2 = ReadCoreReg(Rm, &success);
8678         if (!success)
8679             return false;
8680 
8681         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8682         if (!success)
8683             return false;
8684         uint32_t result = val1 | shifted;
8685 
8686         EmulateInstruction::Context context;
8687         context.type = EmulateInstruction::eContextImmediate;
8688         context.SetNoArgs ();
8689 
8690         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8691             return false;
8692     }
8693     return true;
8694 }
8695 
8696 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to
8697 // the destination register. It can optionally update the condition flags based on the result.
8698 bool
8699 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding)
8700 {
8701 #if 0
8702     // ARM pseudo code...
8703     if ConditionPassed() then
8704         EncodingSpecificOperations();
8705         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
8706         if d == 15 then         // Can only occur for ARM encoding
8707             ALUWritePC(result); // setflags is always FALSE here
8708         else
8709             R[d] = result;
8710             if setflags then
8711                 APSR.N = result<31>;
8712                 APSR.Z = IsZeroBit(result);
8713                 APSR.C = carry;
8714                 APSR.V = overflow;
8715 #endif
8716 
8717     bool success = false;
8718 
8719     uint32_t Rd; // the destination register
8720     uint32_t Rn; // the first operand
8721     bool setflags;
8722     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8723     switch (encoding) {
8724     case eEncodingT1:
8725         Rd = Bits32(opcode, 2, 0);
8726         Rn = Bits32(opcode, 5, 3);
8727         setflags = !InITBlock();
8728         imm32 = 0;
8729         break;
8730     case eEncodingT2:
8731         Rd = Bits32(opcode, 11, 8);
8732         Rn = Bits32(opcode, 19, 16);
8733         setflags = BitIsSet(opcode, 20);
8734         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8735         if (BadReg(Rd) || BadReg(Rn))
8736             return false;
8737         break;
8738     case eEncodingA1:
8739         Rd = Bits32(opcode, 15, 12);
8740         Rn = Bits32(opcode, 19, 16);
8741         setflags = BitIsSet(opcode, 20);
8742         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8743 
8744         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8745         if (Rd == 15 && setflags)
8746             return EmulateSUBSPcLrEtc (opcode, encoding);
8747         break;
8748     default:
8749         return false;
8750     }
8751     // Read the register value from the operand register Rn.
8752     uint32_t reg_val = ReadCoreReg(Rn, &success);
8753     if (!success)
8754         return false;
8755 
8756     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
8757 
8758     EmulateInstruction::Context context;
8759     context.type = EmulateInstruction::eContextImmediate;
8760     context.SetNoArgs ();
8761 
8762     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8763         return false;
8764 
8765     return true;
8766 }
8767 
8768 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the
8769 // result to the destination register. It can optionally update the condition flags based on the result.
8770 bool
8771 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding)
8772 {
8773 #if 0
8774     // ARM pseudo code...
8775     if ConditionPassed() then
8776         EncodingSpecificOperations();
8777         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8778         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
8779         if d == 15 then         // Can only occur for ARM encoding
8780             ALUWritePC(result); // setflags is always FALSE here
8781         else
8782             R[d] = result;
8783             if setflags then
8784                 APSR.N = result<31>;
8785                 APSR.Z = IsZeroBit(result);
8786                 APSR.C = carry;
8787                 APSR.V = overflow;
8788 #endif
8789 
8790     bool success = false;
8791 
8792     uint32_t Rd; // the destination register
8793     uint32_t Rn; // the first operand
8794     uint32_t Rm; // the second operand
8795     bool setflags;
8796     ARM_ShifterType shift_t;
8797     uint32_t shift_n; // the shift applied to the value read from Rm
8798     switch (encoding) {
8799     case eEncodingT1:
8800         Rd = Bits32(opcode, 11, 8);
8801         Rn = Bits32(opcode, 19, 16);
8802         Rm = Bits32(opcode, 3, 0);
8803         setflags = BitIsSet(opcode, 20);
8804         shift_n = DecodeImmShiftThumb(opcode, shift_t);
8805         // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
8806         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8807             return false;
8808         break;
8809     case eEncodingA1:
8810         Rd = Bits32(opcode, 15, 12);
8811         Rn = Bits32(opcode, 19, 16);
8812         Rm = Bits32(opcode, 3, 0);
8813         setflags = BitIsSet(opcode, 20);
8814         shift_n = DecodeImmShiftARM(opcode, shift_t);
8815 
8816         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8817         if (Rd == 15 && setflags)
8818             return EmulateSUBSPcLrEtc (opcode, encoding);
8819         break;
8820     default:
8821         return false;
8822     }
8823     // Read the register value from register Rn.
8824     uint32_t val1 = ReadCoreReg(Rn, &success);
8825     if (!success)
8826         return false;
8827 
8828     // Read the register value from register Rm.
8829     uint32_t val2 = ReadCoreReg(Rm, &success);
8830     if (!success)
8831         return false;
8832 
8833     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8834     if (!success)
8835         return false;
8836     AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
8837 
8838     EmulateInstruction::Context context;
8839     context.type = EmulateInstruction::eContextImmediate;
8840     context.SetNoArgs();
8841     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8842         return false;
8843 
8844     return true;
8845 }
8846 
8847 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from
8848 // an immediate value, and writes the result to the destination register. It can optionally update the condition
8849 // flags based on the result.
8850 bool
8851 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding)
8852 {
8853 #if 0
8854     // ARM pseudo code...
8855     if ConditionPassed() then
8856         EncodingSpecificOperations();
8857         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
8858         if d == 15 then
8859             ALUWritePC(result); // setflags is always FALSE here
8860         else
8861             R[d] = result;
8862             if setflags then
8863                 APSR.N = result<31>;
8864                 APSR.Z = IsZeroBit(result);
8865                 APSR.C = carry;
8866                 APSR.V = overflow;
8867 #endif
8868 
8869     bool success = false;
8870 
8871     uint32_t Rd; // the destination register
8872     uint32_t Rn; // the first operand
8873     bool setflags;
8874     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8875     switch (encoding) {
8876     case eEncodingA1:
8877         Rd = Bits32(opcode, 15, 12);
8878         Rn = Bits32(opcode, 19, 16);
8879         setflags = BitIsSet(opcode, 20);
8880         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8881 
8882         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8883         if (Rd == 15 && setflags)
8884             return EmulateSUBSPcLrEtc  (opcode, encoding);
8885         break;
8886     default:
8887         return false;
8888     }
8889     // Read the register value from the operand register Rn.
8890     uint32_t reg_val = ReadCoreReg(Rn, &success);
8891     if (!success)
8892         return false;
8893 
8894     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
8895 
8896     EmulateInstruction::Context context;
8897     context.type = EmulateInstruction::eContextImmediate;
8898     context.SetNoArgs ();
8899 
8900     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8901         return false;
8902 
8903     return true;
8904 }
8905 
8906 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an
8907 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the
8908 // condition flags based on the result.
8909 bool
8910 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding)
8911 {
8912 #if 0
8913     // ARM pseudo code...
8914     if ConditionPassed() then
8915         EncodingSpecificOperations();
8916         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8917         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
8918         if d == 15 then
8919             ALUWritePC(result); // setflags is always FALSE here
8920         else
8921             R[d] = result;
8922             if setflags then
8923                 APSR.N = result<31>;
8924                 APSR.Z = IsZeroBit(result);
8925                 APSR.C = carry;
8926                 APSR.V = overflow;
8927 #endif
8928 
8929     bool success = false;
8930 
8931     uint32_t Rd; // the destination register
8932     uint32_t Rn; // the first operand
8933     uint32_t Rm; // the second operand
8934     bool setflags;
8935     ARM_ShifterType shift_t;
8936     uint32_t shift_n; // the shift applied to the value read from Rm
8937     switch (encoding) {
8938     case eEncodingA1:
8939         Rd = Bits32(opcode, 15, 12);
8940         Rn = Bits32(opcode, 19, 16);
8941         Rm = Bits32(opcode, 3, 0);
8942         setflags = BitIsSet(opcode, 20);
8943         shift_n = DecodeImmShiftARM(opcode, shift_t);
8944 
8945         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8946         if (Rd == 15 && setflags)
8947             return EmulateSUBSPcLrEtc (opcode, encoding);
8948         break;
8949     default:
8950         return false;
8951     }
8952     // Read the register value from register Rn.
8953     uint32_t val1 = ReadCoreReg(Rn, &success);
8954     if (!success)
8955         return false;
8956 
8957     // Read the register value from register Rm.
8958     uint32_t val2 = ReadCoreReg(Rm, &success);
8959     if (!success)
8960         return false;
8961 
8962     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8963     if (!success)
8964         return false;
8965     AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
8966 
8967     EmulateInstruction::Context context;
8968     context.type = EmulateInstruction::eContextImmediate;
8969     context.SetNoArgs();
8970     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8971         return false;
8972 
8973     return true;
8974 }
8975 
8976 // Subtract with Carry (immediate) subtracts an immediate value and the value of
8977 // NOT (Carry flag) from a register value, and writes the result to the destination register.
8978 // It can optionally update the condition flags based on the result.
8979 bool
8980 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding)
8981 {
8982 #if 0
8983     // ARM pseudo code...
8984     if ConditionPassed() then
8985         EncodingSpecificOperations();
8986         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
8987         if d == 15 then         // Can only occur for ARM encoding
8988             ALUWritePC(result); // setflags is always FALSE here
8989         else
8990             R[d] = result;
8991             if setflags then
8992                 APSR.N = result<31>;
8993                 APSR.Z = IsZeroBit(result);
8994                 APSR.C = carry;
8995                 APSR.V = overflow;
8996 #endif
8997 
8998     bool success = false;
8999 
9000     uint32_t Rd; // the destination register
9001     uint32_t Rn; // the first operand
9002     bool setflags;
9003     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
9004     switch (encoding) {
9005     case eEncodingT1:
9006         Rd = Bits32(opcode, 11, 8);
9007         Rn = Bits32(opcode, 19, 16);
9008         setflags = BitIsSet(opcode, 20);
9009         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9010         if (BadReg(Rd) || BadReg(Rn))
9011             return false;
9012         break;
9013     case eEncodingA1:
9014         Rd = Bits32(opcode, 15, 12);
9015         Rn = Bits32(opcode, 19, 16);
9016         setflags = BitIsSet(opcode, 20);
9017         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9018 
9019         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9020         if (Rd == 15 && setflags)
9021             return EmulateSUBSPcLrEtc (opcode, encoding);
9022         break;
9023     default:
9024         return false;
9025     }
9026     // Read the register value from the operand register Rn.
9027     uint32_t reg_val = ReadCoreReg(Rn, &success);
9028     if (!success)
9029         return false;
9030 
9031     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
9032 
9033     EmulateInstruction::Context context;
9034     context.type = EmulateInstruction::eContextImmediate;
9035     context.SetNoArgs ();
9036 
9037     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9038         return false;
9039 
9040     return true;
9041 }
9042 
9043 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of
9044 // NOT (Carry flag) from a register value, and writes the result to the destination register.
9045 // It can optionally update the condition flags based on the result.
9046 bool
9047 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding)
9048 {
9049 #if 0
9050     // ARM pseudo code...
9051     if ConditionPassed() then
9052         EncodingSpecificOperations();
9053         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9054         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
9055         if d == 15 then         // Can only occur for ARM encoding
9056             ALUWritePC(result); // setflags is always FALSE here
9057         else
9058             R[d] = result;
9059             if setflags then
9060                 APSR.N = result<31>;
9061                 APSR.Z = IsZeroBit(result);
9062                 APSR.C = carry;
9063                 APSR.V = overflow;
9064 #endif
9065 
9066     bool success = false;
9067 
9068     uint32_t Rd; // the destination register
9069     uint32_t Rn; // the first operand
9070     uint32_t Rm; // the second operand
9071     bool setflags;
9072     ARM_ShifterType shift_t;
9073     uint32_t shift_n; // the shift applied to the value read from Rm
9074     switch (encoding) {
9075     case eEncodingT1:
9076         Rd = Rn = Bits32(opcode, 2, 0);
9077         Rm = Bits32(opcode, 5, 3);
9078         setflags = !InITBlock();
9079         shift_t = SRType_LSL;
9080         shift_n = 0;
9081         break;
9082     case eEncodingT2:
9083         Rd = Bits32(opcode, 11, 8);
9084         Rn = Bits32(opcode, 19, 16);
9085         Rm = Bits32(opcode, 3, 0);
9086         setflags = BitIsSet(opcode, 20);
9087         shift_n = DecodeImmShiftThumb(opcode, shift_t);
9088         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
9089             return false;
9090         break;
9091     case eEncodingA1:
9092         Rd = Bits32(opcode, 15, 12);
9093         Rn = Bits32(opcode, 19, 16);
9094         Rm = Bits32(opcode, 3, 0);
9095         setflags = BitIsSet(opcode, 20);
9096         shift_n = DecodeImmShiftARM(opcode, shift_t);
9097 
9098         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9099         if (Rd == 15 && setflags)
9100             return EmulateSUBSPcLrEtc (opcode, encoding);
9101         break;
9102     default:
9103         return false;
9104     }
9105     // Read the register value from register Rn.
9106     uint32_t val1 = ReadCoreReg(Rn, &success);
9107     if (!success)
9108         return false;
9109 
9110     // Read the register value from register Rm.
9111     uint32_t val2 = ReadCoreReg(Rm, &success);
9112     if (!success)
9113         return false;
9114 
9115     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9116     if (!success)
9117         return false;
9118     AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
9119 
9120     EmulateInstruction::Context context;
9121     context.type = EmulateInstruction::eContextImmediate;
9122     context.SetNoArgs();
9123     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9124         return false;
9125 
9126     return true;
9127 }
9128 
9129 // This instruction subtracts an immediate value from a register value, and writes the result
9130 // to the destination register.  It can optionally update the condition flags based on the result.
9131 bool
9132 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding)
9133 {
9134 #if 0
9135     // ARM pseudo code...
9136     if ConditionPassed() then
9137         EncodingSpecificOperations();
9138         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9139         R[d] = result;
9140         if setflags then
9141             APSR.N = result<31>;
9142             APSR.Z = IsZeroBit(result);
9143             APSR.C = carry;
9144             APSR.V = overflow;
9145 #endif
9146 
9147     bool success = false;
9148 
9149     uint32_t Rd; // the destination register
9150     uint32_t Rn; // the first operand
9151     bool setflags;
9152     uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9153     switch (encoding) {
9154     case eEncodingT1:
9155         Rd = Bits32(opcode, 2, 0);
9156         Rn = Bits32(opcode, 5, 3);
9157         setflags = !InITBlock();
9158         imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9159         break;
9160     case eEncodingT2:
9161         Rd = Rn = Bits32(opcode, 10, 8);
9162         setflags = !InITBlock();
9163         imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9164         break;
9165     case eEncodingT3:
9166         Rd = Bits32(opcode, 11, 8);
9167         Rn = Bits32(opcode, 19, 16);
9168         setflags = BitIsSet(opcode, 20);
9169         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9170 
9171         // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9172         if (Rd == 15 && setflags)
9173             return EmulateCMPImm (opcode, eEncodingT2);
9174 
9175         // if Rn == '1101' then SEE SUB (SP minus immediate);
9176         if (Rn == 13)
9177             return EmulateSUBSPImm (opcode, eEncodingT2);
9178 
9179         // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9180         if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9181             return false;
9182         break;
9183     case eEncodingT4:
9184         Rd = Bits32(opcode, 11, 8);
9185         Rn = Bits32(opcode, 19, 16);
9186         setflags = BitIsSet(opcode, 20);
9187         imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9188 
9189         // if Rn == '1111' then SEE ADR;
9190         if (Rn == 15)
9191             return EmulateADR (opcode, eEncodingT2);
9192 
9193         // if Rn == '1101' then SEE SUB (SP minus immediate);
9194         if (Rn == 13)
9195             return EmulateSUBSPImm (opcode, eEncodingT3);
9196 
9197         if (BadReg(Rd))
9198             return false;
9199         break;
9200     default:
9201         return false;
9202     }
9203     // Read the register value from the operand register Rn.
9204     uint32_t reg_val = ReadCoreReg(Rn, &success);
9205     if (!success)
9206         return false;
9207 
9208     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9209 
9210     EmulateInstruction::Context context;
9211     context.type = EmulateInstruction::eContextImmediate;
9212     context.SetNoArgs ();
9213 
9214     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9215         return false;
9216 
9217     return true;
9218 }
9219 
9220 // This instruction subtracts an immediate value from a register value, and writes the result
9221 // to the destination register.  It can optionally update the condition flags based on the result.
9222 bool
9223 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9224 {
9225 #if 0
9226     // ARM pseudo code...
9227     if ConditionPassed() then
9228         EncodingSpecificOperations();
9229         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9230         if d == 15 then
9231             ALUWritePC(result); // setflags is always FALSE here
9232         else
9233             R[d] = result;
9234             if setflags then
9235                 APSR.N = result<31>;
9236                 APSR.Z = IsZeroBit(result);
9237                 APSR.C = carry;
9238                 APSR.V = overflow;
9239 #endif
9240 
9241     bool success = false;
9242 
9243     if (ConditionPassed(opcode))
9244     {
9245         uint32_t Rd; // the destination register
9246         uint32_t Rn; // the first operand
9247         bool setflags;
9248         uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9249         switch (encoding) {
9250         case eEncodingA1:
9251             Rd = Bits32(opcode, 15, 12);
9252             Rn = Bits32(opcode, 19, 16);
9253             setflags = BitIsSet(opcode, 20);
9254             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9255 
9256             // if Rn == '1111' && S == '0' then SEE ADR;
9257             if (Rn == 15 && !setflags)
9258                 return EmulateADR (opcode, eEncodingA2);
9259 
9260             // if Rn == '1101' then SEE SUB (SP minus immediate);
9261             if (Rn == 13)
9262                 return EmulateSUBSPImm (opcode, eEncodingA1);
9263 
9264             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9265             if (Rd == 15 && setflags)
9266                 return EmulateSUBSPcLrEtc (opcode, encoding);
9267             break;
9268         default:
9269             return false;
9270         }
9271         // Read the register value from the operand register Rn.
9272         uint32_t reg_val = ReadCoreReg(Rn, &success);
9273         if (!success)
9274             return false;
9275 
9276         AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9277 
9278         EmulateInstruction::Context context;
9279         if (Rd == 13)
9280             context.type = EmulateInstruction::eContextAdjustStackPointer;
9281         else
9282             context.type = EmulateInstruction::eContextRegisterPlusOffset;
9283 
9284         RegisterInfo dwarf_reg;
9285         GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
9286         int64_t imm32_signed = imm32;
9287         context.SetRegisterPlusOffset (dwarf_reg, -imm32_signed);
9288 
9289         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9290             return false;
9291     }
9292     return true;
9293 }
9294 
9295 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an
9296 // immediate value.  It updates the condition flags based on the result, and discards the result.
9297 bool
9298 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding)
9299 {
9300 #if 0
9301     // ARM pseudo code...
9302     if ConditionPassed() then
9303         EncodingSpecificOperations();
9304         result = R[n] EOR imm32;
9305         APSR.N = result<31>;
9306         APSR.Z = IsZeroBit(result);
9307         APSR.C = carry;
9308         // APSR.V unchanged
9309 #endif
9310 
9311     bool success = false;
9312 
9313     if (ConditionPassed(opcode))
9314     {
9315         uint32_t Rn;
9316         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9317         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9318         switch (encoding)
9319         {
9320         case eEncodingT1:
9321             Rn = Bits32(opcode, 19, 16);
9322             imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9323             if (BadReg(Rn))
9324                 return false;
9325             break;
9326         case eEncodingA1:
9327             Rn = Bits32(opcode, 19, 16);
9328             imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9329             break;
9330         default:
9331             return false;
9332         }
9333 
9334         // Read the first operand.
9335         uint32_t val1 = ReadCoreReg(Rn, &success);
9336         if (!success)
9337             return false;
9338 
9339         uint32_t result = val1 ^ imm32;
9340 
9341         EmulateInstruction::Context context;
9342         context.type = EmulateInstruction::eContextImmediate;
9343         context.SetNoArgs ();
9344 
9345         if (!WriteFlags(context, result, carry))
9346             return false;
9347     }
9348     return true;
9349 }
9350 
9351 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an
9352 // optionally-shifted register value.  It updates the condition flags based on the result, and discards
9353 // the result.
9354 bool
9355 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding)
9356 {
9357 #if 0
9358     // ARM pseudo code...
9359     if ConditionPassed() then
9360         EncodingSpecificOperations();
9361         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9362         result = R[n] EOR shifted;
9363         APSR.N = result<31>;
9364         APSR.Z = IsZeroBit(result);
9365         APSR.C = carry;
9366         // APSR.V unchanged
9367 #endif
9368 
9369     bool success = false;
9370 
9371     if (ConditionPassed(opcode))
9372     {
9373         uint32_t Rn, Rm;
9374         ARM_ShifterType shift_t;
9375         uint32_t shift_n; // the shift applied to the value read from Rm
9376         uint32_t carry;
9377         switch (encoding)
9378         {
9379         case eEncodingT1:
9380             Rn = Bits32(opcode, 19, 16);
9381             Rm = Bits32(opcode, 3, 0);
9382             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9383             if (BadReg(Rn) || BadReg(Rm))
9384                 return false;
9385             break;
9386         case eEncodingA1:
9387             Rn = Bits32(opcode, 19, 16);
9388             Rm = Bits32(opcode, 3, 0);
9389             shift_n = DecodeImmShiftARM(opcode, shift_t);
9390             break;
9391         default:
9392             return false;
9393         }
9394 
9395         // Read the first operand.
9396         uint32_t val1 = ReadCoreReg(Rn, &success);
9397         if (!success)
9398             return false;
9399 
9400         // Read the second operand.
9401         uint32_t val2 = ReadCoreReg(Rm, &success);
9402         if (!success)
9403             return false;
9404 
9405         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9406         if (!success)
9407             return false;
9408         uint32_t result = val1 ^ shifted;
9409 
9410         EmulateInstruction::Context context;
9411         context.type = EmulateInstruction::eContextImmediate;
9412         context.SetNoArgs ();
9413 
9414         if (!WriteFlags(context, result, carry))
9415             return false;
9416     }
9417     return true;
9418 }
9419 
9420 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value.
9421 // It updates the condition flags based on the result, and discards the result.
9422 bool
9423 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding)
9424 {
9425 #if 0
9426     // ARM pseudo code...
9427     if ConditionPassed() then
9428         EncodingSpecificOperations();
9429         result = R[n] AND imm32;
9430         APSR.N = result<31>;
9431         APSR.Z = IsZeroBit(result);
9432         APSR.C = carry;
9433         // APSR.V unchanged
9434 #endif
9435 
9436     bool success = false;
9437 
9438     if (ConditionPassed(opcode))
9439     {
9440         uint32_t Rn;
9441         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9442         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9443         switch (encoding)
9444         {
9445         case eEncodingT1:
9446             Rn = Bits32(opcode, 19, 16);
9447             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9448             if (BadReg(Rn))
9449                 return false;
9450             break;
9451         case eEncodingA1:
9452             Rn = Bits32(opcode, 19, 16);
9453             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9454             break;
9455         default:
9456             return false;
9457         }
9458 
9459         // Read the first operand.
9460         uint32_t val1 = ReadCoreReg(Rn, &success);
9461         if (!success)
9462             return false;
9463 
9464         uint32_t result = val1 & imm32;
9465 
9466         EmulateInstruction::Context context;
9467         context.type = EmulateInstruction::eContextImmediate;
9468         context.SetNoArgs ();
9469 
9470         if (!WriteFlags(context, result, carry))
9471             return false;
9472     }
9473     return true;
9474 }
9475 
9476 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value.
9477 // It updates the condition flags based on the result, and discards the result.
9478 bool
9479 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding)
9480 {
9481 #if 0
9482     // ARM pseudo code...
9483     if ConditionPassed() then
9484         EncodingSpecificOperations();
9485         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9486         result = R[n] AND shifted;
9487         APSR.N = result<31>;
9488         APSR.Z = IsZeroBit(result);
9489         APSR.C = carry;
9490         // APSR.V unchanged
9491 #endif
9492 
9493     bool success = false;
9494 
9495     if (ConditionPassed(opcode))
9496     {
9497         uint32_t Rn, Rm;
9498         ARM_ShifterType shift_t;
9499         uint32_t shift_n; // the shift applied to the value read from Rm
9500         uint32_t carry;
9501         switch (encoding)
9502         {
9503         case eEncodingT1:
9504             Rn = Bits32(opcode, 2, 0);
9505             Rm = Bits32(opcode, 5, 3);
9506             shift_t = SRType_LSL;
9507             shift_n = 0;
9508             break;
9509         case eEncodingT2:
9510             Rn = Bits32(opcode, 19, 16);
9511             Rm = Bits32(opcode, 3, 0);
9512             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9513             if (BadReg(Rn) || BadReg(Rm))
9514                 return false;
9515             break;
9516         case eEncodingA1:
9517             Rn = Bits32(opcode, 19, 16);
9518             Rm = Bits32(opcode, 3, 0);
9519             shift_n = DecodeImmShiftARM(opcode, shift_t);
9520             break;
9521         default:
9522             return false;
9523         }
9524 
9525         // Read the first operand.
9526         uint32_t val1 = ReadCoreReg(Rn, &success);
9527         if (!success)
9528             return false;
9529 
9530         // Read the second operand.
9531         uint32_t val2 = ReadCoreReg(Rm, &success);
9532         if (!success)
9533             return false;
9534 
9535         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9536         if (!success)
9537             return false;
9538         uint32_t result = val1 & shifted;
9539 
9540         EmulateInstruction::Context context;
9541         context.type = EmulateInstruction::eContextImmediate;
9542         context.SetNoArgs ();
9543 
9544         if (!WriteFlags(context, result, carry))
9545             return false;
9546     }
9547     return true;
9548 }
9549 
9550 // A8.6.216 SUB (SP minus register)
9551 bool
9552 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding)
9553 {
9554 #if 0
9555     if ConditionPassed() then
9556         EncodingSpecificOperations();
9557         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9558         (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
9559         if d == 15 then // Can only occur for ARM encoding
9560             ALUWritePC(result); // setflags is always FALSE here
9561         else
9562             R[d] = result;
9563             if setflags then
9564                 APSR.N = result<31>;
9565                 APSR.Z = IsZeroBit(result);
9566                 APSR.C = carry;
9567                 APSR.V = overflow;
9568 #endif
9569 
9570     bool success = false;
9571 
9572     if (ConditionPassed(opcode))
9573     {
9574         uint32_t d;
9575         uint32_t m;
9576         bool setflags;
9577         ARM_ShifterType shift_t;
9578         uint32_t shift_n;
9579 
9580         switch (encoding)
9581         {
9582             case eEncodingT1:
9583                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
9584                 d = Bits32 (opcode, 11, 8);
9585                 m = Bits32 (opcode, 3, 0);
9586                 setflags = BitIsSet (opcode, 20);
9587 
9588                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9589                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9590 
9591                 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE;
9592                 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
9593                     return false;
9594 
9595                 // if d == 15 || BadReg(m) then UNPREDICTABLE;
9596                 if ((d == 15) || BadReg (m))
9597                     return false;
9598                 break;
9599 
9600             case eEncodingA1:
9601                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == '1');
9602                 d = Bits32 (opcode, 15, 12);
9603                 m = Bits32 (opcode, 3, 0);
9604                 setflags = BitIsSet (opcode, 20);
9605 
9606                 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9607                 if (d == 15 && setflags)
9608                     EmulateSUBSPcLrEtc (opcode, encoding);
9609 
9610                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9611                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9612                 break;
9613 
9614             default:
9615                 return false;
9616         }
9617 
9618         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9619         uint32_t Rm = ReadCoreReg (m, &success);
9620         if (!success)
9621             return false;
9622 
9623         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9624         if (!success)
9625             return false;
9626 
9627         // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), '1');
9628         uint32_t sp_val = ReadCoreReg (SP_REG, &success);
9629         if (!success)
9630             return false;
9631 
9632         AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1);
9633 
9634         EmulateInstruction::Context context;
9635         context.type = eContextArithmetic;
9636         RegisterInfo sp_reg;
9637         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
9638         RegisterInfo dwarf_reg;
9639         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
9640         context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
9641 
9642         if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9643             return false;
9644     }
9645     return true;
9646 }
9647 
9648 
9649 // A8.6.7 ADD (register-shifted register)
9650 bool
9651 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding)
9652 {
9653 #if 0
9654     if ConditionPassed() then
9655         EncodingSpecificOperations();
9656         shift_n = UInt(R[s]<7:0>);
9657         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9658         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
9659         R[d] = result;
9660         if setflags then
9661             APSR.N = result<31>;
9662             APSR.Z = IsZeroBit(result);
9663             APSR.C = carry;
9664             APSR.V = overflow;
9665 #endif
9666 
9667     bool success = false;
9668 
9669     if (ConditionPassed(opcode))
9670     {
9671         uint32_t d;
9672         uint32_t n;
9673         uint32_t m;
9674         uint32_t s;
9675         bool setflags;
9676         ARM_ShifterType shift_t;
9677 
9678         switch (encoding)
9679         {
9680             case eEncodingA1:
9681                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
9682                 d = Bits32 (opcode, 15, 12);
9683                 n = Bits32 (opcode, 19, 16);
9684                 m = Bits32 (opcode, 3, 0);
9685                 s = Bits32 (opcode, 11, 8);
9686 
9687                 // setflags = (S == '1'); shift_t = DecodeRegShift(type);
9688                 setflags = BitIsSet (opcode, 20);
9689                 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5));
9690 
9691                 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
9692                 if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
9693                     return false;
9694                 break;
9695 
9696             default:
9697                 return false;
9698         }
9699 
9700         // shift_n = UInt(R[s]<7:0>);
9701         uint32_t Rs = ReadCoreReg (s, &success);
9702         if (!success)
9703             return false;
9704 
9705         uint32_t shift_n = Bits32 (Rs, 7, 0);
9706 
9707         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9708         uint32_t Rm = ReadCoreReg (m, &success);
9709         if (!success)
9710             return false;
9711 
9712         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9713         if (!success)
9714             return false;
9715 
9716         // (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
9717         uint32_t Rn = ReadCoreReg (n, &success);
9718         if (!success)
9719             return false;
9720 
9721         AddWithCarryResult res = AddWithCarry (Rn, shifted, 0);
9722 
9723         // R[d] = result;
9724         EmulateInstruction::Context context;
9725         context.type = eContextArithmetic;
9726         RegisterInfo reg_n;
9727         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9728         RegisterInfo reg_m;
9729         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9730 
9731         context.SetRegisterRegisterOperands (reg_n, reg_m);
9732 
9733         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result))
9734             return false;
9735 
9736         // if setflags then
9737             // APSR.N = result<31>;
9738             // APSR.Z = IsZeroBit(result);
9739             // APSR.C = carry;
9740             // APSR.V = overflow;
9741         if (setflags)
9742             return WriteFlags (context, res.result, res.carry_out, res.overflow);
9743     }
9744     return true;
9745 }
9746 
9747 // A8.6.213 SUB (register)
9748 bool
9749 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding)
9750 {
9751 #if 0
9752     if ConditionPassed() then
9753         EncodingSpecificOperations();
9754         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9755         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
9756         if d == 15 then // Can only occur for ARM encoding
9757             ALUWritePC(result); // setflags is always FALSE here
9758         else
9759             R[d] = result;
9760             if setflags then
9761                 APSR.N = result<31>;
9762                 APSR.Z = IsZeroBit(result);
9763                 APSR.C = carry;
9764                 APSR.V = overflow;
9765 #endif
9766 
9767     bool success = false;
9768 
9769     if (ConditionPassed(opcode))
9770     {
9771         uint32_t d;
9772         uint32_t n;
9773         uint32_t m;
9774         bool setflags;
9775         ARM_ShifterType shift_t;
9776         uint32_t shift_n;
9777 
9778         switch (encoding)
9779         {
9780             case eEncodingT1:
9781                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
9782                 d = Bits32 (opcode, 2, 0);
9783                 n = Bits32 (opcode, 5, 3);
9784                 m = Bits32 (opcode, 8, 6);
9785                 setflags = !InITBlock();
9786 
9787                 // (shift_t, shift_n) = (SRType_LSL, 0);
9788                 shift_t = SRType_LSL;
9789                 shift_n = 0;
9790 
9791                 break;
9792 
9793             case eEncodingT2:
9794                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S =="1");
9795                 d = Bits32 (opcode, 11, 8);
9796                 n = Bits32 (opcode, 19, 16);
9797                 m = Bits32 (opcode, 3, 0);
9798                 setflags = BitIsSet (opcode, 20);
9799 
9800                 // if Rd == "1111" && S == "1" then SEE CMP (register);
9801                 if (d == 15 && setflags == 1)
9802                     return EmulateCMPImm (opcode, eEncodingT3);
9803 
9804                 // if Rn == "1101" then SEE SUB (SP minus register);
9805                 if (n == 13)
9806                     return EmulateSUBSPReg (opcode, eEncodingT1);
9807 
9808                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9809                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9810 
9811                 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE;
9812                 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m))
9813                     return false;
9814 
9815                 break;
9816 
9817             case eEncodingA1:
9818                 // if Rn == '1101' then SEE SUB (SP minus register);
9819                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
9820                 d = Bits32 (opcode, 15, 12);
9821                 n = Bits32 (opcode, 19, 16);
9822                 m = Bits32 (opcode, 3, 0);
9823                 setflags = BitIsSet (opcode, 20);
9824 
9825                 // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9826                 if ((d == 15) && setflags)
9827                     EmulateSUBSPcLrEtc (opcode, encoding);
9828 
9829                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9830                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9831 
9832                 break;
9833 
9834             default:
9835                 return false;
9836         }
9837 
9838         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9839         uint32_t Rm = ReadCoreReg (m, &success);
9840         if (!success)
9841             return false;
9842 
9843         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9844         if (!success)
9845             return false;
9846 
9847         // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
9848         uint32_t Rn = ReadCoreReg (n, &success);
9849         if (!success)
9850             return false;
9851 
9852         AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1);
9853 
9854         // if d == 15 then // Can only occur for ARM encoding
9855             // ALUWritePC(result); // setflags is always FALSE here
9856         // else
9857             // R[d] = result;
9858             // if setflags then
9859                 // APSR.N = result<31>;
9860                 // APSR.Z = IsZeroBit(result);
9861                 // APSR.C = carry;
9862                 // APSR.V = overflow;
9863 
9864         EmulateInstruction::Context context;
9865         context.type = eContextArithmetic;
9866         RegisterInfo reg_n;
9867         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9868         RegisterInfo reg_m;
9869         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9870         context.SetRegisterRegisterOperands (reg_n, reg_m);
9871 
9872         if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9873             return false;
9874     }
9875     return true;
9876 }
9877 
9878 // A8.6.202 STREX
9879 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a
9880 // word from a register to memory if the executing processor has exclusive access to the memory addressed.
9881 bool
9882 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding)
9883 {
9884 #if 0
9885     if ConditionPassed() then
9886         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9887         address = R[n] + imm32;
9888         if ExclusiveMonitorsPass(address,4) then
9889             MemA[address,4] = R[t];
9890             R[d] = 0;
9891         else
9892             R[d] = 1;
9893 #endif
9894 
9895     bool success = false;
9896 
9897     if (ConditionPassed(opcode))
9898     {
9899         uint32_t d;
9900         uint32_t t;
9901         uint32_t n;
9902         uint32_t imm32;
9903         const uint32_t addr_byte_size = GetAddressByteSize();
9904 
9905         switch (encoding)
9906         {
9907             case eEncodingT1:
9908                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
9909                 d = Bits32 (opcode, 11, 8);
9910                 t = Bits32 (opcode, 15, 12);
9911                 n = Bits32 (opcode, 19, 16);
9912                 imm32 = Bits32 (opcode, 7, 0) << 2;
9913 
9914                 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
9915                 if (BadReg (d) || BadReg (t) || (n == 15))
9916                   return false;
9917 
9918                 // if d == n || d == t then UNPREDICTABLE;
9919                 if ((d == n) || (d == t))
9920                   return false;
9921 
9922                 break;
9923 
9924             case eEncodingA1:
9925                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset
9926                 d = Bits32 (opcode, 15, 12);
9927                 t = Bits32 (opcode, 3, 0);
9928                 n = Bits32 (opcode, 19, 16);
9929                 imm32 = 0;
9930 
9931                 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
9932                 if ((d == 15) || (t == 15) || (n == 15))
9933                     return false;
9934 
9935                 // if d == n || d == t then UNPREDICTABLE;
9936                 if ((d == n) || (d == t))
9937                     return false;
9938 
9939                 break;
9940 
9941             default:
9942                 return false;
9943         }
9944 
9945         // address = R[n] + imm32;
9946         uint32_t Rn = ReadCoreReg (n, &success);
9947         if (!success)
9948             return false;
9949 
9950         addr_t address = Rn + imm32;
9951 
9952         RegisterInfo base_reg;
9953         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9954         RegisterInfo data_reg;
9955         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9956         EmulateInstruction::Context context;
9957         context.type = eContextRegisterStore;
9958         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32);
9959 
9960         // if ExclusiveMonitorsPass(address,4) then
9961         // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this
9962         //                                                         always return true.
9963         if (true)
9964         {
9965             // MemA[address,4] = R[t];
9966             uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
9967             if (!success)
9968                 return false;
9969 
9970             if (!MemAWrite (context, address, Rt, addr_byte_size))
9971                 return false;
9972 
9973             // R[d] = 0;
9974             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0))
9975                 return false;
9976         }
9977 #if 0 // unreachable because if true
9978         else
9979         {
9980             // R[d] = 1;
9981             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
9982                 return false;
9983         }
9984 #endif // unreachable because if true
9985     }
9986     return true;
9987 }
9988 
9989 // A8.6.197 STRB (immediate, ARM)
9990 bool
9991 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9992 {
9993 #if 0
9994     if ConditionPassed() then
9995         EncodingSpecificOperations();
9996         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9997         address = if index then offset_addr else R[n];
9998         MemU[address,1] = R[t]<7:0>;
9999         if wback then R[n] = offset_addr;
10000 #endif
10001 
10002     bool success = false;
10003 
10004     if (ConditionPassed(opcode))
10005     {
10006         uint32_t t;
10007         uint32_t n;
10008         uint32_t imm32;
10009         bool index;
10010         bool add;
10011         bool wback;
10012 
10013         switch (encoding)
10014         {
10015             case eEncodingA1:
10016                 // if P == '0' && W == '1' then SEE STRBT;
10017                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10018                 t = Bits32 (opcode, 15, 12);
10019                 n = Bits32 (opcode, 19, 16);
10020                 imm32 = Bits32 (opcode, 11, 0);
10021 
10022                 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10023                 index = BitIsSet (opcode, 24);
10024                 add = BitIsSet (opcode, 23);
10025                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10026 
10027                 // if t == 15 then UNPREDICTABLE;
10028                 if (t == 15)
10029                     return false;
10030 
10031                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10032                 if (wback && ((n == 15) || (n == t)))
10033                     return false;
10034 
10035                 break;
10036 
10037             default:
10038                 return false;
10039         }
10040 
10041         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10042         uint32_t Rn = ReadCoreReg (n, &success);
10043         if (!success)
10044             return false;
10045 
10046         addr_t offset_addr;
10047         if (add)
10048             offset_addr = Rn + imm32;
10049         else
10050             offset_addr = Rn - imm32;
10051 
10052         // address = if index then offset_addr else R[n];
10053         addr_t address;
10054         if (index)
10055             address = offset_addr;
10056         else
10057             address = Rn;
10058 
10059         // MemU[address,1] = R[t]<7:0>;
10060         uint32_t Rt = ReadCoreReg (t, &success);
10061         if (!success)
10062             return false;
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         if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1))
10073             return false;
10074 
10075         // if wback then R[n] = offset_addr;
10076         if (wback)
10077         {
10078             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10079                 return false;
10080         }
10081     }
10082     return true;
10083 }
10084 
10085 // A8.6.194 STR (immediate, ARM)
10086 bool
10087 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding)
10088 {
10089 #if 0
10090     if ConditionPassed() then
10091         EncodingSpecificOperations();
10092         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10093         address = if index then offset_addr else R[n];
10094         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10095         if wback then R[n] = offset_addr;
10096 #endif
10097 
10098     bool success = false;
10099 
10100     if (ConditionPassed(opcode))
10101     {
10102         uint32_t t;
10103         uint32_t n;
10104         uint32_t imm32;
10105         bool index;
10106         bool add;
10107         bool wback;
10108 
10109         const uint32_t addr_byte_size = GetAddressByteSize();
10110 
10111         switch (encoding)
10112         {
10113             case eEncodingA1:
10114                 // if P == '0' && W == '1' then SEE STRT;
10115                 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == '000000000100' then SEE PUSH;
10116                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
10117                 t = Bits32 (opcode, 15, 12);
10118                 n = Bits32 (opcode, 19, 16);
10119                 imm32 = Bits32 (opcode, 11, 0);
10120 
10121                 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10122                 index = BitIsSet (opcode, 24);
10123                 add = BitIsSet (opcode, 23);
10124                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10125 
10126                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
10127                 if (wback && ((n == 15) || (n == t)))
10128                     return false;
10129 
10130                 break;
10131 
10132             default:
10133                 return false;
10134         }
10135 
10136         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10137         uint32_t Rn = ReadCoreReg (n, &success);
10138         if (!success)
10139             return false;
10140 
10141         addr_t offset_addr;
10142         if (add)
10143             offset_addr = Rn + imm32;
10144         else
10145             offset_addr = Rn - imm32;
10146 
10147         // address = if index then offset_addr else R[n];
10148         addr_t address;
10149         if (index)
10150             address = offset_addr;
10151         else
10152             address = Rn;
10153 
10154         RegisterInfo base_reg;
10155         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10156         RegisterInfo data_reg;
10157         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10158         EmulateInstruction::Context context;
10159         context.type = eContextRegisterStore;
10160         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10161 
10162         // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10163         uint32_t Rt = ReadCoreReg (t, &success);
10164         if (!success)
10165             return false;
10166 
10167         if (t == 15)
10168         {
10169             uint32_t pc_value = ReadCoreReg (PC_REG, &success);
10170             if (!success)
10171                 return false;
10172 
10173             if (!MemUWrite (context, address, pc_value, addr_byte_size))
10174                 return false;
10175         }
10176         else
10177         {
10178             if (!MemUWrite (context, address, Rt, addr_byte_size))
10179                   return false;
10180         }
10181 
10182         // if wback then R[n] = offset_addr;
10183         if (wback)
10184         {
10185             context.type = eContextAdjustBaseRegister;
10186             context.SetImmediate (offset_addr);
10187 
10188             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10189                 return false;
10190         }
10191     }
10192     return true;
10193 }
10194 
10195 // A8.6.66 LDRD (immediate)
10196 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two
10197 // words from memory, and writes them to two registers.  It can use offset, post-indexed, or pre-indexed addressing.
10198 bool
10199 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding)
10200 {
10201 #if 0
10202     if ConditionPassed() then
10203         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10204         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10205         address = if index then offset_addr else R[n];
10206         R[t] = MemA[address,4];
10207         R[t2] = MemA[address+4,4];
10208         if wback then R[n] = offset_addr;
10209 #endif
10210 
10211     bool success = false;
10212 
10213     if (ConditionPassed(opcode))
10214     {
10215         uint32_t t;
10216         uint32_t t2;
10217         uint32_t n;
10218         uint32_t imm32;
10219         bool index;
10220         bool add;
10221         bool wback;
10222 
10223         switch (encoding)
10224         {
10225             case eEncodingT1:
10226                 //if P == '0' && W == '0' then SEE 'Related encodings';
10227                 //if Rn == '1111' then SEE LDRD (literal);
10228                 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
10229                 t = Bits32 (opcode, 15, 12);
10230                 t2 = Bits32 (opcode, 11, 8);
10231                 n = Bits32 (opcode, 19, 16);
10232                 imm32 = Bits32 (opcode, 7, 0) << 2;
10233 
10234                 //index = (P == '1'); add = (U == '1'); wback = (W == '1');
10235                 index = BitIsSet (opcode, 24);
10236                 add = BitIsSet (opcode, 23);
10237                 wback = BitIsSet (opcode, 21);
10238 
10239                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10240                 if (wback && ((n == t) || (n == t2)))
10241                     return false;
10242 
10243                 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10244                 if (BadReg (t) || BadReg (t2) || (t == t2))
10245                     return false;
10246 
10247                 break;
10248 
10249             case eEncodingA1:
10250                 //if Rn == '1111' then SEE LDRD (literal);
10251                 //if Rt<0> == '1' then UNPREDICTABLE;
10252                 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10253                 t = Bits32 (opcode, 15, 12);
10254                 if (BitIsSet (t, 0))
10255                     return false;
10256                 t2 = t + 1;
10257                 n = Bits32 (opcode, 19, 16);
10258                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10259 
10260                 //index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10261                 index = BitIsSet (opcode, 24);
10262                 add = BitIsSet (opcode, 23);
10263                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10264 
10265                 //if P == '0' && W == '1' then UNPREDICTABLE;
10266                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10267                     return false;
10268 
10269                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10270                 if (wback && ((n == t) || (n == t2)))
10271                     return false;
10272 
10273                 //if t2 == 15 then UNPREDICTABLE;
10274                 if (t2 == 15)
10275                     return false;
10276 
10277                 break;
10278 
10279             default:
10280                 return false;
10281         }
10282 
10283         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10284         uint32_t Rn = ReadCoreReg (n, &success);
10285         if (!success)
10286             return false;
10287 
10288         addr_t offset_addr;
10289         if (add)
10290                   offset_addr = Rn + imm32;
10291         else
10292             offset_addr = Rn - imm32;
10293 
10294         //address = if index then offset_addr else R[n];
10295         addr_t address;
10296         if (index)
10297             address = offset_addr;
10298         else
10299             address = Rn;
10300 
10301         //R[t] = MemA[address,4];
10302         RegisterInfo base_reg;
10303         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10304 
10305         EmulateInstruction::Context context;
10306         if (n == 13)
10307             context.type = eContextPopRegisterOffStack;
10308         else
10309             context.type = eContextRegisterLoad;
10310         context.SetRegisterPlusOffset (base_reg, address - Rn);
10311 
10312         const uint32_t addr_byte_size = GetAddressByteSize();
10313         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10314         if (!success)
10315             return false;
10316 
10317         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10318             return false;
10319 
10320         //R[t2] = MemA[address+4,4];
10321 
10322         context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10323         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10324         if (!success)
10325             return false;
10326 
10327         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10328             return false;
10329 
10330         //if wback then R[n] = offset_addr;
10331         if (wback)
10332         {
10333             context.type = eContextAdjustBaseRegister;
10334             context.SetAddress (offset_addr);
10335 
10336             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10337                 return false;
10338         }
10339     }
10340     return true;
10341 }
10342 
10343 // A8.6.68 LDRD (register)
10344 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two
10345 // words from memory, and writes them to two registers.  It can use offset, post-indexed or pre-indexed addressing.
10346 bool
10347 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding)
10348 {
10349 #if 0
10350     if ConditionPassed() then
10351         EncodingSpecificOperations();
10352         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10353         address = if index then offset_addr else R[n];
10354         R[t] = MemA[address,4];
10355         R[t2] = MemA[address+4,4];
10356         if wback then R[n] = offset_addr;
10357 #endif
10358 
10359     bool success = false;
10360 
10361     if (ConditionPassed(opcode))
10362     {
10363         uint32_t t;
10364         uint32_t t2;
10365         uint32_t n;
10366         uint32_t m;
10367         bool index;
10368         bool add;
10369         bool wback;
10370 
10371         switch (encoding)
10372         {
10373             case eEncodingA1:
10374                 // if Rt<0> == '1' then UNPREDICTABLE;
10375                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10376                 t = Bits32 (opcode, 15, 12);
10377                 if (BitIsSet (t, 0))
10378                     return false;
10379                 t2 = t + 1;
10380                 n = Bits32 (opcode, 19, 16);
10381                 m = Bits32 (opcode, 3, 0);
10382 
10383                 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10384                 index = BitIsSet (opcode, 24);
10385                 add = BitIsSet (opcode, 23);
10386                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10387 
10388                 // if P == '0' && W == '1' then UNPREDICTABLE;
10389                   if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10390                   return false;
10391 
10392                 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10393                   if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10394                   return false;
10395 
10396                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10397                   if (wback && ((n == 15) || (n == t) || (n == t2)))
10398                   return false;
10399 
10400                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10401                 if ((ArchVersion() < 6) && wback && (m == n))
10402                   return false;
10403                 break;
10404 
10405             default:
10406                 return false;
10407         }
10408 
10409         uint32_t Rn = ReadCoreReg (n, &success);
10410         if (!success)
10411             return false;
10412         RegisterInfo base_reg;
10413         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10414 
10415         uint32_t Rm = ReadCoreReg (m, &success);
10416         if (!success)
10417             return false;
10418         RegisterInfo offset_reg;
10419         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10420 
10421         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10422         addr_t offset_addr;
10423         if (add)
10424             offset_addr = Rn + Rm;
10425         else
10426             offset_addr = Rn - Rm;
10427 
10428         // address = if index then offset_addr else R[n];
10429         addr_t address;
10430         if (index)
10431             address = offset_addr;
10432         else
10433             address = Rn;
10434 
10435         EmulateInstruction::Context context;
10436         if (n == 13)
10437             context.type = eContextPopRegisterOffStack;
10438         else
10439             context.type = eContextRegisterLoad;
10440         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
10441 
10442         // R[t] = MemA[address,4];
10443         const uint32_t addr_byte_size = GetAddressByteSize();
10444         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10445         if (!success)
10446             return false;
10447 
10448         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10449             return false;
10450 
10451         // R[t2] = MemA[address+4,4];
10452 
10453         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10454         if (!success)
10455             return false;
10456 
10457         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10458             return false;
10459 
10460         // if wback then R[n] = offset_addr;
10461         if (wback)
10462         {
10463             context.type = eContextAdjustBaseRegister;
10464             context.SetAddress (offset_addr);
10465 
10466             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10467                 return false;
10468         }
10469     }
10470     return true;
10471 }
10472 
10473 // A8.6.200 STRD (immediate)
10474 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and
10475 // stores two words from two registers to memory.  It can use offset, post-indexed, or pre-indexed addressing.
10476 bool
10477 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding)
10478 {
10479 #if 0
10480     if ConditionPassed() then
10481         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10482         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10483         address = if index then offset_addr else R[n];
10484         MemA[address,4] = R[t];
10485         MemA[address+4,4] = R[t2];
10486         if wback then R[n] = offset_addr;
10487 #endif
10488 
10489     bool success = false;
10490 
10491     if (ConditionPassed(opcode))
10492     {
10493         uint32_t t;
10494         uint32_t t2;
10495         uint32_t n;
10496         uint32_t imm32;
10497         bool index;
10498         bool add;
10499         bool wback;
10500 
10501         switch (encoding)
10502         {
10503             case eEncodingT1:
10504                 // if P == '0' && W == '0' then SEE 'Related encodings';
10505                 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
10506                 t = Bits32 (opcode, 15, 12);
10507                 t2 = Bits32 (opcode, 11, 8);
10508                 n = Bits32 (opcode, 19, 16);
10509                 imm32 = Bits32 (opcode, 7, 0) << 2;
10510 
10511                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
10512                 index = BitIsSet (opcode, 24);
10513                 add = BitIsSet (opcode, 23);
10514                 wback = BitIsSet (opcode, 21);
10515 
10516                 // if wback && (n == t || n == t2) then UNPREDICTABLE;
10517                 if (wback && ((n == t) || (n == t2)))
10518                     return false;
10519 
10520                 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10521                 if ((n == 15) || BadReg (t) || BadReg (t2))
10522                     return false;
10523 
10524                 break;
10525 
10526             case eEncodingA1:
10527                 // if Rt<0> == '1' then UNPREDICTABLE;
10528                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10529                 t = Bits32 (opcode, 15, 12);
10530                 if (BitIsSet (t, 0))
10531                     return false;
10532 
10533                 t2 = t + 1;
10534                 n = Bits32 (opcode, 19, 16);
10535                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10536 
10537                 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10538                 index = BitIsSet (opcode, 24);
10539                 add = BitIsSet (opcode, 23);
10540                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10541 
10542                 // if P == '0' && W == '1' then UNPREDICTABLE;
10543                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10544                     return false;
10545 
10546                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10547                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10548                     return false;
10549 
10550                 // if t2 == 15 then UNPREDICTABLE;
10551                 if (t2 == 15)
10552                     return false;
10553 
10554                 break;
10555 
10556             default:
10557                 return false;
10558         }
10559 
10560         RegisterInfo base_reg;
10561         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10562 
10563         uint32_t Rn = ReadCoreReg (n, &success);
10564         if (!success)
10565             return false;
10566 
10567         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10568         addr_t offset_addr;
10569         if (add)
10570             offset_addr = Rn + imm32;
10571         else
10572             offset_addr = Rn - imm32;
10573 
10574         //address = if index then offset_addr else R[n];
10575         addr_t address;
10576         if (index)
10577             address = offset_addr;
10578         else
10579             address = Rn;
10580 
10581         //MemA[address,4] = R[t];
10582         RegisterInfo data_reg;
10583         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10584 
10585         uint32_t data = ReadCoreReg (t, &success);
10586         if (!success)
10587             return false;
10588 
10589         EmulateInstruction::Context context;
10590         if (n == 13)
10591             context.type = eContextPushRegisterOnStack;
10592         else
10593             context.type = eContextRegisterStore;
10594         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10595 
10596         const uint32_t addr_byte_size = GetAddressByteSize();
10597 
10598         if (!MemAWrite (context, address, data, addr_byte_size))
10599             return false;
10600 
10601         //MemA[address+4,4] = R[t2];
10602         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10603         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10604 
10605         data = ReadCoreReg (t2, &success);
10606         if (!success)
10607             return false;
10608 
10609         if (!MemAWrite (context, address + 4, data, addr_byte_size))
10610             return false;
10611 
10612         //if wback then R[n] = offset_addr;
10613         if (wback)
10614         {
10615             context.type = eContextAdjustBaseRegister;
10616             context.SetAddress (offset_addr);
10617 
10618             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10619                 return false;
10620         }
10621     }
10622     return true;
10623 }
10624 
10625 
10626 // A8.6.201 STRD (register)
10627 bool
10628 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding)
10629 {
10630 #if 0
10631     if ConditionPassed() then
10632         EncodingSpecificOperations();
10633         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10634         address = if index then offset_addr else R[n];
10635         MemA[address,4] = R[t];
10636         MemA[address+4,4] = R[t2];
10637         if wback then R[n] = offset_addr;
10638 #endif
10639 
10640     bool success = false;
10641 
10642     if (ConditionPassed(opcode))
10643     {
10644         uint32_t t;
10645         uint32_t t2;
10646         uint32_t n;
10647         uint32_t m;
10648         bool index;
10649         bool add;
10650         bool wback;
10651 
10652         switch (encoding)
10653         {
10654             case eEncodingA1:
10655                 // if Rt<0> == '1' then UNPREDICTABLE;
10656                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10657                 t = Bits32 (opcode, 15, 12);
10658                 if (BitIsSet (t, 0))
10659                    return false;
10660 
10661                 t2 = t+1;
10662                 n = Bits32 (opcode, 19, 16);
10663                 m = Bits32 (opcode, 3, 0);
10664 
10665                 // index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1');
10666                 index = BitIsSet (opcode, 24);
10667                 add = BitIsSet (opcode, 23);
10668                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10669 
10670                 // if P == '0' && W == '1' then UNPREDICTABLE;
10671                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10672                    return false;
10673 
10674                 // if t2 == 15 || m == 15 then UNPREDICTABLE;
10675                 if ((t2 == 15) || (m == 15))
10676                    return false;
10677 
10678                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10679                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10680                    return false;
10681 
10682                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10683                 if ((ArchVersion() < 6) && wback && (m == n))
10684                    return false;
10685 
10686                 break;
10687 
10688             default:
10689                 return false;
10690         }
10691 
10692         RegisterInfo base_reg;
10693         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10694         RegisterInfo offset_reg;
10695         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10696         RegisterInfo data_reg;
10697 
10698         uint32_t Rn = ReadCoreReg (n, &success);
10699         if (!success)
10700             return false;
10701 
10702         uint32_t Rm = ReadCoreReg (m, &success);
10703         if (!success)
10704             return false;
10705 
10706         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10707         addr_t offset_addr;
10708         if (add)
10709             offset_addr = Rn + Rm;
10710         else
10711             offset_addr = Rn - Rm;
10712 
10713         // address = if index then offset_addr else R[n];
10714         addr_t address;
10715         if (index)
10716             address = offset_addr;
10717         else
10718             address = Rn;
10719                           // MemA[address,4] = R[t];
10720         uint32_t Rt = ReadCoreReg (t, &success);
10721         if (!success)
10722             return false;
10723 
10724         EmulateInstruction::Context context;
10725         if (t == 13)
10726             context.type = eContextPushRegisterOnStack;
10727         else
10728             context.type = eContextRegisterStore;
10729 
10730         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10731         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10732 
10733         const uint32_t addr_byte_size = GetAddressByteSize();
10734 
10735         if (!MemAWrite (context, address, Rt, addr_byte_size))
10736             return false;
10737 
10738         // MemA[address+4,4] = R[t2];
10739         uint32_t Rt2 = ReadCoreReg (t2, &success);
10740         if (!success)
10741             return false;
10742 
10743         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10744 
10745         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10746 
10747         if (!MemAWrite (context, address + 4, Rt2, addr_byte_size))
10748             return false;
10749 
10750         // if wback then R[n] = offset_addr;
10751         if (wback)
10752         {
10753             context.type = eContextAdjustBaseRegister;
10754             context.SetAddress (offset_addr);
10755 
10756             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10757                 return false;
10758 
10759         }
10760     }
10761     return true;
10762 }
10763 
10764 // A8.6.319 VLDM
10765 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from
10766 // an ARM core register.
10767 bool
10768 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding)
10769 {
10770 #if 0
10771     if ConditionPassed() then
10772         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10773         address = if add then R[n] else R[n]-imm32;
10774         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10775         for r = 0 to regs-1
10776             if single_regs then
10777                 S[d+r] = MemA[address,4]; address = address+4;
10778             else
10779                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10780                 // Combine the word-aligned words in the correct order for current endianness.
10781                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10782 #endif
10783 
10784     bool success = false;
10785 
10786     if (ConditionPassed(opcode))
10787     {
10788         bool single_regs;
10789         bool add;
10790         bool wback;
10791         uint32_t d;
10792         uint32_t n;
10793         uint32_t imm32;
10794         uint32_t regs;
10795 
10796         switch (encoding)
10797         {
10798             case eEncodingT1:
10799             case eEncodingA1:
10800                 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
10801                 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
10802                 // if P == '1' && W == '0' then SEE VLDR;
10803                 // if P == U && W == '1' then UNDEFINED;
10804                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10805                     return false;
10806 
10807                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10808                 // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
10809                 single_regs = false;
10810                 add = BitIsSet (opcode, 23);
10811                 wback = BitIsSet (opcode, 21);
10812 
10813                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
10814                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10815                 n = Bits32 (opcode, 19, 16);
10816                 imm32 = Bits32 (opcode, 7, 0) << 2;
10817 
10818                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FLDMX'.
10819                 regs = Bits32 (opcode, 7, 0) / 2;
10820 
10821                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10822                 if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
10823                     return false;
10824 
10825                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10826                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10827                     return false;
10828 
10829                 break;
10830 
10831             case eEncodingT2:
10832             case eEncodingA2:
10833                 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
10834                 // if P == '0' && U == '1' && W == '1' && Rn == '1101' then SEE VPOP;
10835                 // if P == '1' && W == '0' then SEE VLDR;
10836                 // if P == U && W == '1' then UNDEFINED;
10837                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10838                     return false;
10839 
10840                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10841                 // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn);
10842                 single_regs = true;
10843                 add = BitIsSet (opcode, 23);
10844                 wback = BitIsSet (opcode, 21);
10845                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10846                 n = Bits32 (opcode, 19, 16);
10847 
10848                 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
10849                 imm32 = Bits32 (opcode, 7, 0) << 2;
10850                 regs = Bits32 (opcode, 7, 0);
10851 
10852                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10853                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10854                     return false;
10855 
10856                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10857                 if ((regs == 0) || ((d + regs) > 32))
10858                     return false;
10859                 break;
10860 
10861             default:
10862                 return false;
10863         }
10864 
10865         RegisterInfo base_reg;
10866         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10867 
10868         uint32_t Rn = ReadCoreReg (n, &success);
10869         if (!success)
10870             return false;
10871 
10872         // address = if add then R[n] else R[n]-imm32;
10873         addr_t address;
10874         if (add)
10875             address = Rn;
10876         else
10877             address = Rn - imm32;
10878 
10879         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10880         EmulateInstruction::Context context;
10881 
10882         if (wback)
10883         {
10884             uint32_t value;
10885             if (add)
10886                 value = Rn + imm32;
10887             else
10888                 value = Rn - imm32;
10889 
10890             context.type = eContextAdjustBaseRegister;
10891             context.SetImmediateSigned (value - Rn);
10892             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10893                 return false;
10894 
10895         }
10896 
10897         const uint32_t addr_byte_size = GetAddressByteSize();
10898         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10899 
10900         context.type = eContextRegisterLoad;
10901 
10902         // for r = 0 to regs-1
10903         for (uint32_t r = 0; r < regs; ++r)
10904         {
10905             if (single_regs)
10906             {
10907                 // S[d+r] = MemA[address,4]; address = address+4;
10908                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10909 
10910                 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10911                 if (!success)
10912                     return false;
10913 
10914                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10915                     return false;
10916 
10917                 address = address + 4;
10918             }
10919             else
10920             {
10921                 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10922                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10923                 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10924                 if (!success)
10925                     return false;
10926 
10927                 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10928                 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10929                 if (!success)
10930                     return false;
10931 
10932                 address = address + 8;
10933                 // // Combine the word-aligned words in the correct order for current endianness.
10934                 // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10935                 uint64_t data;
10936                 if (GetByteOrder() == eByteOrderBig)
10937                 {
10938                     data = word1;
10939                     data = (data << 32) | word2;
10940                 }
10941                 else
10942                 {
10943                     data = word2;
10944                     data = (data << 32) | word1;
10945                 }
10946 
10947                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10948                     return false;
10949             }
10950         }
10951     }
10952     return true;
10953 }
10954 
10955 // A8.6.399 VSTM
10956 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an
10957 // ARM core register.
10958 bool
10959 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding)
10960 {
10961 #if 0
10962     if ConditionPassed() then
10963         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10964         address = if add then R[n] else R[n]-imm32;
10965         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10966         for r = 0 to regs-1
10967             if single_regs then
10968                 MemA[address,4] = S[d+r]; address = address+4;
10969             else
10970                 // Store as two word-aligned words in the correct order for current endianness.
10971                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10972                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10973                 address = address+8;
10974 #endif
10975 
10976     bool success = false;
10977 
10978     if (ConditionPassed (opcode))
10979     {
10980         bool single_regs;
10981         bool add;
10982         bool wback;
10983         uint32_t d;
10984         uint32_t n;
10985         uint32_t imm32;
10986         uint32_t regs;
10987 
10988         switch (encoding)
10989         {
10990             case eEncodingT1:
10991             case eEncodingA1:
10992                 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
10993                 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
10994                 // if P == '1' && W == '0' then SEE VSTR;
10995                 // if P == U && W == '1' then UNDEFINED;
10996                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10997                     return false;
10998 
10999                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
11000                 // single_regs = FALSE; add = (U == '1'); wback = (W == '1');
11001                 single_regs = false;
11002                 add = BitIsSet (opcode, 23);
11003                 wback = BitIsSet (opcode, 21);
11004 
11005                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:'00', 32);
11006                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11007                 n = Bits32 (opcode, 19, 16);
11008                 imm32 = Bits32 (opcode, 7, 0) << 2;
11009 
11010                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see 'FSTMX'.
11011                 regs = Bits32 (opcode, 7, 0) / 2;
11012 
11013                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
11014                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
11015                     return false;
11016 
11017                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
11018                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
11019                     return false;
11020 
11021                 break;
11022 
11023             case eEncodingT2:
11024             case eEncodingA2:
11025                 // if P == '0' && U == '0' && W == '0' then SEE 'Related encodings';
11026                 // if P == '1' && U == '0' && W == '1' && Rn == '1101' then SEE VPUSH;
11027                 // if P == '1' && W == '0' then SEE VSTR;
11028                 // if P == U && W == '1' then UNDEFINED;
11029                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
11030                     return false;
11031 
11032                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
11033                 // single_regs = TRUE; add = (U == '1'); wback = (W == '1'); d = UInt(Vd:D); n = UInt(Rn);
11034                 single_regs = true;
11035                 add = BitIsSet (opcode, 23);
11036                 wback = BitIsSet (opcode, 21);
11037                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11038                 n = Bits32 (opcode, 19, 16);
11039 
11040                 // imm32 = ZeroExtend(imm8:'00', 32); regs = UInt(imm8);
11041                 imm32 = Bits32 (opcode, 7, 0) << 2;
11042                 regs = Bits32 (opcode, 7, 0);
11043 
11044                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
11045                 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM)))
11046                     return false;
11047 
11048                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
11049                 if ((regs == 0) || ((d + regs) > 32))
11050                     return false;
11051 
11052                 break;
11053 
11054             default:
11055                 return false;
11056         }
11057 
11058         RegisterInfo base_reg;
11059         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11060 
11061         uint32_t Rn = ReadCoreReg (n, &success);
11062         if (!success)
11063             return false;
11064 
11065         // address = if add then R[n] else R[n]-imm32;
11066         addr_t address;
11067         if (add)
11068             address = Rn;
11069         else
11070             address = Rn - imm32;
11071 
11072         EmulateInstruction::Context context;
11073         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
11074         if (wback)
11075         {
11076             uint32_t value;
11077             if (add)
11078                 value = Rn + imm32;
11079             else
11080                 value = Rn - imm32;
11081 
11082             context.type = eContextAdjustBaseRegister;
11083             context.SetRegisterPlusOffset (base_reg, value - Rn);
11084 
11085             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11086                 return false;
11087         }
11088 
11089         const uint32_t addr_byte_size = GetAddressByteSize();
11090         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
11091 
11092         context.type = eContextRegisterStore;
11093         // for r = 0 to regs-1
11094         for (uint32_t r = 0; r < regs; ++r)
11095         {
11096 
11097             if (single_regs)
11098             {
11099                 // MemA[address,4] = S[d+r]; address = address+4;
11100                 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
11101                 if (!success)
11102                     return false;
11103 
11104                 RegisterInfo data_reg;
11105                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
11106                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11107                 if (!MemAWrite (context, address, data, addr_byte_size))
11108                     return false;
11109 
11110                 address = address + 4;
11111             }
11112             else
11113             {
11114                 // // Store as two word-aligned words in the correct order for current endianness.
11115                 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
11116                 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
11117                 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
11118                 if (!success)
11119                     return false;
11120 
11121                 RegisterInfo data_reg;
11122                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
11123 
11124                 if (GetByteOrder() == eByteOrderBig)
11125                 {
11126                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11127                     if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11128                         return false;
11129 
11130                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11131                     if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size))
11132                         return false;
11133                 }
11134                 else
11135                 {
11136                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11137                     if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11138                         return false;
11139 
11140                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11141                     if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11142                         return false;
11143                 }
11144                 // address = address+8;
11145                 address = address + 8;
11146             }
11147         }
11148     }
11149     return true;
11150 }
11151 
11152 // A8.6.320
11153 // This instruction loads a single extension register from memory, using an address from an ARM core register, with
11154 // an optional offset.
11155 bool
11156 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
11157 {
11158 #if 0
11159     if ConditionPassed() then
11160         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11161         base = if n == 15 then Align(PC,4) else R[n];
11162         address = if add then (base + imm32) else (base - imm32);
11163         if single_reg then
11164             S[d] = MemA[address,4];
11165         else
11166             word1 = MemA[address,4]; word2 = MemA[address+4,4];
11167             // Combine the word-aligned words in the correct order for current endianness.
11168             D[d] = if BigEndian() then word1:word2 else word2:word1;
11169 #endif
11170 
11171     bool success = false;
11172 
11173     if (ConditionPassed (opcode))
11174     {
11175         bool single_reg;
11176         bool add;
11177         uint32_t imm32;
11178         uint32_t d;
11179         uint32_t n;
11180 
11181         switch (encoding)
11182         {
11183             case eEncodingT1:
11184             case eEncodingA1:
11185                 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11186                 single_reg = false;
11187                 add = BitIsSet (opcode, 23);
11188                 imm32 = Bits32 (opcode, 7, 0) << 2;
11189 
11190                 // d = UInt(D:Vd); n = UInt(Rn);
11191                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11192                 n = Bits32 (opcode, 19, 16);
11193 
11194                 break;
11195 
11196             case eEncodingT2:
11197             case eEncodingA2:
11198                 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11199                 single_reg = true;
11200                 add = BitIsSet (opcode, 23);
11201                 imm32 = Bits32 (opcode, 7, 0) << 2;
11202 
11203                 // d = UInt(Vd:D); n = UInt(Rn);
11204                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11205                 n = Bits32 (opcode, 19, 16);
11206 
11207                 break;
11208 
11209             default:
11210                 return false;
11211         }
11212         RegisterInfo base_reg;
11213         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11214 
11215         uint32_t Rn = ReadCoreReg (n, &success);
11216         if (!success)
11217             return false;
11218 
11219         // base = if n == 15 then Align(PC,4) else R[n];
11220         uint32_t base;
11221         if (n == 15)
11222             base = AlignPC (Rn);
11223         else
11224             base = Rn;
11225 
11226         // address = if add then (base + imm32) else (base - imm32);
11227         addr_t address;
11228         if (add)
11229             address = base + imm32;
11230         else
11231             address = base - imm32;
11232 
11233         const uint32_t addr_byte_size = GetAddressByteSize();
11234         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11235 
11236         EmulateInstruction::Context context;
11237         context.type = eContextRegisterLoad;
11238         context.SetRegisterPlusOffset (base_reg, address - base);
11239 
11240         if (single_reg)
11241         {
11242             // S[d] = MemA[address,4];
11243             uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
11244             if (!success)
11245                 return false;
11246 
11247             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data))
11248                 return false;
11249         }
11250         else
11251         {
11252             // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11253             uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
11254             if (!success)
11255                 return false;
11256 
11257             context.SetRegisterPlusOffset (base_reg, (address + 4) - base);
11258             uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
11259             if (!success)
11260                 return false;
11261             // // Combine the word-aligned words in the correct order for current endianness.
11262             // D[d] = if BigEndian() then word1:word2 else word2:word1;
11263             uint64_t data64;
11264             if (GetByteOrder() == eByteOrderBig)
11265             {
11266                 data64 = word1;
11267                 data64 = (data64 << 32) | word2;
11268             }
11269             else
11270             {
11271                 data64 = word2;
11272                 data64 = (data64 << 32) | word1;
11273             }
11274 
11275             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64))
11276                 return false;
11277         }
11278     }
11279     return true;
11280 }
11281 
11282 // A8.6.400 VSTR
11283 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an
11284 // optional offset.
11285 bool
11286 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
11287 {
11288 #if 0
11289     if ConditionPassed() then
11290         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11291         address = if add then (R[n] + imm32) else (R[n] - imm32);
11292         if single_reg then
11293             MemA[address,4] = S[d];
11294         else
11295             // Store as two word-aligned words in the correct order for current endianness.
11296             MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11297             MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11298 #endif
11299 
11300     bool success = false;
11301 
11302     if (ConditionPassed (opcode))
11303     {
11304         bool single_reg;
11305         bool add;
11306         uint32_t imm32;
11307         uint32_t d;
11308         uint32_t n;
11309 
11310         switch (encoding)
11311         {
11312             case eEncodingT1:
11313             case eEncodingA1:
11314                 // single_reg = FALSE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11315                 single_reg = false;
11316                 add = BitIsSet (opcode, 23);
11317                 imm32 = Bits32 (opcode, 7, 0) << 2;
11318 
11319                 // d = UInt(D:Vd); n = UInt(Rn);
11320                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11321                 n = Bits32 (opcode, 19, 16);
11322 
11323                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11324                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11325                     return false;
11326 
11327                 break;
11328 
11329             case eEncodingT2:
11330             case eEncodingA2:
11331                 // single_reg = TRUE; add = (U == '1'); imm32 = ZeroExtend(imm8:'00', 32);
11332                 single_reg = true;
11333                 add = BitIsSet (opcode, 23);
11334                 imm32 = Bits32 (opcode, 7, 0) << 2;
11335 
11336                 // d = UInt(Vd:D); n = UInt(Rn);
11337                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11338                 n = Bits32 (opcode, 19, 16);
11339 
11340                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11341                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11342                     return false;
11343 
11344                 break;
11345 
11346             default:
11347                 return false;
11348         }
11349 
11350         RegisterInfo base_reg;
11351         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11352 
11353         uint32_t Rn = ReadCoreReg (n, &success);
11354         if (!success)
11355             return false;
11356 
11357         // address = if add then (R[n] + imm32) else (R[n] - imm32);
11358         addr_t address;
11359         if (add)
11360             address = Rn + imm32;
11361         else
11362             address = Rn - imm32;
11363 
11364         const uint32_t addr_byte_size = GetAddressByteSize();
11365         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11366 
11367         RegisterInfo data_reg;
11368         GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg);
11369         EmulateInstruction::Context context;
11370         context.type = eContextRegisterStore;
11371         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11372 
11373         if (single_reg)
11374         {
11375             // MemA[address,4] = S[d];
11376             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11377             if (!success)
11378                 return false;
11379 
11380             if (!MemAWrite (context, address, data, addr_byte_size))
11381                 return false;
11382         }
11383         else
11384         {
11385             // // Store as two word-aligned words in the correct order for current endianness.
11386             // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11387             // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11388             uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11389             if (!success)
11390                 return false;
11391 
11392             if (GetByteOrder() == eByteOrderBig)
11393             {
11394                 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11395                     return false;
11396 
11397                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11398                 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size))
11399                     return false;
11400             }
11401             else
11402             {
11403                 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11404                     return false;
11405 
11406                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11407                 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11408                     return false;
11409             }
11410         }
11411     }
11412     return true;
11413 }
11414 
11415 // A8.6.307 VLDI1 (multiple single elements)
11416 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving.  Every
11417 // element of each register is loaded.
11418 bool
11419 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding)
11420 {
11421 #if 0
11422     if ConditionPassed() then
11423         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11424         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11425         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11426         for r = 0 to regs-1
11427             for e = 0 to elements-1
11428                 Elem[D[d+r],e,esize] = MemU[address,ebytes];
11429                 address = address + ebytes;
11430 #endif
11431 
11432     bool success = false;
11433 
11434     if (ConditionPassed (opcode))
11435     {
11436         uint32_t regs;
11437         uint32_t alignment;
11438         uint32_t ebytes;
11439         uint32_t esize;
11440         uint32_t elements;
11441         uint32_t d;
11442         uint32_t n;
11443         uint32_t m;
11444         bool wback;
11445         bool register_index;
11446 
11447         switch (encoding)
11448         {
11449             case eEncodingT1:
11450             case eEncodingA1:
11451             {
11452                 // case type of
11453                     // when '0111'
11454                         // regs = 1; if align<1> == '1' then UNDEFINED;
11455                     // when '1010'
11456                         // regs = 2; if align == '11' then UNDEFINED;
11457                     // when '0110'
11458                         // regs = 3; if align<1> == '1' then UNDEFINED;
11459                     // when '0010'
11460                         // regs = 4;
11461                     // otherwise
11462                         // SEE 'Related encodings';
11463                 uint32_t type = Bits32 (opcode, 11, 8);
11464                 uint32_t align = Bits32 (opcode, 5, 4);
11465                 if (type == 7) // '0111'
11466                 {
11467                     regs = 1;
11468                     if (BitIsSet (align, 1))
11469                         return false;
11470                 }
11471                 else if (type == 10) // '1010'
11472                 {
11473                     regs = 2;
11474                     if (align == 3)
11475                         return false;
11476 
11477                 }
11478                 else if (type == 6) // '0110'
11479                 {
11480                     regs = 3;
11481                     if (BitIsSet (align, 1))
11482                         return false;
11483                 }
11484                 else if (type == 2) // '0010'
11485                 {
11486                     regs = 4;
11487                 }
11488                 else
11489                     return false;
11490 
11491                 // alignment = if align == '00' then 1 else 4 << UInt(align);
11492                 if (align == 0)
11493                     alignment = 1;
11494                 else
11495                     alignment = 4 << align;
11496 
11497                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11498                 ebytes = 1 << Bits32 (opcode, 7, 6);
11499                 esize = 8 * ebytes;
11500                 elements = 8 / ebytes;
11501 
11502                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11503                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11504                 n = Bits32 (opcode, 19, 15);
11505                 m = Bits32 (opcode, 3, 0);
11506 
11507                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11508                 wback = (m != 15);
11509                 register_index = ((m != 15) && (m != 13));
11510 
11511                 // if d+regs > 32 then UNPREDICTABLE;
11512                 if ((d + regs) > 32)
11513                     return false;
11514             }
11515                 break;
11516 
11517             default:
11518                 return false;
11519         }
11520 
11521         RegisterInfo base_reg;
11522         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11523 
11524         uint32_t Rn = ReadCoreReg (n, &success);
11525         if (!success)
11526             return false;
11527 
11528         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11529         addr_t address = Rn;
11530         if ((address % alignment) != 0)
11531             return false;
11532 
11533         EmulateInstruction::Context context;
11534         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11535         if (wback)
11536         {
11537             uint32_t Rm = ReadCoreReg (m, &success);
11538             if (!success)
11539                 return false;
11540 
11541             uint32_t offset;
11542             if (register_index)
11543                 offset = Rm;
11544             else
11545                 offset = 8 * regs;
11546 
11547             uint32_t value = Rn + offset;
11548             context.type = eContextAdjustBaseRegister;
11549             context.SetRegisterPlusOffset (base_reg, offset);
11550 
11551             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11552                 return false;
11553 
11554         }
11555 
11556         // for r = 0 to regs-1
11557         for (uint32_t r = 0; r < regs; ++r)
11558         {
11559             // for e = 0 to elements-1
11560             uint64_t assembled_data = 0;
11561             for (uint32_t e = 0; e < elements; ++e)
11562             {
11563                 // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11564                 context.type = eContextRegisterLoad;
11565                 context.SetRegisterPlusOffset (base_reg, address - Rn);
11566                 uint64_t data = MemURead (context, address, ebytes, 0, &success);
11567                 if (!success)
11568                     return false;
11569 
11570                 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data
11571 
11572                 // address = address + ebytes;
11573                 address = address + ebytes;
11574             }
11575             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data))
11576                 return false;
11577         }
11578     }
11579     return true;
11580 }
11581 
11582 // A8.6.308 VLD1 (single element to one lane)
11583 //
11584 bool
11585 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding)
11586 {
11587 #if 0
11588     if ConditionPassed() then
11589         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11590         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11591         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11592         Elem[D[d],index,esize] = MemU[address,ebytes];
11593 #endif
11594 
11595     bool success = false;
11596 
11597     if (ConditionPassed (opcode))
11598     {
11599         uint32_t ebytes;
11600         uint32_t esize;
11601         uint32_t index;
11602         uint32_t alignment;
11603         uint32_t d;
11604         uint32_t n;
11605         uint32_t m;
11606         bool wback;
11607         bool register_index;
11608 
11609         switch (encoding)
11610         {
11611             case eEncodingT1:
11612             case eEncodingA1:
11613             {
11614                 uint32_t size = Bits32 (opcode, 11, 10);
11615                 uint32_t index_align = Bits32 (opcode, 7, 4);
11616                 // if size == '11' then SEE VLD1 (single element to all lanes);
11617                 if (size == 3)
11618                    return EmulateVLD1SingleAll (opcode, encoding);
11619                 // case size of
11620                 if (size == 0) // when '00'
11621                 {
11622                     // if index_align<0> != '0' then UNDEFINED;
11623                     if (BitIsClear (index_align, 0))
11624                         return false;
11625 
11626                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11627                     ebytes = 1;
11628                     esize = 8;
11629                     index = Bits32 (index_align, 3, 1);
11630                     alignment = 1;
11631                 }
11632                 else if (size == 1) // when '01'
11633                 {
11634                     // if index_align<1> != '0' then UNDEFINED;
11635                     if (BitIsClear (index_align, 1))
11636                         return false;
11637 
11638                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11639                     ebytes = 2;
11640                     esize = 16;
11641                     index = Bits32 (index_align, 3, 2);
11642 
11643                     // alignment = if index_align<0> == '0' then 1 else 2;
11644                     if (BitIsClear (index_align, 0))
11645                         alignment = 1;
11646                     else
11647                         alignment = 2;
11648                 }
11649                 else if (size == 2) // when '10'
11650                 {
11651                     // if index_align<2> != '0' then UNDEFINED;
11652                     if (BitIsClear (index_align, 2))
11653                         return false;
11654 
11655                     // if index_align<1:0> != '00' && index_align<1:0> != '11' then UNDEFINED;
11656                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11657                         return false;
11658 
11659                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11660                     ebytes = 4;
11661                     esize = 32;
11662                     index = Bit32 (index_align, 3);
11663 
11664                     // alignment = if index_align<1:0> == '00' then 1 else 4;
11665                     if (Bits32 (index_align, 1, 0) == 0)
11666                         alignment = 1;
11667                     else
11668                         alignment = 4;
11669                 }
11670                 else
11671                 {
11672                     return false;
11673                 }
11674                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11675                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11676                 n = Bits32 (opcode, 19, 16);
11677                 m = Bits32 (opcode, 3, 0);
11678 
11679                 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
11680                 wback = (m != 15);
11681                 register_index = ((m != 15) && (m != 13));
11682 
11683                 if (n == 15)
11684                     return false;
11685 
11686             }
11687                 break;
11688 
11689             default:
11690                 return false;
11691         }
11692 
11693         RegisterInfo base_reg;
11694         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11695 
11696         uint32_t Rn = ReadCoreReg (n, &success);
11697         if (!success)
11698             return false;
11699 
11700         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11701         addr_t address = Rn;
11702         if ((address % alignment) != 0)
11703             return false;
11704 
11705         EmulateInstruction::Context context;
11706         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11707         if (wback)
11708         {
11709             uint32_t Rm = ReadCoreReg (m, &success);
11710             if (!success)
11711                 return false;
11712 
11713             uint32_t offset;
11714             if (register_index)
11715                 offset = Rm;
11716             else
11717                 offset = ebytes;
11718 
11719             uint32_t value = Rn + offset;
11720 
11721             context.type = eContextAdjustBaseRegister;
11722             context.SetRegisterPlusOffset (base_reg, offset);
11723 
11724             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11725                 return false;
11726         }
11727 
11728         // Elem[D[d],index,esize] = MemU[address,ebytes];
11729         uint32_t element = MemURead (context, address, esize, 0, &success);
11730         if (!success)
11731             return false;
11732 
11733         element = element << (index * esize);
11734 
11735         uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11736         if (!success)
11737             return false;
11738 
11739         uint64_t all_ones = -1;
11740         uint64_t mask = all_ones << ((index+1) * esize);  // mask is all 1's to left of where 'element' goes, & all 0's
11741                                                           // at element & to the right of element.
11742         if (index > 0)
11743             mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes.
11744                                                                      // now mask should be 0's where element goes & 1's
11745                                                                      // everywhere else.
11746 
11747         uint64_t masked_reg = reg_data & mask;  // Take original reg value & zero out 'element' bits
11748         reg_data = masked_reg & element;        // Put 'element' into those bits in reg_data.
11749 
11750         context.type = eContextRegisterLoad;
11751         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data))
11752             return false;
11753     }
11754     return true;
11755 }
11756 
11757 // A8.6.391 VST1 (multiple single elements)
11758 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four registers, without
11759 // interleaving.  Every element of each register is stored.
11760 bool
11761 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding)
11762 {
11763 #if 0
11764     if ConditionPassed() then
11765         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11766         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11767         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11768         for r = 0 to regs-1
11769             for e = 0 to elements-1
11770                 MemU[address,ebytes] = Elem[D[d+r],e,esize];
11771                 address = address + ebytes;
11772 #endif
11773 
11774     bool success = false;
11775 
11776     if (ConditionPassed (opcode))
11777     {
11778         uint32_t regs;
11779         uint32_t alignment;
11780         uint32_t ebytes;
11781         uint32_t esize;
11782         uint32_t elements;
11783         uint32_t d;
11784         uint32_t n;
11785         uint32_t m;
11786         bool wback;
11787         bool register_index;
11788 
11789         switch (encoding)
11790         {
11791             case eEncodingT1:
11792             case eEncodingA1:
11793             {
11794                 uint32_t type = Bits32 (opcode, 11, 8);
11795                 uint32_t align = Bits32 (opcode, 5, 4);
11796 
11797                 // case type of
11798                 if (type == 7)    // when '0111'
11799                 {
11800                     // regs = 1; if align<1> == '1' then UNDEFINED;
11801                     regs = 1;
11802                     if (BitIsSet (align, 1))
11803                         return false;
11804                 }
11805                 else if (type == 10) // when '1010'
11806                 {
11807                     // regs = 2; if align == '11' then UNDEFINED;
11808                     regs = 2;
11809                     if (align == 3)
11810                         return false;
11811                 }
11812                 else if (type == 6) // when '0110'
11813                 {
11814                     // regs = 3; if align<1> == '1' then UNDEFINED;
11815                     regs = 3;
11816                     if (BitIsSet (align, 1))
11817                         return false;
11818                 }
11819                 else if (type == 2) // when '0010'
11820                     // regs = 4;
11821                     regs = 4;
11822                 else // otherwise
11823                     // SEE 'Related encodings';
11824                     return false;
11825 
11826                 // alignment = if align == '00' then 1 else 4 << UInt(align);
11827                 if (align == 0)
11828                     alignment = 1;
11829                 else
11830                     alignment = 4 << align;
11831 
11832                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11833                 ebytes = 1 << Bits32 (opcode,7, 6);
11834                 esize = 8 * ebytes;
11835                 elements = 8 / ebytes;
11836 
11837                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11838                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11839                 n = Bits32 (opcode, 19, 16);
11840                 m = Bits32 (opcode, 3, 0);
11841 
11842                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11843                 wback = (m != 15);
11844                 register_index = ((m != 15) && (m != 13));
11845 
11846                 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11847                 if ((d + regs) > 32)
11848                     return false;
11849 
11850                 if (n == 15)
11851                     return false;
11852 
11853             }
11854                 break;
11855 
11856             default:
11857                 return false;
11858         }
11859 
11860         RegisterInfo base_reg;
11861         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11862 
11863         uint32_t Rn = ReadCoreReg (n, &success);
11864         if (!success)
11865             return false;
11866 
11867         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11868         addr_t address = Rn;
11869         if ((address % alignment) != 0)
11870             return false;
11871 
11872         EmulateInstruction::Context context;
11873         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11874         if (wback)
11875         {
11876             uint32_t Rm = ReadCoreReg (m, &success);
11877             if (!success)
11878                 return false;
11879 
11880             uint32_t offset;
11881             if (register_index)
11882                 offset = Rm;
11883             else
11884                 offset = 8 * regs;
11885 
11886             context.type = eContextAdjustBaseRegister;
11887             context.SetRegisterPlusOffset (base_reg, offset);
11888 
11889             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11890                 return false;
11891         }
11892 
11893         RegisterInfo data_reg;
11894         context.type = eContextRegisterStore;
11895         // for r = 0 to regs-1
11896         for (uint32_t r = 0; r < regs; ++r)
11897         {
11898             GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
11899             uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
11900             if (!success)
11901                 return false;
11902 
11903              // for e = 0 to elements-1
11904             for (uint32_t e = 0; e < elements; ++e)
11905             {
11906                 // MemU[address,ebytes] = Elem[D[d+r],e,esize];
11907                 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize);
11908 
11909                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11910                 if (!MemUWrite (context, address, word, ebytes))
11911                     return false;
11912 
11913                 // address = address + ebytes;
11914                 address = address + ebytes;
11915             }
11916         }
11917     }
11918     return true;
11919 }
11920 
11921 // A8.6.392 VST1 (single element from one lane)
11922 // This instruction stores one element to memory from one element of a register.
11923 bool
11924 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding)
11925 {
11926 #if 0
11927     if ConditionPassed() then
11928         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11929         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11930         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11931         MemU[address,ebytes] = Elem[D[d],index,esize];
11932 #endif
11933 
11934     bool success = false;
11935 
11936     if (ConditionPassed (opcode))
11937     {
11938         uint32_t ebytes;
11939         uint32_t esize;
11940         uint32_t index;
11941         uint32_t alignment;
11942         uint32_t d;
11943         uint32_t n;
11944         uint32_t m;
11945         bool wback;
11946         bool register_index;
11947 
11948         switch (encoding)
11949         {
11950             case eEncodingT1:
11951             case eEncodingA1:
11952             {
11953                 uint32_t size = Bits32 (opcode, 11, 10);
11954                 uint32_t index_align = Bits32 (opcode, 7, 4);
11955 
11956                 // if size == '11' then UNDEFINED;
11957                 if (size == 3)
11958                     return false;
11959 
11960                 // case size of
11961                 if (size == 0) // when '00'
11962                 {
11963                     // if index_align<0> != '0' then UNDEFINED;
11964                     if (BitIsClear (index_align, 0))
11965                         return false;
11966                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11967                     ebytes = 1;
11968                     esize = 8;
11969                     index = Bits32 (index_align, 3, 1);
11970                     alignment = 1;
11971                 }
11972                 else if (size == 1) // when '01'
11973                 {
11974                     // if index_align<1> != '0' then UNDEFINED;
11975                     if (BitIsClear (index_align, 1))
11976                         return false;
11977 
11978                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11979                     ebytes = 2;
11980                     esize = 16;
11981                     index = Bits32 (index_align, 3, 2);
11982 
11983                     // alignment = if index_align<0> == '0' then 1 else 2;
11984                     if (BitIsClear (index_align, 0))
11985                         alignment = 1;
11986                     else
11987                         alignment = 2;
11988                 }
11989                 else if (size == 2) // when '10'
11990                 {
11991                     // if index_align<2> != '0' then UNDEFINED;
11992                     if (BitIsClear (index_align, 2))
11993                         return false;
11994 
11995                     // if index_align<1:0> != '00' && index_align<1:0> != '11' then UNDEFINED;
11996                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11997                         return false;
11998 
11999                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
12000                     ebytes = 4;
12001                     esize = 32;
12002                     index = Bit32 (index_align, 3);
12003 
12004                     // alignment = if index_align<1:0> == '00' then 1 else 4;
12005                     if (Bits32 (index_align, 1, 0) == 0)
12006                         alignment = 1;
12007                     else
12008                         alignment = 4;
12009                 }
12010                 else
12011                 {
12012                     return false;
12013                 }
12014                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12015                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
12016                 n = Bits32 (opcode, 19, 16);
12017                 m = Bits32 (opcode, 3, 0);
12018 
12019                 // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15 then UNPREDICTABLE;
12020                 wback = (m != 15);
12021                 register_index = ((m != 15) && (m != 13));
12022 
12023                 if (n == 15)
12024                     return false;
12025             }
12026                 break;
12027 
12028             default:
12029                 return false;
12030         }
12031 
12032         RegisterInfo base_reg;
12033         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12034 
12035         uint32_t Rn = ReadCoreReg (n, &success);
12036         if (!success)
12037             return false;
12038 
12039         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12040         addr_t address = Rn;
12041         if ((address % alignment) != 0)
12042             return false;
12043 
12044         EmulateInstruction::Context context;
12045         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12046         if (wback)
12047         {
12048             uint32_t Rm = ReadCoreReg (m, &success);
12049             if (!success)
12050                 return false;
12051 
12052             uint32_t offset;
12053             if (register_index)
12054                 offset = Rm;
12055             else
12056                 offset = ebytes;
12057 
12058             context.type = eContextAdjustBaseRegister;
12059             context.SetRegisterPlusOffset (base_reg, offset);
12060 
12061             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
12062                 return false;
12063         }
12064 
12065         // MemU[address,ebytes] = Elem[D[d],index,esize];
12066         uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
12067         if (!success)
12068             return false;
12069 
12070         uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1,  index * esize);
12071 
12072         RegisterInfo data_reg;
12073         GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg);
12074         context.type = eContextRegisterStore;
12075         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
12076 
12077         if (!MemUWrite (context, address, word, ebytes))
12078             return false;
12079     }
12080     return true;
12081 }
12082 
12083 // A8.6.309 VLD1 (single element to all lanes)
12084 // This instruction loads one element from memory into every element of one or two vectors.
12085 bool
12086 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding)
12087 {
12088 #if 0
12089     if ConditionPassed() then
12090         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
12091         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12092         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12093         replicated_element = Replicate(MemU[address,ebytes], elements);
12094         for r = 0 to regs-1
12095             D[d+r] = replicated_element;
12096 #endif
12097 
12098     bool success = false;
12099 
12100     if (ConditionPassed (opcode))
12101     {
12102         uint32_t ebytes;
12103         uint32_t elements;
12104         uint32_t regs;
12105         uint32_t alignment;
12106         uint32_t d;
12107         uint32_t n;
12108         uint32_t m;
12109         bool wback;
12110         bool register_index;
12111 
12112         switch (encoding)
12113         {
12114             case eEncodingT1:
12115             case eEncodingA1:
12116             {
12117                 //if size == '11' || (size == '00' && a == '1') then UNDEFINED;
12118                 uint32_t size = Bits32 (opcode, 7, 6);
12119                 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4)))
12120                     return false;
12121 
12122                 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == '0' then 1 else 2;
12123                 ebytes = 1 << size;
12124                 elements = 8 / ebytes;
12125                 if (BitIsClear (opcode, 5))
12126                     regs = 1;
12127                 else
12128                     regs = 2;
12129 
12130                 //alignment = if a == '0' then 1 else ebytes;
12131                 if (BitIsClear (opcode, 4))
12132                     alignment = 1;
12133                 else
12134                     alignment = ebytes;
12135 
12136                 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
12137                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
12138                 n = Bits32 (opcode, 19, 16);
12139                 m = Bits32 (opcode, 3, 0);
12140 
12141                 //wback = (m != 15); register_index = (m != 15 && m != 13);
12142                 wback = (m != 15);
12143                 register_index = ((m != 15) && (m != 13));
12144 
12145                 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12146                 if ((d + regs) > 32)
12147                     return false;
12148 
12149                 if (n == 15)
12150                     return false;
12151             }
12152             break;
12153 
12154             default:
12155                 return false;
12156         }
12157 
12158         RegisterInfo base_reg;
12159         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12160 
12161         uint32_t Rn = ReadCoreReg (n, &success);
12162         if (!success)
12163             return false;
12164 
12165         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12166         addr_t address = Rn;
12167         if ((address % alignment) != 0)
12168             return false;
12169 
12170         EmulateInstruction::Context context;
12171         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12172         if (wback)
12173         {
12174             uint32_t Rm = ReadCoreReg (m, &success);
12175             if (!success)
12176                 return false;
12177 
12178             uint32_t offset;
12179             if (register_index)
12180                 offset = Rm;
12181             else
12182                 offset = ebytes;
12183 
12184             context.type = eContextAdjustBaseRegister;
12185             context.SetRegisterPlusOffset (base_reg, offset);
12186 
12187             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
12188                 return false;
12189         }
12190 
12191         // replicated_element = Replicate(MemU[address,ebytes], elements);
12192 
12193         context.type = eContextRegisterLoad;
12194         uint64_t word = MemURead (context, address, ebytes, 0, &success);
12195         if (!success)
12196             return false;
12197 
12198         uint64_t replicated_element = 0;
12199         uint32_t esize = ebytes * 8;
12200         for (uint32_t e = 0; e < elements; ++e)
12201             replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0);
12202 
12203         // for r = 0 to regs-1
12204         for (uint32_t r = 0; r < regs; ++r)
12205         {
12206             // D[d+r] = replicated_element;
12207             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element))
12208                 return false;
12209         }
12210     }
12211     return true;
12212 }
12213 
12214 // B6.2.13 SUBS PC, LR and related instructions
12215 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack.  It subtracts the
12216 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR.
12217 bool
12218 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding)
12219 {
12220 #if 0
12221     if ConditionPassed() then
12222         EncodingSpecificOperations();
12223         if CurrentInstrSet() == InstrSet_ThumbEE then
12224             UNPREDICTABLE;
12225         operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12226         case opcode of
12227             when '0000' result = R[n] AND operand2; // AND
12228             when '0001' result = R[n] EOR operand2; // EOR
12229             when '0010' (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12230             when '0011' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12231             when '0100' (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12232             when '0101' (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12233             when '0110' (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12234             when '0111' (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12235             when '1100' result = R[n] OR operand2; // ORR
12236             when '1101' result = operand2; // MOV
12237             when '1110' result = R[n] AND NOT(operand2); // BIC
12238             when '1111' result = NOT(operand2); // MVN
12239         CPSRWriteByInstr(SPSR[], '1111', TRUE);
12240         BranchWritePC(result);
12241 #endif
12242 
12243     bool success = false;
12244 
12245     if (ConditionPassed (opcode))
12246     {
12247         uint32_t n;
12248         uint32_t m;
12249         uint32_t imm32;
12250         bool register_form;
12251         ARM_ShifterType shift_t;
12252         uint32_t shift_n;
12253         uint32_t code;
12254 
12255         switch (encoding)
12256         {
12257             case eEncodingT1:
12258                 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
12259                 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = '0010'; // = SUB
12260                 n = 14;
12261                 imm32 = Bits32 (opcode, 7, 0);
12262                 register_form = false;
12263                 code = 2;
12264 
12265                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12266                 if (InITBlock() && !LastInITBlock())
12267                     return false;
12268 
12269                 break;
12270 
12271             case eEncodingA1:
12272                 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12273                 n = Bits32 (opcode, 19, 16);
12274                 imm32 = ARMExpandImm (opcode);
12275                 register_form = false;
12276                 code = Bits32 (opcode, 24, 21);
12277 
12278                 break;
12279 
12280             case eEncodingA2:
12281                 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12282                 n = Bits32 (opcode, 19, 16);
12283                 m = Bits32 (opcode, 3, 0);
12284                 register_form = true;
12285 
12286                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12287                 shift_n = DecodeImmShiftARM (opcode, shift_t);
12288 
12289                 break;
12290 
12291             default:
12292                 return false;
12293         }
12294 
12295         // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12296         uint32_t operand2;
12297         if (register_form)
12298         {
12299             uint32_t Rm = ReadCoreReg (m, &success);
12300             if (!success)
12301                 return false;
12302 
12303             operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success);
12304             if (!success)
12305                 return false;
12306         }
12307         else
12308         {
12309             operand2 = imm32;
12310         }
12311 
12312         uint32_t Rn = ReadCoreReg (n, &success);
12313         if (!success)
12314             return false;
12315 
12316         AddWithCarryResult result;
12317 
12318         // case opcode of
12319         switch (code)
12320         {
12321             case 0: // when '0000'
12322                 // result = R[n] AND operand2; // AND
12323                 result.result = Rn & operand2;
12324                 break;
12325 
12326             case 1: // when '0001'
12327                 // result = R[n] EOR operand2; // EOR
12328                 result.result = Rn ^ operand2;
12329                 break;
12330 
12331             case 2: // when '0010'
12332                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), '1'); // SUB
12333                 result = AddWithCarry (Rn, ~(operand2), 1);
12334                 break;
12335 
12336             case 3: // when '0011'
12337                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, '1'); // RSB
12338                 result = AddWithCarry (~(Rn), operand2, 1);
12339                 break;
12340 
12341             case 4: // when '0100'
12342                 // (result, -, -) = AddWithCarry(R[n], operand2, '0'); // ADD
12343                 result = AddWithCarry (Rn, operand2, 0);
12344                 break;
12345 
12346             case 5: // when '0101'
12347                 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12348                 result = AddWithCarry (Rn, operand2, APSR_C);
12349                 break;
12350 
12351             case 6: // when '0110'
12352                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12353                 result = AddWithCarry (Rn, ~(operand2), APSR_C);
12354                 break;
12355 
12356             case 7: // when '0111'
12357                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12358                 result = AddWithCarry (~(Rn), operand2, APSR_C);
12359                 break;
12360 
12361             case 10: // when '1100'
12362                 // result = R[n] OR operand2; // ORR
12363                 result.result = Rn | operand2;
12364                 break;
12365 
12366             case 11: // when '1101'
12367                 // result = operand2; // MOV
12368                 result.result = operand2;
12369                 break;
12370 
12371             case 12: // when '1110'
12372                 // result = R[n] AND NOT(operand2); // BIC
12373                 result.result = Rn & ~(operand2);
12374                 break;
12375 
12376             case 15: // when '1111'
12377                 // result = NOT(operand2); // MVN
12378                 result.result = ~(operand2);
12379                 break;
12380 
12381             default:
12382                 return false;
12383         }
12384         // CPSRWriteByInstr(SPSR[], '1111', TRUE);
12385 
12386         // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for
12387         // the best.
12388         uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12389         if (!success)
12390             return false;
12391 
12392         CPSRWriteByInstr (spsr, 15, true);
12393 
12394         // BranchWritePC(result);
12395         EmulateInstruction::Context context;
12396         context.type = eContextAdjustPC;
12397         context.SetImmediate (result.result);
12398 
12399         BranchWritePC (context, result.result);
12400     }
12401     return true;
12402 }
12403 
12404 EmulateInstructionARM::ARMOpcode*
12405 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12406 {
12407     static ARMOpcode
12408     g_arm_opcodes[] =
12409     {
12410         //----------------------------------------------------------------------
12411         // Prologue instructions
12412         //----------------------------------------------------------------------
12413 
12414         // push register(s)
12415         { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12416         { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
12417 
12418         // set r7 to point to a stack offset
12419         { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
12420         { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12421         // copy the stack pointer to ip
12422         { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
12423         { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
12424         { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12425 
12426         // adjust the stack pointer
12427         { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12428         { 0x0fef0010, 0x004d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12429 
12430         // push one register
12431         // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12432         { 0x0e5f0000, 0x040d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
12433 
12434         // vector push consecutive extension register(s)
12435         { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12436         { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12437 
12438         //----------------------------------------------------------------------
12439         // Epilogue instructions
12440         //----------------------------------------------------------------------
12441 
12442         { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12443         { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12444         { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12445         { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12446 
12447         //----------------------------------------------------------------------
12448         // Supervisor Call (previously Software Interrupt)
12449         //----------------------------------------------------------------------
12450         { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12451 
12452         //----------------------------------------------------------------------
12453         // Branch instructions
12454         //----------------------------------------------------------------------
12455         // To resolve ambiguity, "blx <label>" should come before "b #imm24" and "bl <label>".
12456         { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12457         { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
12458         { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12459         { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12460         // for example, "bx lr"
12461         { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12462         // bxj
12463         { 0x0ffffff0, 0x012fff20, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12464 
12465         //----------------------------------------------------------------------
12466         // Data-processing instructions
12467         //----------------------------------------------------------------------
12468         // adc (immediate)
12469         { 0x0fe00000, 0x02a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12470         // adc (register)
12471         { 0x0fe00010, 0x00a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12472         // add (immediate)
12473         { 0x0fe00000, 0x02800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
12474         // add (register)
12475         { 0x0fe00010, 0x00800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12476         // add (register-shifted register)
12477         { 0x0fe00090, 0x00800010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12478         // adr
12479         { 0x0fff0000, 0x028f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12480         { 0x0fff0000, 0x024f0000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12481         // and (immediate)
12482         { 0x0fe00000, 0x02000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12483         // and (register)
12484         { 0x0fe00010, 0x00000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12485         // bic (immediate)
12486         { 0x0fe00000, 0x03c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12487         // bic (register)
12488         { 0x0fe00010, 0x01c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12489         // eor (immediate)
12490         { 0x0fe00000, 0x02200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12491         // eor (register)
12492         { 0x0fe00010, 0x00200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12493         // orr (immediate)
12494         { 0x0fe00000, 0x03800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12495         // orr (register)
12496         { 0x0fe00010, 0x01800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12497         // rsb (immediate)
12498         { 0x0fe00000, 0x02600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12499         // rsb (register)
12500         { 0x0fe00010, 0x00600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12501         // rsc (immediate)
12502         { 0x0fe00000, 0x02e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12503         // rsc (register)
12504         { 0x0fe00010, 0x00e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12505         // sbc (immediate)
12506         { 0x0fe00000, 0x02c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12507         // sbc (register)
12508         { 0x0fe00010, 0x00c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12509         // sub (immediate, ARM)
12510         { 0x0fe00000, 0x02400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
12511         // sub (sp minus immediate)
12512         { 0x0fef0000, 0x024d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12513         // sub (register)
12514         { 0x0fe00010, 0x00400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12515         // teq (immediate)
12516         { 0x0ff0f000, 0x03300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12517         // teq (register)
12518         { 0x0ff0f010, 0x01300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12519         // tst (immediate)
12520         { 0x0ff0f000, 0x03100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12521         // tst (register)
12522         { 0x0ff0f010, 0x01100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12523 
12524         // mov (immediate)
12525         { 0x0fef0000, 0x03a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12526         { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
12527         // mov (register)
12528         { 0x0fef0ff0, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12529         // mvn (immediate)
12530         { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12531         // mvn (register)
12532         { 0x0fef0010, 0x01e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12533         // cmn (immediate)
12534         { 0x0ff0f000, 0x03700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12535         // cmn (register)
12536         { 0x0ff0f010, 0x01700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12537         // cmp (immediate)
12538         { 0x0ff0f000, 0x03500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
12539         // cmp (register)
12540         { 0x0ff0f010, 0x01500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
12541         // asr (immediate)
12542         { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
12543         // asr (register)
12544         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
12545         // lsl (immediate)
12546         { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
12547         // lsl (register)
12548         { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
12549         // lsr (immediate)
12550         { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
12551         // lsr (register)
12552         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
12553         // rrx is a special case encoding of ror (immediate)
12554         { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
12555         // ror (immediate)
12556         { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
12557         // ror (register)
12558         { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
12559         // mul
12560         { 0x0fe000f0, 0x00000090, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
12561 
12562         // subs pc, lr and related instructions
12563         { 0x0e10f000, 0x0210f000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" },
12564         { 0x0e10f010, 0x0010f000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" },
12565 
12566         //----------------------------------------------------------------------
12567         // Load instructions
12568         //----------------------------------------------------------------------
12569         { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12570         { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
12571         { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12572         { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
12573         { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
12574         { 0x0e500010, 0x06100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
12575         { 0x0e5f0000, 0x045f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
12576         { 0xfe500010, 0x06500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
12577         { 0x0e5f00f0, 0x005f00b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12578         { 0x0e5000f0, 0x001000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"  },
12579         { 0x0e5000f0, 0x005000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
12580         { 0x0e5f00f0, 0x005f00d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
12581         { 0x0e5000f0, 0x001000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12582         { 0x0e5000f0, 0x005000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
12583         { 0x0e5f00f0, 0x005f00f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12584         { 0x0e5000f0, 0x001000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12585         { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
12586         { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12587         { 0x0e100f00, 0x0c100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12588         { 0x0e100f00, 0x0c100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12589         { 0x0f300f00, 0x0d100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12590         { 0x0f300f00, 0x0d100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12591         { 0xffb00000, 0xf4200000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12592         { 0xffb00300, 0xf4a00000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12593         { 0xffb00f00, 0xf4a00c00, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12594 
12595         //----------------------------------------------------------------------
12596         // Store instructions
12597         //----------------------------------------------------------------------
12598         { 0x0fd00000, 0x08800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12599         { 0x0fd00000, 0x08000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
12600         { 0x0fd00000, 0x09000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12601         { 0x0fd00000, 0x09800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
12602         { 0x0e500010, 0x06000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
12603         { 0x0e5000f0, 0x000000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
12604         { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
12605         { 0x0e500000, 0x04400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12606         { 0x0e500000, 0x04000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12607         { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
12608         { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12609         { 0x0e100f00, 0x0c000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12610         { 0x0e100f00, 0x0c000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12611         { 0x0f300f00, 0x0d000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
12612         { 0x0f300f00, 0x0d000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
12613         { 0xffb00000, 0xf4000000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12614         { 0xffb00300, 0xf4800000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12615 
12616         //----------------------------------------------------------------------
12617         // Other instructions
12618         //----------------------------------------------------------------------
12619         { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
12620         { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
12621         { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
12622         { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
12623         { 0xfe500000, 0xf8100000, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
12624 
12625     };
12626     static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_arm_opcodes);
12627 
12628     for (size_t i=0; i<k_num_arm_opcodes; ++i)
12629     {
12630         if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
12631             (g_arm_opcodes[i].variants & arm_isa) != 0)
12632             return &g_arm_opcodes[i];
12633     }
12634     return NULL;
12635 }
12636 
12637 
12638 EmulateInstructionARM::ARMOpcode*
12639 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12640 {
12641 
12642     static ARMOpcode
12643     g_thumb_opcodes[] =
12644     {
12645         //----------------------------------------------------------------------
12646         // Prologue instructions
12647         //----------------------------------------------------------------------
12648 
12649         // push register(s)
12650         { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12651         { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
12652         { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
12653 
12654         // set r7 to point to a stack offset
12655         { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
12656         // copy the stack pointer to r7
12657         { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
12658         // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
12659         { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
12660 
12661         // PC-relative load into register (see also EmulateADDSPRm)
12662         { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
12663 
12664         // adjust the stack pointer
12665         { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
12666         { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
12667         { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
12668         { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
12669         { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12670 
12671         // vector push consecutive extension register(s)
12672         { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12673         { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12674 
12675         //----------------------------------------------------------------------
12676         // Epilogue instructions
12677         //----------------------------------------------------------------------
12678 
12679         { 0xfffff800, 0x0000a800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
12680         { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
12681         { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12682         { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
12683         { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
12684         { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12685         { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12686 
12687         //----------------------------------------------------------------------
12688         // Supervisor Call (previously Software Interrupt)
12689         //----------------------------------------------------------------------
12690         { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
12691 
12692         //----------------------------------------------------------------------
12693         // If Then makes up to four following instructions conditional.
12694         //----------------------------------------------------------------------
12695         // The next 5 opcode _must_ come before the if then instruction
12696         { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"},
12697         { 0xffffffff, 0x0000bf10, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
12698         { 0xffffffff, 0x0000bf20, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
12699         { 0xffffffff, 0x0000bf30, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
12700         { 0xffffffff, 0x0000bf40, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
12701         { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
12702 
12703         //----------------------------------------------------------------------
12704         // Branch instructions
12705         //----------------------------------------------------------------------
12706         // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
12707         { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
12708         { 0xfffff800, 0x0000e000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
12709         { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
12710         { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
12711         // J1 == J2 == 1
12712         { 0xf800d000, 0xf000d000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12713         // J1 == J2 == 1
12714         { 0xf800d001, 0xf000c000, ARMV5_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12715         { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12716         // for example, "bx lr"
12717         { 0xffffff87, 0x00004700, ARMvAll,       eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12718         // bxj
12719         { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12720         // compare and branch
12721         { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
12722         // table branch byte
12723         { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
12724         // table branch halfword
12725         { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
12726 
12727         //----------------------------------------------------------------------
12728         // Data-processing instructions
12729         //----------------------------------------------------------------------
12730         // adc (immediate)
12731         { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
12732         // adc (register)
12733         { 0xffffffc0, 0x00004140, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
12734         { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12735         // add (register)
12736         { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
12737         // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
12738         { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
12739         // adr
12740         { 0xfffff800, 0x0000a000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12741         { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12742         { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12743         // and (immediate)
12744         { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
12745         // and (register)
12746         { 0xffffffc0, 0x00004000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
12747         { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12748         // bic (immediate)
12749         { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
12750         // bic (register)
12751         { 0xffffffc0, 0x00004380, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
12752         { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12753         // eor (immediate)
12754         { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
12755         // eor (register)
12756         { 0xffffffc0, 0x00004040, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
12757         { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12758         // orr (immediate)
12759         { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
12760         // orr (register)
12761         { 0xffffffc0, 0x00004300, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
12762         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12763         // rsb (immediate)
12764         { 0xffffffc0, 0x00004240, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
12765         { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
12766         // rsb (register)
12767         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12768         // sbc (immediate)
12769         { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12770         // sbc (register)
12771         { 0xffffffc0, 0x00004180, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
12772         { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12773         // add (immediate, Thumb)
12774         { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
12775         { 0xfffff800, 0x00003000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
12776         { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
12777         { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
12778         // sub (immediate, Thumb)
12779         { 0xfffffe00, 0x00001e00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
12780         { 0xfffff800, 0x00003800, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
12781         { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
12782         { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
12783         // sub (sp minus immediate)
12784         { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
12785         { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
12786         // sub (register)
12787         { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
12788         { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
12789         // teq (immediate)
12790         { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
12791         // teq (register)
12792         { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12793         // tst (immediate)
12794         { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
12795         // tst (register)
12796         { 0xffffffc0, 0x00004200, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
12797         { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
12798 
12799 
12800         // move from high register to high register
12801         { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
12802         // move from low register to low register
12803         { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
12804         // mov{s}<c>.w <Rd>, <Rm>
12805         { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
12806         // move immediate
12807         { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
12808         { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
12809         { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
12810         // mvn (immediate)
12811         { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
12812         // mvn (register)
12813         { 0xffffffc0, 0x000043c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
12814         { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
12815         // cmn (immediate)
12816         { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12817         // cmn (register)
12818         { 0xffffffc0, 0x000042c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
12819         { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12820         // cmp (immediate)
12821         { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
12822         { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
12823         // cmp (register) (Rn and Rm both from r0-r7)
12824         { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12825         // cmp (register) (Rn and Rm not both from r0-r7)
12826         { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12827         { 0xfff08f00, 0xebb00f00, ARMvAll,       eEncodingT3, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c>.w <Rn>, <Rm> {, <shift>}"},
12828         // asr (immediate)
12829         { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
12830         { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
12831         // asr (register)
12832         { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
12833         { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12834         // lsl (immediate)
12835         { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
12836         { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
12837         // lsl (register)
12838         { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
12839         { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
12840         // lsr (immediate)
12841         { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
12842         { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
12843         // lsr (register)
12844         { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
12845         { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12846         // rrx is a special case encoding of ror (immediate)
12847         { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
12848         // ror (immediate)
12849         { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
12850         // ror (register)
12851         { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
12852         { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
12853         // mul
12854         { 0xffffffc0, 0x00004340, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
12855         // mul
12856         { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
12857 
12858         // subs pc, lr and related instructions
12859         { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" },
12860 
12861         //----------------------------------------------------------------------
12862         // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table;
12863         // otherwise the wrong instructions will be selected.
12864         //----------------------------------------------------------------------
12865 
12866         { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
12867         { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
12868 
12869         //----------------------------------------------------------------------
12870         // Load instructions
12871         //----------------------------------------------------------------------
12872         { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12873         { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
12874         { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12875         { 0xfffff800, 0x00006800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
12876         { 0xfffff800, 0x00009800, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
12877         { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
12878         { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
12879                   // Thumb2 PC-relative load into register
12880         { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
12881         { 0xfffffe00, 0x00005800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
12882         { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
12883         { 0xfffff800, 0x00007800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
12884         { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12885         { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" },
12886         { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
12887         { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
12888         { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
12889         { 0xfffff800, 0x00008800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"  },
12890         { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12891         { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"  },
12892         { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12893         { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
12894         { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12895         { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
12896         { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12897         { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
12898         { 0xfffffe00, 0x00005600, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
12899         { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"  },
12900         { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
12901         { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12902         { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12903         { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
12904         { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12905         { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
12906         { 0xfe100f00, 0xec100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12907         { 0xfe100f00, 0xec100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
12908         { 0xffe00f00, 0xed100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12909         { 0xff300f00, 0xed100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
12910         { 0xffb00000, 0xf9200000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12911         { 0xffb00300, 0xf9a00000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12912         { 0xffb00f00, 0xf9a00c00, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12913 
12914         //----------------------------------------------------------------------
12915         // Store instructions
12916         //----------------------------------------------------------------------
12917         { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12918         { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
12919         { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12920         { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
12921         { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
12922         { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
12923         { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
12924         { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
12925         { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
12926         { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
12927         { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
12928         { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
12929         { 0xfffffe00, 0x00005200, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
12930         { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12931         { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
12932         { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
12933         { 0xfe100f00, 0xec000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12934         { 0xfea00f00, 0xec000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12935         { 0xff300f00, 0xed000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12936         { 0xff300f00, 0xed000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12937         { 0xffb00000, 0xf9000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12938         { 0xffb00300, 0xf9800000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12939 
12940         //----------------------------------------------------------------------
12941         // Other instructions
12942         //----------------------------------------------------------------------
12943         { 0xffffffc0, 0x0000b240, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
12944         { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12945         { 0xffffffc0, 0x0000b200, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
12946         { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12947         { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
12948         { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12949         { 0xffffffc0, 0x0000b280, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
12950         { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12951     };
12952 
12953     const size_t k_num_thumb_opcodes = llvm::array_lengthof(g_thumb_opcodes);
12954     for (size_t i=0; i<k_num_thumb_opcodes; ++i)
12955     {
12956         if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
12957             (g_thumb_opcodes[i].variants & arm_isa) != 0)
12958             return &g_thumb_opcodes[i];
12959     }
12960     return NULL;
12961 }
12962 
12963 bool
12964 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
12965 {
12966     m_arch = arch;
12967     m_arm_isa = 0;
12968     const char *arch_cstr = arch.GetArchitectureName ();
12969     if (arch_cstr)
12970     {
12971         if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
12972         else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
12973         else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
12974         else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
12975         else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
12976         else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
12977         else if (0 == ::strcasecmp(arch_cstr, "armv7s"))    m_arm_isa = ARMv7S;
12978         else if (0 == ::strcasecmp(arch_cstr, "arm"))       m_arm_isa = ARMvAll;
12979         else if (0 == ::strcasecmp(arch_cstr, "thumb"))     m_arm_isa = ARMvAll;
12980         else if (0 == ::strncasecmp(arch_cstr,"armv4", 5))  m_arm_isa = ARMv4;
12981         else if (0 == ::strncasecmp(arch_cstr,"armv6", 5))  m_arm_isa = ARMv6;
12982         else if (0 == ::strncasecmp(arch_cstr,"armv7", 5))  m_arm_isa = ARMv7;
12983         else if (0 == ::strncasecmp(arch_cstr,"armv8", 5))  m_arm_isa = ARMv8;
12984     }
12985     return m_arm_isa != 0;
12986 }
12987 
12988 bool
12989 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
12990 {
12991     if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
12992     {
12993         if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
12994             m_opcode_mode = eModeThumb;
12995         else
12996         {
12997             AddressClass addr_class = inst_addr.GetAddressClass();
12998 
12999             if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
13000                 m_opcode_mode = eModeARM;
13001             else if (addr_class == eAddressClassCodeAlternateISA)
13002                 m_opcode_mode = eModeThumb;
13003             else
13004                 return false;
13005         }
13006         if (m_opcode_mode == eModeThumb)
13007             m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
13008         else
13009             m_opcode_cpsr = CPSR_MODE_USR;
13010         return true;
13011     }
13012     return false;
13013 }
13014 
13015 bool
13016 EmulateInstructionARM::ReadInstruction ()
13017 {
13018     bool success = false;
13019     m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
13020     if (success)
13021     {
13022         addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
13023         if (success)
13024         {
13025             Context read_inst_context;
13026             read_inst_context.type = eContextReadOpcode;
13027             read_inst_context.SetNoArgs ();
13028 
13029             if (m_opcode_cpsr & MASK_CPSR_T)
13030             {
13031                 m_opcode_mode = eModeThumb;
13032                 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
13033 
13034                 if (success)
13035                 {
13036                     if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
13037                     {
13038                         m_opcode.SetOpcode16 (thumb_opcode, GetByteOrder());
13039                     }
13040                     else
13041                     {
13042                         m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success), GetByteOrder());
13043                     }
13044                 }
13045             }
13046             else
13047             {
13048                 m_opcode_mode = eModeARM;
13049                 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success), GetByteOrder());
13050             }
13051         }
13052     }
13053     if (!success)
13054     {
13055         m_opcode_mode = eModeInvalid;
13056         m_addr = LLDB_INVALID_ADDRESS;
13057     }
13058     return success;
13059 }
13060 
13061 uint32_t
13062 EmulateInstructionARM::ArchVersion ()
13063 {
13064     return m_arm_isa;
13065 }
13066 
13067 bool
13068 EmulateInstructionARM::ConditionPassed (const uint32_t opcode)
13069 {
13070    // If we are ignoring conditions, then always return true.
13071    // this allows us to iterate over disassembly code and still
13072    // emulate an instruction even if we don't have all the right
13073    // bits set in the CPSR register...
13074     if (m_ignore_conditions)
13075         return true;
13076 
13077     const uint32_t cond = CurrentCond (opcode);
13078     if (cond == UINT32_MAX)
13079         return false;
13080 
13081     bool result = false;
13082     switch (UnsignedBits(cond, 3, 1))
13083     {
13084     case 0:
13085 		if (m_opcode_cpsr == 0)
13086 			result = true;
13087         else
13088             result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
13089 		break;
13090     case 1:
13091         if (m_opcode_cpsr == 0)
13092             result = true;
13093         else
13094             result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
13095 		break;
13096     case 2:
13097         if (m_opcode_cpsr == 0)
13098             result = true;
13099         else
13100             result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
13101 		break;
13102     case 3:
13103         if (m_opcode_cpsr == 0)
13104             result = true;
13105         else
13106             result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
13107 		break;
13108     case 4:
13109         if (m_opcode_cpsr == 0)
13110             result = true;
13111         else
13112             result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13113 		break;
13114     case 5:
13115         if (m_opcode_cpsr == 0)
13116             result = true;
13117         else
13118 		{
13119             bool n = (m_opcode_cpsr & MASK_CPSR_N);
13120             bool v = (m_opcode_cpsr & MASK_CPSR_V);
13121             result = n == v;
13122         }
13123         break;
13124     case 6:
13125         if (m_opcode_cpsr == 0)
13126             result = true;
13127         else
13128 		{
13129             bool n = (m_opcode_cpsr & MASK_CPSR_N);
13130             bool v = (m_opcode_cpsr & MASK_CPSR_V);
13131             result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
13132         }
13133         break;
13134     case 7:
13135         // Always execute (cond == 0b1110, or the special 0b1111 which gives
13136         // opcodes different meanings, but always means execution happens.
13137         return true;
13138     }
13139 
13140     if (cond & 1)
13141         result = !result;
13142     return result;
13143 }
13144 
13145 uint32_t
13146 EmulateInstructionARM::CurrentCond (const uint32_t opcode)
13147 {
13148     switch (m_opcode_mode)
13149     {
13150     case eModeInvalid:
13151         break;
13152 
13153     case eModeARM:
13154         return UnsignedBits(opcode, 31, 28);
13155 
13156     case eModeThumb:
13157         // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
13158         // 'cond' field of the encoding.
13159         {
13160             const uint32_t byte_size = m_opcode.GetByteSize();
13161             if (byte_size == 2)
13162             {
13163                 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 8) != 0x0f)
13164                     return Bits32(opcode, 11, 8);
13165             }
13166             else if (byte_size == 4)
13167             {
13168                 if (Bits32(opcode, 31, 27) == 0x1e &&
13169                     Bits32(opcode, 15, 14) == 0x02 &&
13170                     Bits32(opcode, 12, 12) == 0x00 &&
13171                     Bits32(opcode, 25, 22) <= 0x0d)
13172                 {
13173                     return Bits32(opcode, 25, 22);
13174                 }
13175             }
13176             else
13177                 // We have an invalid thumb instruction, let's bail out.
13178                 break;
13179 
13180             return m_it_session.GetCond();
13181         }
13182     }
13183     return UINT32_MAX;  // Return invalid value
13184 }
13185 
13186 bool
13187 EmulateInstructionARM::InITBlock()
13188 {
13189     return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13190 }
13191 
13192 bool
13193 EmulateInstructionARM::LastInITBlock()
13194 {
13195     return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13196 }
13197 
13198 bool
13199 EmulateInstructionARM::BadMode (uint32_t mode)
13200 {
13201 
13202     switch (mode)
13203     {
13204         case 16: return false; // '10000'
13205         case 17: return false; // '10001'
13206         case 18: return false; // '10010'
13207         case 19: return false; // '10011'
13208         case 22: return false; // '10110'
13209         case 23: return false; // '10111'
13210         case 27: return false; // '11011'
13211         case 31: return false; // '11111'
13212         default: return true;
13213     }
13214     return true;
13215 }
13216 
13217 bool
13218 EmulateInstructionARM::CurrentModeIsPrivileged ()
13219 {
13220     uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
13221 
13222     if (BadMode (mode))
13223         return false;
13224 
13225     if (mode == 16)
13226         return false;
13227 
13228     return true;
13229 }
13230 
13231 void
13232 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
13233 {
13234     bool privileged = CurrentModeIsPrivileged();
13235 
13236     uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20;
13237 
13238     if (BitIsSet (bytemask, 3))
13239     {
13240         tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
13241         if (affect_execstate)
13242             tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
13243     }
13244 
13245     if (BitIsSet (bytemask, 2))
13246     {
13247         tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
13248     }
13249 
13250     if (BitIsSet (bytemask, 1))
13251     {
13252         if (affect_execstate)
13253             tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
13254         tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
13255         if (privileged)
13256             tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
13257     }
13258 
13259     if (BitIsSet (bytemask, 0))
13260     {
13261         if (privileged)
13262             tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
13263         if (affect_execstate)
13264             tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
13265         if (privileged)
13266             tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
13267     }
13268 
13269     m_opcode_cpsr = tmp_cpsr;
13270 }
13271 
13272 
13273 bool
13274 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
13275 {
13276     addr_t target;
13277 
13278     // Check the current instruction set.
13279     if (CurrentInstrSet() == eModeARM)
13280         target = addr & 0xfffffffc;
13281     else
13282         target = addr & 0xfffffffe;
13283 
13284     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13285         return false;
13286 
13287     return true;
13288 }
13289 
13290 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
13291 bool
13292 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
13293 {
13294     addr_t target;
13295     // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
13296     // we want to record it and issue a WriteRegister callback so the clients
13297     // can track the mode changes accordingly.
13298     bool cpsr_changed = false;
13299 
13300     if (BitIsSet(addr, 0))
13301     {
13302         if (CurrentInstrSet() != eModeThumb)
13303         {
13304             SelectInstrSet(eModeThumb);
13305             cpsr_changed = true;
13306         }
13307         target = addr & 0xfffffffe;
13308         context.SetISA (eModeThumb);
13309     }
13310     else if (BitIsClear(addr, 1))
13311     {
13312         if (CurrentInstrSet() != eModeARM)
13313         {
13314             SelectInstrSet(eModeARM);
13315             cpsr_changed = true;
13316         }
13317         target = addr & 0xfffffffc;
13318         context.SetISA (eModeARM);
13319     }
13320     else
13321         return false; // address<1:0> == '10' => UNPREDICTABLE
13322 
13323     if (cpsr_changed)
13324     {
13325         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13326             return false;
13327     }
13328     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13329         return false;
13330 
13331     return true;
13332 }
13333 
13334 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
13335 bool
13336 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
13337 {
13338     if (ArchVersion() >= ARMv5T)
13339         return BXWritePC(context, addr);
13340     else
13341         return BranchWritePC((const Context)context, addr);
13342 }
13343 
13344 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
13345 bool
13346 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
13347 {
13348     if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
13349         return BXWritePC(context, addr);
13350     else
13351         return BranchWritePC((const Context)context, addr);
13352 }
13353 
13354 EmulateInstructionARM::Mode
13355 EmulateInstructionARM::CurrentInstrSet ()
13356 {
13357     return m_opcode_mode;
13358 }
13359 
13360 // Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
13361 // ReadInstruction() is performed.  This function has a side effect of updating
13362 // the m_new_inst_cpsr member variable if necessary.
13363 bool
13364 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
13365 {
13366     m_new_inst_cpsr = m_opcode_cpsr;
13367     switch (arm_or_thumb)
13368     {
13369     default:
13370         return false;
13371     case eModeARM:
13372         // Clear the T bit.
13373         m_new_inst_cpsr &= ~MASK_CPSR_T;
13374         break;
13375     case eModeThumb:
13376         // Set the T bit.
13377         m_new_inst_cpsr |= MASK_CPSR_T;
13378         break;
13379     }
13380     return true;
13381 }
13382 
13383 // This function returns TRUE if the processor currently provides support for
13384 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
13385 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
13386 bool
13387 EmulateInstructionARM::UnalignedSupport()
13388 {
13389     return (ArchVersion() >= ARMv7);
13390 }
13391 
13392 // The main addition and subtraction instructions can produce status information
13393 // about both unsigned carry and signed overflow conditions.  This status
13394 // information can be used to synthesize multi-word additions and subtractions.
13395 EmulateInstructionARM::AddWithCarryResult
13396 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
13397 {
13398     uint32_t result;
13399     uint8_t carry_out;
13400     uint8_t overflow;
13401 
13402     uint64_t unsigned_sum = x + y + carry_in;
13403     int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
13404 
13405     result = UnsignedBits(unsigned_sum, 31, 0);
13406 //    carry_out = (result == unsigned_sum ? 0 : 1);
13407     overflow = ((int32_t)result == signed_sum ? 0 : 1);
13408 
13409     if (carry_in)
13410         carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0;
13411     else
13412         carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0;
13413 
13414     AddWithCarryResult res = { result, carry_out, overflow };
13415     return res;
13416 }
13417 
13418 uint32_t
13419 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
13420 {
13421     lldb::RegisterKind reg_kind;
13422     uint32_t reg_num;
13423     switch (num)
13424     {
13425     case SP_REG:
13426         reg_kind = eRegisterKindGeneric;
13427         reg_num  = LLDB_REGNUM_GENERIC_SP;
13428         break;
13429     case LR_REG:
13430         reg_kind = eRegisterKindGeneric;
13431         reg_num  = LLDB_REGNUM_GENERIC_RA;
13432         break;
13433     case PC_REG:
13434         reg_kind = eRegisterKindGeneric;
13435         reg_num  = LLDB_REGNUM_GENERIC_PC;
13436         break;
13437     default:
13438         if (num < SP_REG)
13439         {
13440             reg_kind = eRegisterKindDWARF;
13441             reg_num  = dwarf_r0 + num;
13442         }
13443         else
13444         {
13445             //assert(0 && "Invalid register number");
13446             *success = false;
13447             return UINT32_MAX;
13448         }
13449         break;
13450     }
13451 
13452     // Read our register.
13453     uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
13454 
13455     // When executing an ARM instruction , PC reads as the address of the current
13456     // instruction plus 8.
13457     // When executing a Thumb instruction , PC reads as the address of the current
13458     // instruction plus 4.
13459     if (num == 15)
13460     {
13461         if (CurrentInstrSet() == eModeARM)
13462             val += 8;
13463         else
13464             val += 4;
13465     }
13466 
13467     return val;
13468 }
13469 
13470 // Write the result to the ARM core register Rd, and optionally update the
13471 // condition flags based on the result.
13472 //
13473 // This helper method tries to encapsulate the following pseudocode from the
13474 // ARM Architecture Reference Manual:
13475 //
13476 // if d == 15 then         // Can only occur for encoding A1
13477 //     ALUWritePC(result); // setflags is always FALSE here
13478 // else
13479 //     R[d] = result;
13480 //     if setflags then
13481 //         APSR.N = result<31>;
13482 //         APSR.Z = IsZeroBit(result);
13483 //         APSR.C = carry;
13484 //         // APSR.V unchanged
13485 //
13486 // In the above case, the API client does not pass in the overflow arg, which
13487 // defaults to ~0u.
13488 bool
13489 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
13490                                                   const uint32_t result,
13491                                                   const uint32_t Rd,
13492                                                   bool setflags,
13493                                                   const uint32_t carry,
13494                                                   const uint32_t overflow)
13495 {
13496     if (Rd == 15)
13497     {
13498         if (!ALUWritePC (context, result))
13499             return false;
13500     }
13501     else
13502     {
13503         lldb::RegisterKind reg_kind;
13504         uint32_t reg_num;
13505         switch (Rd)
13506         {
13507         case SP_REG:
13508             reg_kind = eRegisterKindGeneric;
13509             reg_num  = LLDB_REGNUM_GENERIC_SP;
13510             break;
13511         case LR_REG:
13512             reg_kind = eRegisterKindGeneric;
13513             reg_num  = LLDB_REGNUM_GENERIC_RA;
13514             break;
13515         default:
13516             reg_kind = eRegisterKindDWARF;
13517             reg_num  = dwarf_r0 + Rd;
13518         }
13519         if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
13520             return false;
13521         if (setflags)
13522             return WriteFlags (context, result, carry, overflow);
13523     }
13524     return true;
13525 }
13526 
13527 // This helper method tries to encapsulate the following pseudocode from the
13528 // ARM Architecture Reference Manual:
13529 //
13530 // APSR.N = result<31>;
13531 // APSR.Z = IsZeroBit(result);
13532 // APSR.C = carry;
13533 // APSR.V = overflow
13534 //
13535 // Default arguments can be specified for carry and overflow parameters, which means
13536 // not to update the respective flags.
13537 bool
13538 EmulateInstructionARM::WriteFlags (Context &context,
13539                                    const uint32_t result,
13540                                    const uint32_t carry,
13541                                    const uint32_t overflow)
13542 {
13543     m_new_inst_cpsr = m_opcode_cpsr;
13544     SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
13545     SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
13546     if (carry != ~0u)
13547         SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
13548     if (overflow != ~0u)
13549         SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
13550     if (m_new_inst_cpsr != m_opcode_cpsr)
13551     {
13552         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13553             return false;
13554     }
13555     return true;
13556 }
13557 
13558 bool
13559 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
13560 {
13561     // Advance the ITSTATE bits to their values for the next instruction.
13562     if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
13563         m_it_session.ITAdvance();
13564 
13565     ARMOpcode *opcode_data = NULL;
13566 
13567     if (m_opcode_mode == eModeThumb)
13568         opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13569     else if (m_opcode_mode == eModeARM)
13570         opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13571 
13572     if (opcode_data == NULL)
13573         return false;
13574 
13575     const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
13576     m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
13577 
13578     bool success = false;
13579     if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
13580     {
13581         m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF,
13582                                                 dwarf_cpsr,
13583                                                 0,
13584                                                 &success);
13585     }
13586 
13587     // Only return false if we are unable to read the CPSR if we care about conditions
13588     if (success == false && m_ignore_conditions == false)
13589         return false;
13590 
13591     uint32_t orig_pc_value = 0;
13592     if (auto_advance_pc)
13593     {
13594         orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13595         if (!success)
13596             return false;
13597     }
13598 
13599     // Call the Emulate... function.
13600     success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
13601     if (!success)
13602         return false;
13603 
13604     if (auto_advance_pc)
13605     {
13606         uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13607         if (!success)
13608             return false;
13609 
13610         if (auto_advance_pc && (after_pc_value == orig_pc_value))
13611         {
13612             if (opcode_data->size == eSize32)
13613                 after_pc_value += 4;
13614             else if (opcode_data->size == eSize16)
13615                 after_pc_value += 2;
13616 
13617             EmulateInstruction::Context context;
13618             context.type = eContextAdvancePC;
13619             context.SetNoArgs();
13620             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
13621                 return false;
13622 
13623         }
13624     }
13625     return true;
13626 }
13627 
13628 bool
13629 EmulateInstructionARM::IsInstructionConditional()
13630 {
13631     const uint32_t cond = CurrentCond (m_opcode.GetOpcode32());
13632     return cond != 0xe && cond != 0xf && cond != UINT32_MAX;
13633 }
13634 
13635 bool
13636 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data)
13637 {
13638     if (!test_data)
13639     {
13640         out_stream->Printf ("TestEmulation: Missing test data.\n");
13641         return false;
13642     }
13643 
13644     static ConstString opcode_key ("opcode");
13645     static ConstString before_key ("before_state");
13646     static ConstString after_key ("after_state");
13647 
13648     OptionValueSP value_sp = test_data->GetValueForKey (opcode_key);
13649 
13650     uint32_t test_opcode;
13651     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64))
13652     {
13653         out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n");
13654         return false;
13655     }
13656     test_opcode = value_sp->GetUInt64Value ();
13657 
13658     if (arch.GetTriple().getArch() == llvm::Triple::arm)
13659     {
13660         m_opcode_mode = eModeARM;
13661         m_opcode.SetOpcode32 (test_opcode, GetByteOrder());
13662     }
13663     else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
13664     {
13665         m_opcode_mode = eModeThumb;
13666         if (test_opcode < 0x10000)
13667             m_opcode.SetOpcode16 (test_opcode, GetByteOrder());
13668         else
13669             m_opcode.SetOpcode32 (test_opcode, GetByteOrder());
13670 
13671     }
13672     else
13673     {
13674         out_stream->Printf ("TestEmulation:  Invalid arch.\n");
13675         return false;
13676     }
13677 
13678     EmulationStateARM before_state;
13679     EmulationStateARM after_state;
13680 
13681     value_sp = test_data->GetValueForKey (before_key);
13682     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13683     {
13684         out_stream->Printf ("TestEmulation:  Failed to find 'before' state.\n");
13685         return false;
13686     }
13687 
13688     OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary ();
13689     if (!before_state.LoadStateFromDictionary (state_dictionary))
13690     {
13691         out_stream->Printf ("TestEmulation:  Failed loading 'before' state.\n");
13692         return false;
13693     }
13694 
13695     value_sp = test_data->GetValueForKey (after_key);
13696     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13697     {
13698         out_stream->Printf ("TestEmulation:  Failed to find 'after' state.\n");
13699         return false;
13700     }
13701 
13702     state_dictionary = value_sp->GetAsDictionary ();
13703     if (!after_state.LoadStateFromDictionary (state_dictionary))
13704     {
13705         out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n");
13706         return false;
13707     }
13708 
13709     SetBaton ((void *) &before_state);
13710     SetCallbacks (&EmulationStateARM::ReadPseudoMemory,
13711                   &EmulationStateARM::WritePseudoMemory,
13712                   &EmulationStateARM::ReadPseudoRegister,
13713                   &EmulationStateARM::WritePseudoRegister);
13714 
13715     bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC);
13716     if (!success)
13717     {
13718         out_stream->Printf ("TestEmulation:  EvaluateInstruction() failed.\n");
13719         return false;
13720     }
13721 
13722     success = before_state.CompareState (after_state);
13723     if (!success)
13724         out_stream->Printf ("TestEmulation:  'before' and 'after' states do not match.\n");
13725 
13726     return success;
13727 }
13728 //
13729 //
13730 //const char *
13731 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
13732 //{
13733 //    if (reg_kind == eRegisterKindGeneric)
13734 //    {
13735 //        switch (reg_num)
13736 //        {
13737 //        case LLDB_REGNUM_GENERIC_PC:    return "pc";
13738 //        case LLDB_REGNUM_GENERIC_SP:    return "sp";
13739 //        case LLDB_REGNUM_GENERIC_FP:    return "fp";
13740 //        case LLDB_REGNUM_GENERIC_RA:    return "lr";
13741 //        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
13742 //        default: return NULL;
13743 //        }
13744 //    }
13745 //    else if (reg_kind == eRegisterKindDWARF)
13746 //    {
13747 //        return GetARMDWARFRegisterName (reg_num);
13748 //    }
13749 //    return NULL;
13750 //}
13751 //
13752 bool
13753 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
13754 {
13755     unwind_plan.Clear();
13756     unwind_plan.SetRegisterKind (eRegisterKindDWARF);
13757 
13758     UnwindPlan::RowSP row(new UnwindPlan::Row);
13759 
13760     // Our previous Call Frame Address is the stack pointer
13761     row->GetCFAValue().SetIsRegisterPlusOffset (dwarf_sp, 0);
13762 
13763     unwind_plan.AppendRow (row);
13764     unwind_plan.SetSourceName ("EmulateInstructionARM");
13765     unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
13766     unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
13767     unwind_plan.SetReturnAddressRegister (dwarf_lr);
13768     return true;
13769 }
13770