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/Support/MathExtras.h" // for SignExtend32 template function
28                                      // and CountTrailingZeros_32 function
29 
30 using namespace lldb;
31 using namespace lldb_private;
32 
33 // Convenient macro definitions.
34 #define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS)
35 #define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS)
36 
37 #define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
38 
39 //----------------------------------------------------------------------
40 //
41 // ITSession implementation
42 //
43 //----------------------------------------------------------------------
44 
45 // A8.6.50
46 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
47 static uint32_t
48 CountITSize (uint32_t ITMask) {
49     // First count the trailing zeros of the IT mask.
50     uint32_t TZ = llvm::CountTrailingZeros_32(ITMask);
51     if (TZ > 3)
52     {
53         printf("Encoding error: IT Mask '0000'\n");
54         return 0;
55     }
56     return (4 - TZ);
57 }
58 
59 // Init ITState.  Note that at least one bit is always 1 in mask.
60 bool ITSession::InitIT(uint32_t bits7_0)
61 {
62     ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
63     if (ITCounter == 0)
64         return false;
65 
66     // A8.6.50 IT
67     unsigned short FirstCond = Bits32(bits7_0, 7, 4);
68     if (FirstCond == 0xF)
69     {
70         printf("Encoding error: IT FirstCond '1111'\n");
71         return false;
72     }
73     if (FirstCond == 0xE && ITCounter != 1)
74     {
75         printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
76         return false;
77     }
78 
79     ITState = bits7_0;
80     return true;
81 }
82 
83 // Update ITState if necessary.
84 void ITSession::ITAdvance()
85 {
86     //assert(ITCounter);
87     --ITCounter;
88     if (ITCounter == 0)
89         ITState = 0;
90     else
91     {
92         unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
93         SetBits32(ITState, 4, 0, NewITState4_0);
94     }
95 }
96 
97 // Return true if we're inside an IT Block.
98 bool ITSession::InITBlock()
99 {
100     return ITCounter != 0;
101 }
102 
103 // Return true if we're the last instruction inside an IT Block.
104 bool ITSession::LastInITBlock()
105 {
106     return ITCounter == 1;
107 }
108 
109 // Get condition bits for the current thumb instruction.
110 uint32_t ITSession::GetCond()
111 {
112     if (InITBlock())
113         return Bits32(ITState, 7, 4);
114     else
115         return COND_AL;
116 }
117 
118 // ARM constants used during decoding
119 #define REG_RD          0
120 #define LDM_REGLIST     1
121 #define SP_REG          13
122 #define LR_REG          14
123 #define PC_REG          15
124 #define PC_REGLIST_BIT  0x8000
125 
126 #define ARMv4     (1u << 0)
127 #define ARMv4T    (1u << 1)
128 #define ARMv5T    (1u << 2)
129 #define ARMv5TE   (1u << 3)
130 #define ARMv5TEJ  (1u << 4)
131 #define ARMv6     (1u << 5)
132 #define ARMv6K    (1u << 6)
133 #define ARMv6T2   (1u << 7)
134 #define ARMv7     (1u << 8)
135 #define ARMv7S    (1u << 9)
136 #define ARMv8     (1u << 10)
137 #define ARMvAll   (0xffffffffu)
138 
139 #define ARMV4T_ABOVE  (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
140 #define ARMV5_ABOVE   (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
141 #define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
142 #define ARMV5J_ABOVE  (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
143 #define ARMV6_ABOVE   (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
144 #define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv7S|ARMv8)
145 #define ARMV7_ABOVE   (ARMv7|ARMv7S|ARMv8)
146 
147 #define No_VFP  0
148 #define VFPv1   (1u << 1)
149 #define VFPv2   (1u << 2)
150 #define VFPv3   (1u << 3)
151 #define AdvancedSIMD (1u << 4)
152 
153 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
154 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
155 #define VFPv2v3     (VFPv2 | VFPv3)
156 
157 //----------------------------------------------------------------------
158 //
159 // EmulateInstructionARM implementation
160 //
161 //----------------------------------------------------------------------
162 
163 void
164 EmulateInstructionARM::Initialize ()
165 {
166     PluginManager::RegisterPlugin (GetPluginNameStatic (),
167                                    GetPluginDescriptionStatic (),
168                                    CreateInstance);
169 }
170 
171 void
172 EmulateInstructionARM::Terminate ()
173 {
174     PluginManager::UnregisterPlugin (CreateInstance);
175 }
176 
177 const char *
178 EmulateInstructionARM::GetPluginNameStatic ()
179 {
180     return "lldb.emulate-instruction.arm";
181 }
182 
183 const char *
184 EmulateInstructionARM::GetPluginDescriptionStatic ()
185 {
186     return "Emulate instructions for the ARM architecture.";
187 }
188 
189 EmulateInstruction *
190 EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type)
191 {
192     if (EmulateInstructionARM::SupportsEmulatingIntructionsOfTypeStatic(inst_type))
193     {
194         if (arch.GetTriple().getArch() == llvm::Triple::arm)
195         {
196             std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
197 
198             if (emulate_insn_ap.get())
199                 return emulate_insn_ap.release();
200         }
201         else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
202         {
203             std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
204 
205             if (emulate_insn_ap.get())
206                 return emulate_insn_ap.release();
207         }
208     }
209 
210     return NULL;
211 }
212 
213 bool
214 EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch)
215 {
216     if (arch.GetTriple().getArch () == llvm::Triple::arm)
217         return true;
218     else if (arch.GetTriple().getArch () == llvm::Triple::thumb)
219         return true;
220 
221     return false;
222 }
223 
224 // Write "bits (32) UNKNOWN" to memory address "address".  Helper function for many ARM instructions.
225 bool
226 EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address)
227 {
228     EmulateInstruction::Context context;
229     context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
230     context.SetNoArgs ();
231 
232     uint32_t random_data = rand ();
233     const uint32_t addr_byte_size = GetAddressByteSize();
234 
235     if (!MemAWrite (context, address, random_data, addr_byte_size))
236         return false;
237 
238     return true;
239 }
240 
241 // Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM instructions.
242 bool
243 EmulateInstructionARM::WriteBits32Unknown (int n)
244 {
245     EmulateInstruction::Context context;
246     context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
247     context.SetNoArgs ();
248 
249     bool success;
250     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
251 
252     if (!success)
253         return false;
254 
255     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
256         return false;
257 
258     return true;
259 }
260 
261 bool
262 EmulateInstructionARM::GetRegisterInfo (uint32_t reg_kind, uint32_t reg_num, RegisterInfo &reg_info)
263 {
264     if (reg_kind == eRegisterKindGeneric)
265     {
266         switch (reg_num)
267         {
268             case LLDB_REGNUM_GENERIC_PC:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break;
269             case LLDB_REGNUM_GENERIC_SP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break;
270             case LLDB_REGNUM_GENERIC_FP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break;
271             case LLDB_REGNUM_GENERIC_RA:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break;
272             case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break;
273             default: return false;
274         }
275     }
276 
277     if (reg_kind == eRegisterKindDWARF)
278         return GetARMDWARFRegisterInfo(reg_num, reg_info);
279     return false;
280 }
281 
282 uint32_t
283 EmulateInstructionARM::GetFramePointerRegisterNumber () const
284 {
285     if (m_opcode_mode == eModeThumb)
286     {
287         switch (m_arch.GetTriple().getOS())
288         {
289             case llvm::Triple::Darwin:
290             case llvm::Triple::MacOSX:
291             case llvm::Triple::IOS:
292                 return 7;
293             default:
294                 break;
295         }
296     }
297     return 11;
298 }
299 
300 uint32_t
301 EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const
302 {
303     if (m_opcode_mode == eModeThumb)
304     {
305         switch (m_arch.GetTriple().getOS())
306         {
307             case llvm::Triple::Darwin:
308             case llvm::Triple::MacOSX:
309             case llvm::Triple::IOS:
310                 return dwarf_r7;
311             default:
312                 break;
313         }
314     }
315     return dwarf_r11;
316 }
317 
318 // Push Multiple Registers stores multiple registers to the stack, storing to
319 // consecutive memory locations ending just below the address in SP, and updates
320 // SP to point to the start of the stored data.
321 bool
322 EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding)
323 {
324 #if 0
325     // ARM pseudo code...
326     if (ConditionPassed())
327     {
328         EncodingSpecificOperations();
329         NullCheckIfThumbEE(13);
330         address = SP - 4*BitCount(registers);
331 
332         for (i = 0 to 14)
333         {
334             if (registers<i> == '1')
335             {
336                 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
337                     MemA[address,4] = bits(32) UNKNOWN;
338                 else
339                     MemA[address,4] = R[i];
340                 address = address + 4;
341             }
342         }
343 
344         if (registers<15> == '1') // Only possible for encoding A1 or A2
345             MemA[address,4] = PCStoreValue();
346 
347         SP = SP - 4*BitCount(registers);
348     }
349 #endif
350 
351     bool conditional = false;
352     bool success = false;
353     if (ConditionPassed(opcode, &conditional))
354     {
355         const uint32_t addr_byte_size = GetAddressByteSize();
356         const addr_t sp = ReadCoreReg (SP_REG, &success);
357         if (!success)
358             return false;
359         uint32_t registers = 0;
360         uint32_t Rt; // the source register
361         switch (encoding) {
362         case eEncodingT1:
363             registers = Bits32(opcode, 7, 0);
364             // The M bit represents LR.
365             if (Bit32(opcode, 8))
366                 registers |= (1u << 14);
367             // if BitCount(registers) < 1 then UNPREDICTABLE;
368             if (BitCount(registers) < 1)
369                 return false;
370             break;
371         case eEncodingT2:
372             // Ignore bits 15 & 13.
373             registers = Bits32(opcode, 15, 0) & ~0xa000;
374             // if BitCount(registers) < 2 then UNPREDICTABLE;
375             if (BitCount(registers) < 2)
376                 return false;
377             break;
378         case eEncodingT3:
379             Rt = Bits32(opcode, 15, 12);
380             // if BadReg(t) then UNPREDICTABLE;
381             if (BadReg(Rt))
382                 return false;
383             registers = (1u << Rt);
384             break;
385         case eEncodingA1:
386             registers = Bits32(opcode, 15, 0);
387             // Instead of return false, let's handle the following case as well,
388             // which amounts to pushing one reg onto the full descending stacks.
389             // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
390             break;
391         case eEncodingA2:
392             Rt = Bits32(opcode, 15, 12);
393             // if t == 13 then UNPREDICTABLE;
394             if (Rt == dwarf_sp)
395                 return false;
396             registers = (1u << Rt);
397             break;
398         default:
399             return false;
400         }
401         addr_t sp_offset = addr_byte_size * BitCount (registers);
402         addr_t addr = sp - sp_offset;
403         uint32_t i;
404 
405         EmulateInstruction::Context context;
406         if (conditional)
407             context.type = EmulateInstruction::eContextRegisterStore;
408         else
409             context.type = EmulateInstruction::eContextPushRegisterOnStack;
410         RegisterInfo reg_info;
411         RegisterInfo sp_reg;
412         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
413         for (i=0; i<15; ++i)
414         {
415             if (BitIsSet (registers, i))
416             {
417                 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info);
418                 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
419                 uint32_t reg_value = ReadCoreReg(i, &success);
420                 if (!success)
421                     return false;
422                 if (!MemAWrite (context, addr, reg_value, addr_byte_size))
423                     return false;
424                 addr += addr_byte_size;
425             }
426         }
427 
428         if (BitIsSet (registers, 15))
429         {
430             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info);
431             context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
432             const uint32_t pc = ReadCoreReg(PC_REG, &success);
433             if (!success)
434                 return false;
435             if (!MemAWrite (context, addr, pc, addr_byte_size))
436                 return false;
437         }
438 
439         context.type = EmulateInstruction::eContextAdjustStackPointer;
440         context.SetImmediateSigned (-sp_offset);
441 
442         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
443             return false;
444     }
445     return true;
446 }
447 
448 // Pop Multiple Registers loads multiple registers from the stack, loading from
449 // consecutive memory locations staring at the address in SP, and updates
450 // SP to point just above the loaded data.
451 bool
452 EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding)
453 {
454 #if 0
455     // ARM pseudo code...
456     if (ConditionPassed())
457     {
458         EncodingSpecificOperations(); NullCheckIfThumbEE(13);
459         address = SP;
460         for i = 0 to 14
461             if registers<i> == '1' then
462                 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
463         if registers<15> == '1' then
464             if UnalignedAllowed then
465                 LoadWritePC(MemU[address,4]);
466             else
467                 LoadWritePC(MemA[address,4]);
468         if registers<13> == '0' then SP = SP + 4*BitCount(registers);
469         if registers<13> == '1' then SP = bits(32) UNKNOWN;
470     }
471 #endif
472 
473     bool success = false;
474 
475     bool conditional = false;
476     if (ConditionPassed(opcode, &conditional))
477     {
478         const uint32_t addr_byte_size = GetAddressByteSize();
479         const addr_t sp = ReadCoreReg (SP_REG, &success);
480         if (!success)
481             return false;
482         uint32_t registers = 0;
483         uint32_t Rt; // the destination register
484         switch (encoding) {
485         case eEncodingT1:
486             registers = Bits32(opcode, 7, 0);
487             // The P bit represents PC.
488             if (Bit32(opcode, 8))
489                 registers |= (1u << 15);
490             // if BitCount(registers) < 1 then UNPREDICTABLE;
491             if (BitCount(registers) < 1)
492                 return false;
493             break;
494         case eEncodingT2:
495             // Ignore bit 13.
496             registers = Bits32(opcode, 15, 0) & ~0x2000;
497             // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
498             if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
499                 return false;
500             // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
501             if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
502                 return false;
503             break;
504         case eEncodingT3:
505             Rt = Bits32(opcode, 15, 12);
506             // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
507             if (Rt == 13)
508                 return false;
509             if (Rt == 15 && InITBlock() && !LastInITBlock())
510                 return false;
511             registers = (1u << Rt);
512             break;
513         case eEncodingA1:
514             registers = Bits32(opcode, 15, 0);
515             // Instead of return false, let's handle the following case as well,
516             // which amounts to popping one reg from the full descending stacks.
517             // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
518 
519             // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
520             if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
521                 return false;
522             break;
523         case eEncodingA2:
524             Rt = Bits32(opcode, 15, 12);
525             // if t == 13 then UNPREDICTABLE;
526             if (Rt == dwarf_sp)
527                 return false;
528             registers = (1u << Rt);
529             break;
530         default:
531             return false;
532         }
533         addr_t sp_offset = addr_byte_size * BitCount (registers);
534         addr_t addr = sp;
535         uint32_t i, data;
536 
537         EmulateInstruction::Context context;
538         if (conditional)
539             context.type = EmulateInstruction::eContextRegisterLoad;
540         else
541             context.type = EmulateInstruction::eContextPopRegisterOffStack;
542 
543         RegisterInfo sp_reg;
544         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
545 
546         for (i=0; i<15; ++i)
547         {
548             if (BitIsSet (registers, i))
549             {
550                 context.SetRegisterPlusOffset (sp_reg, addr - sp);
551                 data = MemARead(context, addr, 4, 0, &success);
552                 if (!success)
553                     return false;
554                 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data))
555                     return false;
556                 addr += addr_byte_size;
557             }
558         }
559 
560         if (BitIsSet (registers, 15))
561         {
562             context.SetRegisterPlusOffset (sp_reg, addr - sp);
563             data = MemARead(context, addr, 4, 0, &success);
564             if (!success)
565                 return false;
566             // In ARMv5T and above, this is an interworking branch.
567             if (!LoadWritePC(context, data))
568                 return false;
569             //addr += addr_byte_size;
570         }
571 
572         context.type = EmulateInstruction::eContextAdjustStackPointer;
573         context.SetImmediateSigned (sp_offset);
574 
575         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
576             return false;
577     }
578     return true;
579 }
580 
581 // Set r7 or ip to point to saved value residing within the stack.
582 // ADD (SP plus immediate)
583 bool
584 EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding)
585 {
586 #if 0
587     // ARM pseudo code...
588     if (ConditionPassed())
589     {
590         EncodingSpecificOperations();
591         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
592         if d == 15 then
593            ALUWritePC(result); // setflags is always FALSE here
594         else
595             R[d] = result;
596             if setflags then
597                 APSR.N = result<31>;
598                 APSR.Z = IsZeroBit(result);
599                 APSR.C = carry;
600                 APSR.V = overflow;
601     }
602 #endif
603 
604     bool success = false;
605 
606     if (ConditionPassed(opcode))
607     {
608         const addr_t sp = ReadCoreReg (SP_REG, &success);
609         if (!success)
610             return false;
611         uint32_t Rd; // the destination register
612         uint32_t imm32;
613         switch (encoding) {
614         case eEncodingT1:
615             Rd = 7;
616             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
617             break;
618         case eEncodingA1:
619             Rd = Bits32(opcode, 15, 12);
620             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
621             break;
622         default:
623             return false;
624         }
625         addr_t sp_offset = imm32;
626         addr_t addr = sp + sp_offset; // a pointer to the stack area
627 
628         EmulateInstruction::Context context;
629         context.type = eContextSetFramePointer;
630         RegisterInfo sp_reg;
631         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
632         context.SetRegisterPlusOffset (sp_reg, sp_offset);
633 
634         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
635             return false;
636     }
637     return true;
638 }
639 
640 // Set r7 or ip to the current stack pointer.
641 // MOV (register)
642 bool
643 EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding)
644 {
645 #if 0
646     // ARM pseudo code...
647     if (ConditionPassed())
648     {
649         EncodingSpecificOperations();
650         result = R[m];
651         if d == 15 then
652             ALUWritePC(result); // setflags is always FALSE here
653         else
654             R[d] = result;
655             if setflags then
656                 APSR.N = result<31>;
657                 APSR.Z = IsZeroBit(result);
658                 // APSR.C unchanged
659                 // APSR.V unchanged
660     }
661 #endif
662 
663     bool success = false;
664 
665     if (ConditionPassed(opcode))
666     {
667         const addr_t sp = ReadCoreReg (SP_REG, &success);
668         if (!success)
669             return false;
670         uint32_t Rd; // the destination register
671         switch (encoding) {
672         case eEncodingT1:
673             Rd = 7;
674             break;
675         case eEncodingA1:
676             Rd = 12;
677             break;
678         default:
679             return false;
680         }
681 
682         EmulateInstruction::Context context;
683         if (Rd == GetFramePointerRegisterNumber())
684             context.type = EmulateInstruction::eContextSetFramePointer;
685         else
686             context.type = EmulateInstruction::eContextRegisterPlusOffset;
687         RegisterInfo sp_reg;
688         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
689         context.SetRegisterPlusOffset (sp_reg, 0);
690 
691         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
692             return false;
693     }
694     return true;
695 }
696 
697 // Move from high register (r8-r15) to low register (r0-r7).
698 // MOV (register)
699 bool
700 EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding)
701 {
702     return EmulateMOVRdRm (opcode, encoding);
703 }
704 
705 // Move from register to register.
706 // MOV (register)
707 bool
708 EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding)
709 {
710 #if 0
711     // ARM pseudo code...
712     if (ConditionPassed())
713     {
714         EncodingSpecificOperations();
715         result = R[m];
716         if d == 15 then
717             ALUWritePC(result); // setflags is always FALSE here
718         else
719             R[d] = result;
720             if setflags then
721                 APSR.N = result<31>;
722                 APSR.Z = IsZeroBit(result);
723                 // APSR.C unchanged
724                 // APSR.V unchanged
725     }
726 #endif
727 
728     bool success = false;
729 
730     if (ConditionPassed(opcode))
731     {
732         uint32_t Rm; // the source register
733         uint32_t Rd; // the destination register
734         bool setflags;
735         switch (encoding) {
736         case eEncodingT1:
737             Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
738             Rm = Bits32(opcode, 6, 3);
739             setflags = false;
740             if (Rd == 15 && InITBlock() && !LastInITBlock())
741                 return false;
742             break;
743         case eEncodingT2:
744             Rd = Bits32(opcode, 2, 0);
745             Rm = Bits32(opcode, 5, 3);
746             setflags = true;
747             if (InITBlock())
748                 return false;
749             break;
750         case eEncodingT3:
751             Rd = Bits32(opcode, 11, 8);
752             Rm = Bits32(opcode, 3, 0);
753             setflags = BitIsSet(opcode, 20);
754             // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
755             if (setflags && (BadReg(Rd) || BadReg(Rm)))
756                 return false;
757             // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE;
758             if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
759                 return false;
760             break;
761         case eEncodingA1:
762             Rd = Bits32(opcode, 15, 12);
763             Rm = Bits32(opcode, 3, 0);
764             setflags = BitIsSet(opcode, 20);
765 
766             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
767             if (Rd == 15 && setflags)
768                 return EmulateSUBSPcLrEtc (opcode, encoding);
769             break;
770         default:
771             return false;
772         }
773         uint32_t result = ReadCoreReg(Rm, &success);
774         if (!success)
775             return false;
776 
777         // The context specifies that Rm is to be moved into Rd.
778         EmulateInstruction::Context context;
779         context.type = EmulateInstruction::eContextRegisterLoad;
780         RegisterInfo dwarf_reg;
781         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
782         context.SetRegister (dwarf_reg);
783 
784         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
785             return false;
786     }
787     return true;
788 }
789 
790 // Move (immediate) writes an immediate value to the destination register.  It
791 // can optionally update the condition flags based on the value.
792 // MOV (immediate)
793 bool
794 EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding)
795 {
796 #if 0
797     // ARM pseudo code...
798     if (ConditionPassed())
799     {
800         EncodingSpecificOperations();
801         result = imm32;
802         if d == 15 then         // Can only occur for ARM encoding
803             ALUWritePC(result); // setflags is always FALSE here
804         else
805             R[d] = result;
806             if setflags then
807                 APSR.N = result<31>;
808                 APSR.Z = IsZeroBit(result);
809                 APSR.C = carry;
810                 // APSR.V unchanged
811     }
812 #endif
813 
814     if (ConditionPassed(opcode))
815     {
816         uint32_t Rd; // the destination register
817         uint32_t imm32; // the immediate value to be written to Rd
818         uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
819                             // for setflags == false, this value is a don't care
820                             // initialized to 0 to silence the static analyzer
821         bool setflags;
822         switch (encoding) {
823             case eEncodingT1:
824                 Rd = Bits32(opcode, 10, 8);
825                 setflags = !InITBlock();
826                 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
827                 carry = APSR_C;
828 
829                 break;
830 
831             case eEncodingT2:
832                 Rd = Bits32(opcode, 11, 8);
833                 setflags = BitIsSet(opcode, 20);
834                 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
835                 if (BadReg(Rd))
836                   return false;
837 
838                 break;
839 
840             case eEncodingT3:
841             {
842                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32);
843                 Rd = Bits32 (opcode, 11, 8);
844                 setflags = false;
845                 uint32_t imm4 = Bits32 (opcode, 19, 16);
846                 uint32_t imm3 = Bits32 (opcode, 14, 12);
847                 uint32_t i = Bit32 (opcode, 26);
848                 uint32_t imm8 = Bits32 (opcode, 7, 0);
849                 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
850 
851                 // if BadReg(d) then UNPREDICTABLE;
852                 if (BadReg (Rd))
853                     return false;
854             }
855                 break;
856 
857             case eEncodingA1:
858                 // d = UInt(Rd); setflags = (S == �1�); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C);
859                 Rd = Bits32 (opcode, 15, 12);
860                 setflags = BitIsSet (opcode, 20);
861                 imm32 = ARMExpandImm_C (opcode, APSR_C, carry);
862 
863                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
864                 if ((Rd == 15) && setflags)
865                     return EmulateSUBSPcLrEtc (opcode, encoding);
866 
867                 break;
868 
869             case eEncodingA2:
870             {
871                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
872                 Rd = Bits32 (opcode, 15, 12);
873                 setflags = false;
874                 uint32_t imm4 = Bits32 (opcode, 19, 16);
875                 uint32_t imm12 = Bits32 (opcode, 11, 0);
876                 imm32 = (imm4 << 12) | imm12;
877 
878                 // if d == 15 then UNPREDICTABLE;
879                 if (Rd == 15)
880                     return false;
881             }
882                 break;
883 
884             default:
885                 return false;
886         }
887         uint32_t result = imm32;
888 
889         // The context specifies that an immediate is to be moved into Rd.
890         EmulateInstruction::Context context;
891         context.type = EmulateInstruction::eContextImmediate;
892         context.SetNoArgs ();
893 
894         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
895             return false;
896     }
897     return true;
898 }
899 
900 // MUL multiplies two register values.  The least significant 32 bits of the result are written to the destination
901 // register.  These 32 bits do not depend on whether the source register values are considered to be signed values or
902 // unsigned values.
903 //
904 // Optionally, it can update the condition flags based on the result.  In the Thumb instruction set, this option is
905 // limited to only a few forms of the instruction.
906 bool
907 EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding)
908 {
909 #if 0
910     if ConditionPassed() then
911         EncodingSpecificOperations();
912         operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
913         operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
914         result = operand1 * operand2;
915         R[d] = result<31:0>;
916         if setflags then
917             APSR.N = result<31>;
918             APSR.Z = IsZeroBit(result);
919             if ArchVersion() == 4 then
920                 APSR.C = bit UNKNOWN;
921             // else APSR.C unchanged
922             // APSR.V always unchanged
923 #endif
924 
925     if (ConditionPassed(opcode))
926     {
927         uint32_t d;
928         uint32_t n;
929         uint32_t m;
930         bool setflags;
931 
932         // EncodingSpecificOperations();
933         switch (encoding)
934         {
935             case eEncodingT1:
936                 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
937                 d = Bits32 (opcode, 2, 0);
938                 n = Bits32 (opcode, 5, 3);
939                 m = Bits32 (opcode, 2, 0);
940                 setflags = !InITBlock();
941 
942                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
943                 if ((ArchVersion() < ARMv6) && (d == n))
944                     return false;
945 
946                 break;
947 
948             case eEncodingT2:
949                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
950                 d = Bits32 (opcode, 11, 8);
951                 n = Bits32 (opcode, 19, 16);
952                 m = Bits32 (opcode, 3, 0);
953                 setflags = false;
954 
955                 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
956                 if (BadReg (d) || BadReg (n) || BadReg (m))
957                     return false;
958 
959                 break;
960 
961             case eEncodingA1:
962                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
963                 d = Bits32 (opcode, 19, 16);
964                 n = Bits32 (opcode, 3, 0);
965                 m = Bits32 (opcode, 11, 8);
966                 setflags = BitIsSet (opcode, 20);
967 
968                 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
969                 if ((d == 15) ||  (n == 15) || (m == 15))
970                     return false;
971 
972                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
973                 if ((ArchVersion() < ARMv6) && (d == n))
974                     return false;
975 
976                 break;
977 
978             default:
979                 return false;
980         }
981 
982         bool success = false;
983 
984         // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
985         uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
986         if (!success)
987             return false;
988 
989         // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
990         uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
991         if (!success)
992             return false;
993 
994         // result = operand1 * operand2;
995         uint64_t result = operand1 * operand2;
996 
997         // R[d] = result<31:0>;
998         RegisterInfo op1_reg;
999         RegisterInfo op2_reg;
1000         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
1001         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
1002 
1003         EmulateInstruction::Context context;
1004         context.type = eContextArithmetic;
1005         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
1006 
1007         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result)))
1008             return false;
1009 
1010         // if setflags then
1011         if (setflags)
1012         {
1013             // APSR.N = result<31>;
1014             // APSR.Z = IsZeroBit(result);
1015             m_new_inst_cpsr = m_opcode_cpsr;
1016             SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31));
1017             SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1018             if (m_new_inst_cpsr != m_opcode_cpsr)
1019             {
1020                 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1021                     return false;
1022             }
1023 
1024             // if ArchVersion() == 4 then
1025                 // APSR.C = bit UNKNOWN;
1026         }
1027     }
1028     return true;
1029 }
1030 
1031 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register.
1032 // It can optionally update the condition flags based on the value.
1033 bool
1034 EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding)
1035 {
1036 #if 0
1037     // ARM pseudo code...
1038     if (ConditionPassed())
1039     {
1040         EncodingSpecificOperations();
1041         result = NOT(imm32);
1042         if d == 15 then         // Can only occur for ARM encoding
1043             ALUWritePC(result); // setflags is always FALSE here
1044         else
1045             R[d] = result;
1046             if setflags then
1047                 APSR.N = result<31>;
1048                 APSR.Z = IsZeroBit(result);
1049                 APSR.C = carry;
1050                 // APSR.V unchanged
1051     }
1052 #endif
1053 
1054     if (ConditionPassed(opcode))
1055     {
1056         uint32_t Rd; // the destination register
1057         uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1058         uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1059         bool setflags;
1060         switch (encoding) {
1061         case eEncodingT1:
1062             Rd = Bits32(opcode, 11, 8);
1063             setflags = BitIsSet(opcode, 20);
1064             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1065             break;
1066         case eEncodingA1:
1067             Rd = Bits32(opcode, 15, 12);
1068             setflags = BitIsSet(opcode, 20);
1069             imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1070 
1071             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1072             if (Rd == 15 && setflags)
1073                 return EmulateSUBSPcLrEtc (opcode, encoding);
1074             break;
1075         default:
1076             return false;
1077         }
1078         uint32_t result = ~imm32;
1079 
1080         // The context specifies that an immediate is to be moved into Rd.
1081         EmulateInstruction::Context context;
1082         context.type = EmulateInstruction::eContextImmediate;
1083         context.SetNoArgs ();
1084 
1085         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1086             return false;
1087     }
1088     return true;
1089 }
1090 
1091 // Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register.
1092 // It can optionally update the condition flags based on the result.
1093 bool
1094 EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding)
1095 {
1096 #if 0
1097     // ARM pseudo code...
1098     if (ConditionPassed())
1099     {
1100         EncodingSpecificOperations();
1101         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1102         result = NOT(shifted);
1103         if d == 15 then         // Can only occur for ARM encoding
1104             ALUWritePC(result); // setflags is always FALSE here
1105         else
1106             R[d] = result;
1107             if setflags then
1108                 APSR.N = result<31>;
1109                 APSR.Z = IsZeroBit(result);
1110                 APSR.C = carry;
1111                 // APSR.V unchanged
1112     }
1113 #endif
1114 
1115     if (ConditionPassed(opcode))
1116     {
1117         uint32_t Rm; // the source register
1118         uint32_t Rd; // the destination register
1119         ARM_ShifterType shift_t;
1120         uint32_t shift_n; // the shift applied to the value read from Rm
1121         bool setflags;
1122         uint32_t carry; // the carry bit after the shift operation
1123         switch (encoding) {
1124         case eEncodingT1:
1125             Rd = Bits32(opcode, 2, 0);
1126             Rm = Bits32(opcode, 5, 3);
1127             setflags = !InITBlock();
1128             shift_t = SRType_LSL;
1129             shift_n = 0;
1130             if (InITBlock())
1131                 return false;
1132             break;
1133         case eEncodingT2:
1134             Rd = Bits32(opcode, 11, 8);
1135             Rm = Bits32(opcode, 3, 0);
1136             setflags = BitIsSet(opcode, 20);
1137             shift_n = DecodeImmShiftThumb(opcode, shift_t);
1138             // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1139             if (BadReg(Rd) || BadReg(Rm))
1140                 return false;
1141             break;
1142         case eEncodingA1:
1143             Rd = Bits32(opcode, 15, 12);
1144             Rm = Bits32(opcode, 3, 0);
1145             setflags = BitIsSet(opcode, 20);
1146             shift_n = DecodeImmShiftARM(opcode, shift_t);
1147             break;
1148         default:
1149             return false;
1150         }
1151         bool success = false;
1152         uint32_t value = ReadCoreReg(Rm, &success);
1153         if (!success)
1154             return false;
1155 
1156         uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1157         if (!success)
1158             return false;
1159         uint32_t result = ~shifted;
1160 
1161         // The context specifies that an immediate is to be moved into Rd.
1162         EmulateInstruction::Context context;
1163         context.type = EmulateInstruction::eContextImmediate;
1164         context.SetNoArgs ();
1165 
1166         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1167             return false;
1168     }
1169     return true;
1170 }
1171 
1172 // PC relative immediate load into register, possibly followed by ADD (SP plus register).
1173 // LDR (literal)
1174 bool
1175 EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding)
1176 {
1177 #if 0
1178     // ARM pseudo code...
1179     if (ConditionPassed())
1180     {
1181         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1182         base = Align(PC,4);
1183         address = if add then (base + imm32) else (base - imm32);
1184         data = MemU[address,4];
1185         if t == 15 then
1186             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1187         elsif UnalignedSupport() || address<1:0> = '00' then
1188             R[t] = data;
1189         else // Can only apply before ARMv7
1190             if CurrentInstrSet() == InstrSet_ARM then
1191                 R[t] = ROR(data, 8*UInt(address<1:0>));
1192             else
1193                 R[t] = bits(32) UNKNOWN;
1194     }
1195 #endif
1196 
1197     if (ConditionPassed(opcode))
1198     {
1199         bool success = false;
1200         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1201         if (!success)
1202             return false;
1203 
1204         // PC relative immediate load context
1205         EmulateInstruction::Context context;
1206         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1207         RegisterInfo pc_reg;
1208         GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
1209         context.SetRegisterPlusOffset (pc_reg, 0);
1210 
1211         uint32_t Rt;    // the destination register
1212         uint32_t imm32; // immediate offset from the PC
1213         bool add;       // +imm32 or -imm32?
1214         addr_t base;    // the base address
1215         addr_t address; // the PC relative address
1216         uint32_t data;  // the literal data value from the PC relative load
1217         switch (encoding) {
1218         case eEncodingT1:
1219             Rt = Bits32(opcode, 10, 8);
1220             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1221             add = true;
1222             break;
1223         case eEncodingT2:
1224             Rt = Bits32(opcode, 15, 12);
1225             imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1226             add = BitIsSet(opcode, 23);
1227             if (Rt == 15 && InITBlock() && !LastInITBlock())
1228                 return false;
1229             break;
1230         default:
1231             return false;
1232         }
1233 
1234         base = Align(pc, 4);
1235         if (add)
1236             address = base + imm32;
1237         else
1238             address = base - imm32;
1239 
1240         context.SetRegisterPlusOffset(pc_reg, address - base);
1241         data = MemURead(context, address, 4, 0, &success);
1242         if (!success)
1243             return false;
1244 
1245         if (Rt == 15)
1246         {
1247             if (Bits32(address, 1, 0) == 0)
1248             {
1249                 // In ARMv5T and above, this is an interworking branch.
1250                 if (!LoadWritePC(context, data))
1251                     return false;
1252             }
1253             else
1254                 return false;
1255         }
1256         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
1257         {
1258             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
1259                 return false;
1260         }
1261         else // We don't handle ARM for now.
1262             return false;
1263 
1264     }
1265     return true;
1266 }
1267 
1268 // An add operation to adjust the SP.
1269 // ADD (SP plus immediate)
1270 bool
1271 EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding)
1272 {
1273 #if 0
1274     // ARM pseudo code...
1275     if (ConditionPassed())
1276     {
1277         EncodingSpecificOperations();
1278         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1279         if d == 15 then // Can only occur for ARM encoding
1280             ALUWritePC(result); // setflags is always FALSE here
1281         else
1282             R[d] = result;
1283             if setflags then
1284                 APSR.N = result<31>;
1285                 APSR.Z = IsZeroBit(result);
1286                 APSR.C = carry;
1287                 APSR.V = overflow;
1288     }
1289 #endif
1290 
1291     bool success = false;
1292 
1293     if (ConditionPassed(opcode))
1294     {
1295         const addr_t sp = ReadCoreReg (SP_REG, &success);
1296         if (!success)
1297             return false;
1298         uint32_t imm32; // the immediate operand
1299         uint32_t d;
1300         //bool setflags = false; // Add this back if/when support eEncodingT3 eEncodingA1
1301         switch (encoding)
1302         {
1303             case eEncodingT1:
1304                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1305                 d = Bits32 (opcode, 10, 8);
1306                 imm32 = (Bits32 (opcode, 7, 0) << 2);
1307 
1308                 break;
1309 
1310             case eEncodingT2:
1311                 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1312                 d = 13;
1313                 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1314 
1315                 break;
1316 
1317             default:
1318                 return false;
1319         }
1320         addr_t sp_offset = imm32;
1321         addr_t addr = sp + sp_offset; // the adjusted stack pointer value
1322 
1323         EmulateInstruction::Context context;
1324         context.type = EmulateInstruction::eContextAdjustStackPointer;
1325         RegisterInfo sp_reg;
1326         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1327         context.SetRegisterPlusOffset (sp_reg, sp_offset);
1328 
1329         if (d == 15)
1330         {
1331             if (!ALUWritePC (context, addr))
1332                 return false;
1333         }
1334         else
1335         {
1336             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr))
1337                 return false;
1338 
1339             // Add this back if/when support eEncodingT3 eEncodingA1
1340             //if (setflags)
1341             //{
1342             //    APSR.N = result<31>;
1343             //    APSR.Z = IsZeroBit(result);
1344             //    APSR.C = carry;
1345             //    APSR.V = overflow;
1346             //}
1347         }
1348     }
1349     return true;
1350 }
1351 
1352 // An add operation to adjust the SP.
1353 // ADD (SP plus register)
1354 bool
1355 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding)
1356 {
1357 #if 0
1358     // ARM pseudo code...
1359     if (ConditionPassed())
1360     {
1361         EncodingSpecificOperations();
1362         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1363         (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1364         if d == 15 then
1365             ALUWritePC(result); // setflags is always FALSE here
1366         else
1367             R[d] = result;
1368             if setflags then
1369                 APSR.N = result<31>;
1370                 APSR.Z = IsZeroBit(result);
1371                 APSR.C = carry;
1372                 APSR.V = overflow;
1373     }
1374 #endif
1375 
1376     bool success = false;
1377 
1378     if (ConditionPassed(opcode))
1379     {
1380         const addr_t sp = ReadCoreReg (SP_REG, &success);
1381         if (!success)
1382             return false;
1383         uint32_t Rm; // the second operand
1384         switch (encoding) {
1385         case eEncodingT2:
1386             Rm = Bits32(opcode, 6, 3);
1387             break;
1388         default:
1389             return false;
1390         }
1391         int32_t reg_value = ReadCoreReg(Rm, &success);
1392         if (!success)
1393             return false;
1394 
1395         addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1396 
1397         EmulateInstruction::Context context;
1398         context.type = eContextArithmetic;
1399         RegisterInfo sp_reg;
1400         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1401 
1402         RegisterInfo other_reg;
1403         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1404         context.SetRegisterRegisterOperands (sp_reg, other_reg);
1405 
1406         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
1407             return false;
1408     }
1409     return true;
1410 }
1411 
1412 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
1413 // at a PC-relative address, and changes instruction set from ARM to Thumb, or
1414 // from Thumb to ARM.
1415 // BLX (immediate)
1416 bool
1417 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding)
1418 {
1419 #if 0
1420     // ARM pseudo code...
1421     if (ConditionPassed())
1422     {
1423         EncodingSpecificOperations();
1424         if CurrentInstrSet() == InstrSet_ARM then
1425             LR = PC - 4;
1426         else
1427             LR = PC<31:1> : '1';
1428         if targetInstrSet == InstrSet_ARM then
1429             targetAddress = Align(PC,4) + imm32;
1430         else
1431             targetAddress = PC + imm32;
1432         SelectInstrSet(targetInstrSet);
1433         BranchWritePC(targetAddress);
1434     }
1435 #endif
1436 
1437     bool success = true;
1438 
1439     if (ConditionPassed(opcode))
1440     {
1441         EmulateInstruction::Context context;
1442         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1443         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1444         if (!success)
1445             return false;
1446         addr_t lr; // next instruction address
1447         addr_t target; // target address
1448         int32_t imm32; // PC-relative offset
1449         switch (encoding) {
1450         case eEncodingT1:
1451             {
1452             lr = pc | 1u; // return address
1453             uint32_t S = Bit32(opcode, 26);
1454             uint32_t imm10 = Bits32(opcode, 25, 16);
1455             uint32_t J1 = Bit32(opcode, 13);
1456             uint32_t J2 = Bit32(opcode, 11);
1457             uint32_t imm11 = Bits32(opcode, 10, 0);
1458             uint32_t I1 = !(J1 ^ S);
1459             uint32_t I2 = !(J2 ^ S);
1460             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1461             imm32 = llvm::SignExtend32<25>(imm25);
1462             target = pc + imm32;
1463             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
1464             if (InITBlock() && !LastInITBlock())
1465                 return false;
1466             break;
1467             }
1468         case eEncodingT2:
1469             {
1470             lr = pc | 1u; // return address
1471             uint32_t S = Bit32(opcode, 26);
1472             uint32_t imm10H = Bits32(opcode, 25, 16);
1473             uint32_t J1 = Bit32(opcode, 13);
1474             uint32_t J2 = Bit32(opcode, 11);
1475             uint32_t imm10L = Bits32(opcode, 10, 1);
1476             uint32_t I1 = !(J1 ^ S);
1477             uint32_t I2 = !(J2 ^ S);
1478             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
1479             imm32 = llvm::SignExtend32<25>(imm25);
1480             target = Align(pc, 4) + imm32;
1481             context.SetISAAndImmediateSigned (eModeARM, 4 + imm32);
1482             if (InITBlock() && !LastInITBlock())
1483                 return false;
1484             break;
1485             }
1486         case eEncodingA1:
1487             lr = pc - 4; // return address
1488             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1489             target = Align(pc, 4) + imm32;
1490             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
1491             break;
1492         case eEncodingA2:
1493             lr = pc - 4; // return address
1494             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
1495             target = pc + imm32;
1496             context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32);
1497             break;
1498         default:
1499             return false;
1500         }
1501         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1502             return false;
1503         if (!BranchWritePC(context, target))
1504             return false;
1505     }
1506     return true;
1507 }
1508 
1509 // Branch with Link and Exchange (register) calls a subroutine at an address and
1510 // instruction set specified by a register.
1511 // BLX (register)
1512 bool
1513 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding)
1514 {
1515 #if 0
1516     // ARM pseudo code...
1517     if (ConditionPassed())
1518     {
1519         EncodingSpecificOperations();
1520         target = R[m];
1521         if CurrentInstrSet() == InstrSet_ARM then
1522             next_instr_addr = PC - 4;
1523             LR = next_instr_addr;
1524         else
1525             next_instr_addr = PC - 2;
1526             LR = next_instr_addr<31:1> : '1';
1527         BXWritePC(target);
1528     }
1529 #endif
1530 
1531     bool success = false;
1532 
1533     if (ConditionPassed(opcode))
1534     {
1535         EmulateInstruction::Context context;
1536         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1537         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1538         addr_t lr; // next instruction address
1539         if (!success)
1540             return false;
1541         uint32_t Rm; // the register with the target address
1542         switch (encoding) {
1543         case eEncodingT1:
1544             lr = (pc - 2) | 1u; // return address
1545             Rm = Bits32(opcode, 6, 3);
1546             // if m == 15 then UNPREDICTABLE;
1547             if (Rm == 15)
1548                 return false;
1549             if (InITBlock() && !LastInITBlock())
1550                 return false;
1551             break;
1552         case eEncodingA1:
1553             lr = pc - 4; // return address
1554             Rm = Bits32(opcode, 3, 0);
1555             // if m == 15 then UNPREDICTABLE;
1556             if (Rm == 15)
1557                 return false;
1558             break;
1559         default:
1560             return false;
1561         }
1562         addr_t target = ReadCoreReg (Rm, &success);
1563         if (!success)
1564             return false;
1565         RegisterInfo dwarf_reg;
1566         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1567         context.SetRegister (dwarf_reg);
1568         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1569             return false;
1570         if (!BXWritePC(context, target))
1571             return false;
1572     }
1573     return true;
1574 }
1575 
1576 // Branch and Exchange causes a branch to an address and instruction set specified by a register.
1577 bool
1578 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding)
1579 {
1580 #if 0
1581     // ARM pseudo code...
1582     if (ConditionPassed())
1583     {
1584         EncodingSpecificOperations();
1585         BXWritePC(R[m]);
1586     }
1587 #endif
1588 
1589     if (ConditionPassed(opcode))
1590     {
1591         EmulateInstruction::Context context;
1592         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1593         uint32_t Rm; // the register with the target address
1594         switch (encoding) {
1595         case eEncodingT1:
1596             Rm = Bits32(opcode, 6, 3);
1597             if (InITBlock() && !LastInITBlock())
1598                 return false;
1599             break;
1600         case eEncodingA1:
1601             Rm = Bits32(opcode, 3, 0);
1602             break;
1603         default:
1604             return false;
1605         }
1606         bool success = false;
1607         addr_t target = ReadCoreReg (Rm, &success);
1608         if (!success)
1609             return false;
1610 
1611         RegisterInfo dwarf_reg;
1612         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1613         context.SetRegister (dwarf_reg);
1614         if (!BXWritePC(context, target))
1615             return false;
1616     }
1617     return true;
1618 }
1619 
1620 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an
1621 // address and instruction set specified by a register as though it were a BX instruction.
1622 //
1623 // TODO: Emulate Jazelle architecture?
1624 //       We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation.
1625 bool
1626 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding)
1627 {
1628 #if 0
1629     // ARM pseudo code...
1630     if (ConditionPassed())
1631     {
1632         EncodingSpecificOperations();
1633         if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
1634             BXWritePC(R[m]);
1635         else
1636             if JazelleAcceptsExecution() then
1637                 SwitchToJazelleExecution();
1638             else
1639                 SUBARCHITECTURE_DEFINED handler call;
1640     }
1641 #endif
1642 
1643     if (ConditionPassed(opcode))
1644     {
1645         EmulateInstruction::Context context;
1646         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1647         uint32_t Rm; // the register with the target address
1648         switch (encoding) {
1649         case eEncodingT1:
1650             Rm = Bits32(opcode, 19, 16);
1651             if (BadReg(Rm))
1652                 return false;
1653             if (InITBlock() && !LastInITBlock())
1654                 return false;
1655             break;
1656         case eEncodingA1:
1657             Rm = Bits32(opcode, 3, 0);
1658             if (Rm == 15)
1659                 return false;
1660             break;
1661         default:
1662             return false;
1663         }
1664         bool success = false;
1665         addr_t target = ReadCoreReg (Rm, &success);
1666         if (!success)
1667             return false;
1668 
1669         RegisterInfo dwarf_reg;
1670         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1671         context.SetRegister (dwarf_reg);
1672         if (!BXWritePC(context, target))
1673             return false;
1674     }
1675     return true;
1676 }
1677 
1678 // Set r7 to point to some ip offset.
1679 // SUB (immediate)
1680 bool
1681 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding)
1682 {
1683 #if 0
1684     // ARM pseudo code...
1685     if (ConditionPassed())
1686     {
1687         EncodingSpecificOperations();
1688         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1689         if d == 15 then // Can only occur for ARM encoding
1690            ALUWritePC(result); // setflags is always FALSE here
1691         else
1692             R[d] = result;
1693             if setflags then
1694                 APSR.N = result<31>;
1695                 APSR.Z = IsZeroBit(result);
1696                 APSR.C = carry;
1697                 APSR.V = overflow;
1698     }
1699 #endif
1700 
1701     if (ConditionPassed(opcode))
1702     {
1703         bool success = false;
1704         const addr_t ip = ReadCoreReg (12, &success);
1705         if (!success)
1706             return false;
1707         uint32_t imm32;
1708         switch (encoding) {
1709         case eEncodingA1:
1710             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1711             break;
1712         default:
1713             return false;
1714         }
1715         addr_t ip_offset = imm32;
1716         addr_t addr = ip - ip_offset; // the adjusted ip value
1717 
1718         EmulateInstruction::Context context;
1719         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1720         RegisterInfo dwarf_reg;
1721         GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg);
1722         context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
1723 
1724         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
1725             return false;
1726     }
1727     return true;
1728 }
1729 
1730 // Set ip to point to some stack offset.
1731 // SUB (SP minus immediate)
1732 bool
1733 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding)
1734 {
1735 #if 0
1736     // ARM pseudo code...
1737     if (ConditionPassed())
1738     {
1739         EncodingSpecificOperations();
1740         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1741         if d == 15 then // Can only occur for ARM encoding
1742            ALUWritePC(result); // setflags is always FALSE here
1743         else
1744             R[d] = result;
1745             if setflags then
1746                 APSR.N = result<31>;
1747                 APSR.Z = IsZeroBit(result);
1748                 APSR.C = carry;
1749                 APSR.V = overflow;
1750     }
1751 #endif
1752 
1753     if (ConditionPassed(opcode))
1754     {
1755         bool success = false;
1756         const addr_t sp = ReadCoreReg (SP_REG, &success);
1757         if (!success)
1758             return false;
1759         uint32_t imm32;
1760         switch (encoding) {
1761         case eEncodingA1:
1762             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1763             break;
1764         default:
1765             return false;
1766         }
1767         addr_t sp_offset = imm32;
1768         addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1769 
1770         EmulateInstruction::Context context;
1771         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1772         RegisterInfo dwarf_reg;
1773         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
1774         context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
1775 
1776         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
1777             return false;
1778     }
1779     return true;
1780 }
1781 
1782 // This instruction subtracts an immediate value from the SP value, and writes
1783 // the result to the destination register.
1784 //
1785 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage.
1786 bool
1787 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding)
1788 {
1789 #if 0
1790     // ARM pseudo code...
1791     if (ConditionPassed())
1792     {
1793         EncodingSpecificOperations();
1794         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1795         if d == 15 then        // Can only occur for ARM encoding
1796            ALUWritePC(result); // setflags is always FALSE here
1797         else
1798             R[d] = result;
1799             if setflags then
1800                 APSR.N = result<31>;
1801                 APSR.Z = IsZeroBit(result);
1802                 APSR.C = carry;
1803                 APSR.V = overflow;
1804     }
1805 #endif
1806 
1807     bool success = false;
1808     if (ConditionPassed(opcode))
1809     {
1810         const addr_t sp = ReadCoreReg (SP_REG, &success);
1811         if (!success)
1812             return false;
1813 
1814         uint32_t Rd;
1815         bool setflags;
1816         uint32_t imm32;
1817         switch (encoding) {
1818         case eEncodingT1:
1819             Rd = 13;
1820             setflags = false;
1821             imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1822             break;
1823         case eEncodingT2:
1824             Rd = Bits32(opcode, 11, 8);
1825             setflags = BitIsSet(opcode, 20);
1826             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1827             if (Rd == 15 && setflags)
1828                 return EmulateCMPImm(opcode, eEncodingT2);
1829             if (Rd == 15 && !setflags)
1830                 return false;
1831             break;
1832         case eEncodingT3:
1833             Rd = Bits32(opcode, 11, 8);
1834             setflags = false;
1835             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
1836             if (Rd == 15)
1837                 return false;
1838             break;
1839         case eEncodingA1:
1840             Rd = Bits32(opcode, 15, 12);
1841             setflags = BitIsSet(opcode, 20);
1842             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1843 
1844             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1845             if (Rd == 15 && setflags)
1846                 return EmulateSUBSPcLrEtc (opcode, encoding);
1847             break;
1848         default:
1849             return false;
1850         }
1851         AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
1852 
1853         EmulateInstruction::Context context;
1854         if (Rd == 13)
1855         {
1856             uint64_t imm64 = imm32;  // Need to expand it to 64 bits before attempting to negate it, or the wrong
1857                                      // value gets passed down to context.SetImmediateSigned.
1858             context.type = EmulateInstruction::eContextAdjustStackPointer;
1859             context.SetImmediateSigned (-imm64); // the stack pointer offset
1860         }
1861         else
1862         {
1863             context.type = EmulateInstruction::eContextImmediate;
1864             context.SetNoArgs ();
1865         }
1866 
1867         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
1868             return false;
1869     }
1870     return true;
1871 }
1872 
1873 // A store operation to the stack that also updates the SP.
1874 bool
1875 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding)
1876 {
1877 #if 0
1878     // ARM pseudo code...
1879     if (ConditionPassed())
1880     {
1881         EncodingSpecificOperations();
1882         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1883         address = if index then offset_addr else R[n];
1884         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1885         if wback then R[n] = offset_addr;
1886     }
1887 #endif
1888 
1889     bool conditional = false;
1890     bool success = false;
1891     if (ConditionPassed(opcode, &conditional))
1892     {
1893         const uint32_t addr_byte_size = GetAddressByteSize();
1894         const addr_t sp = ReadCoreReg (SP_REG, &success);
1895         if (!success)
1896             return false;
1897         uint32_t Rt; // the source register
1898         uint32_t imm12;
1899         uint32_t Rn;  // This function assumes Rn is the SP, but we should verify that.
1900 
1901         bool index;
1902         bool add;
1903         bool wback;
1904         switch (encoding) {
1905         case eEncodingA1:
1906             Rt = Bits32(opcode, 15, 12);
1907             imm12 = Bits32(opcode, 11, 0);
1908             Rn = Bits32 (opcode, 19, 16);
1909 
1910             if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
1911                 return false;
1912 
1913             index = BitIsSet (opcode, 24);
1914             add = BitIsSet (opcode, 23);
1915             wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
1916 
1917             if (wback && ((Rn == 15) || (Rn == Rt)))
1918                 return false;
1919             break;
1920         default:
1921             return false;
1922         }
1923         addr_t offset_addr;
1924         if (add)
1925             offset_addr = sp + imm12;
1926         else
1927             offset_addr = sp - imm12;
1928 
1929         addr_t addr;
1930         if (index)
1931             addr = offset_addr;
1932         else
1933             addr = sp;
1934 
1935         EmulateInstruction::Context context;
1936         if (conditional)
1937             context.type = EmulateInstruction::eContextRegisterStore;
1938         else
1939             context.type = EmulateInstruction::eContextPushRegisterOnStack;
1940         RegisterInfo sp_reg;
1941         RegisterInfo dwarf_reg;
1942 
1943         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1944         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
1945         context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
1946         if (Rt != 15)
1947         {
1948             uint32_t reg_value = ReadCoreReg(Rt, &success);
1949             if (!success)
1950                 return false;
1951             if (!MemUWrite (context, addr, reg_value, addr_byte_size))
1952                 return false;
1953         }
1954         else
1955         {
1956             const uint32_t pc = ReadCoreReg(PC_REG, &success);
1957             if (!success)
1958                 return false;
1959             if (!MemUWrite (context, addr, pc, addr_byte_size))
1960                 return false;
1961         }
1962 
1963 
1964         if (wback)
1965         {
1966             context.type = EmulateInstruction::eContextAdjustStackPointer;
1967             context.SetImmediateSigned (addr - sp);
1968             if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr))
1969                 return false;
1970         }
1971     }
1972     return true;
1973 }
1974 
1975 // Vector Push stores multiple extension registers to the stack.
1976 // It also updates SP to point to the start of the stored data.
1977 bool
1978 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding)
1979 {
1980 #if 0
1981     // ARM pseudo code...
1982     if (ConditionPassed())
1983     {
1984         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1985         address = SP - imm32;
1986         SP = SP - imm32;
1987         if single_regs then
1988             for r = 0 to regs-1
1989                 MemA[address,4] = S[d+r]; address = address+4;
1990         else
1991             for r = 0 to regs-1
1992                 // Store as two word-aligned words in the correct order for current endianness.
1993                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
1994                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
1995                 address = address+8;
1996     }
1997 #endif
1998 
1999     bool success = false;
2000     bool conditional = false;
2001     if (ConditionPassed(opcode, &conditional))
2002     {
2003         const uint32_t addr_byte_size = GetAddressByteSize();
2004         const addr_t sp = ReadCoreReg (SP_REG, &success);
2005         if (!success)
2006             return false;
2007         bool single_regs;
2008         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2009         uint32_t imm32; // stack offset
2010         uint32_t regs;  // number of registers
2011         switch (encoding) {
2012         case eEncodingT1:
2013         case eEncodingA1:
2014             single_regs = false;
2015             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2016             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2017             // If UInt(imm8) is odd, see "FSTMX".
2018             regs = Bits32(opcode, 7, 0) / 2;
2019             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2020             if (regs == 0 || regs > 16 || (d + regs) > 32)
2021                 return false;
2022             break;
2023         case eEncodingT2:
2024         case eEncodingA2:
2025             single_regs = true;
2026             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2027             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2028             regs = Bits32(opcode, 7, 0);
2029             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2030             if (regs == 0 || regs > 16 || (d + regs) > 32)
2031                 return false;
2032             break;
2033         default:
2034             return false;
2035         }
2036         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2037         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2038         addr_t sp_offset = imm32;
2039         addr_t addr = sp - sp_offset;
2040         uint32_t i;
2041 
2042         EmulateInstruction::Context context;
2043         if (conditional)
2044             context.type = EmulateInstruction::eContextRegisterStore;
2045         else
2046             context.type = EmulateInstruction::eContextPushRegisterOnStack;
2047         RegisterInfo dwarf_reg;
2048         RegisterInfo sp_reg;
2049         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2050         for (i=0; i<regs; ++i)
2051         {
2052             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2053             context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
2054             // uint64_t to accommodate 64-bit registers.
2055             uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success);
2056             if (!success)
2057                 return false;
2058             if (!MemAWrite (context, addr, reg_value, reg_byte_size))
2059                 return false;
2060             addr += reg_byte_size;
2061         }
2062 
2063         context.type = EmulateInstruction::eContextAdjustStackPointer;
2064         context.SetImmediateSigned (-sp_offset);
2065 
2066         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2067             return false;
2068     }
2069     return true;
2070 }
2071 
2072 // Vector Pop loads multiple extension registers from the stack.
2073 // It also updates SP to point just above the loaded data.
2074 bool
2075 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding)
2076 {
2077 #if 0
2078     // ARM pseudo code...
2079     if (ConditionPassed())
2080     {
2081         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2082         address = SP;
2083         SP = SP + imm32;
2084         if single_regs then
2085             for r = 0 to regs-1
2086                 S[d+r] = MemA[address,4]; address = address+4;
2087         else
2088             for r = 0 to regs-1
2089                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2090                 // Combine the word-aligned words in the correct order for current endianness.
2091                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2092     }
2093 #endif
2094 
2095     bool success = false;
2096     bool conditional = false;
2097     if (ConditionPassed(opcode, &conditional))
2098     {
2099         const uint32_t addr_byte_size = GetAddressByteSize();
2100         const addr_t sp = ReadCoreReg (SP_REG, &success);
2101         if (!success)
2102             return false;
2103         bool single_regs;
2104         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2105         uint32_t imm32; // stack offset
2106         uint32_t regs;  // number of registers
2107         switch (encoding) {
2108         case eEncodingT1:
2109         case eEncodingA1:
2110             single_regs = false;
2111             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2112             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2113             // If UInt(imm8) is odd, see "FLDMX".
2114             regs = Bits32(opcode, 7, 0) / 2;
2115             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2116             if (regs == 0 || regs > 16 || (d + regs) > 32)
2117                 return false;
2118             break;
2119         case eEncodingT2:
2120         case eEncodingA2:
2121             single_regs = true;
2122             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2123             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2124             regs = Bits32(opcode, 7, 0);
2125             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2126             if (regs == 0 || regs > 16 || (d + regs) > 32)
2127                 return false;
2128             break;
2129         default:
2130             return false;
2131         }
2132         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2133         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2134         addr_t sp_offset = imm32;
2135         addr_t addr = sp;
2136         uint32_t i;
2137         uint64_t data; // uint64_t to accomodate 64-bit registers.
2138 
2139         EmulateInstruction::Context context;
2140         if (conditional)
2141             context.type = EmulateInstruction::eContextRegisterLoad;
2142         else
2143             context.type = EmulateInstruction::eContextPopRegisterOffStack;
2144         RegisterInfo dwarf_reg;
2145         RegisterInfo sp_reg;
2146         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2147         for (i=0; i<regs; ++i)
2148         {
2149             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2150             context.SetRegisterPlusOffset (sp_reg, addr - sp);
2151             data = MemARead(context, addr, reg_byte_size, 0, &success);
2152             if (!success)
2153                 return false;
2154             if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2155                 return false;
2156             addr += reg_byte_size;
2157         }
2158 
2159         context.type = EmulateInstruction::eContextAdjustStackPointer;
2160         context.SetImmediateSigned (sp_offset);
2161 
2162         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2163             return false;
2164     }
2165     return true;
2166 }
2167 
2168 // SVC (previously SWI)
2169 bool
2170 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding)
2171 {
2172 #if 0
2173     // ARM pseudo code...
2174     if (ConditionPassed())
2175     {
2176         EncodingSpecificOperations();
2177         CallSupervisor();
2178     }
2179 #endif
2180 
2181     bool success = false;
2182 
2183     if (ConditionPassed(opcode))
2184     {
2185         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2186         addr_t lr; // next instruction address
2187         if (!success)
2188             return false;
2189         uint32_t imm32; // the immediate constant
2190         uint32_t mode;  // ARM or Thumb mode
2191         switch (encoding) {
2192         case eEncodingT1:
2193             lr = (pc + 2) | 1u; // return address
2194             imm32 = Bits32(opcode, 7, 0);
2195             mode = eModeThumb;
2196             break;
2197         case eEncodingA1:
2198             lr = pc + 4; // return address
2199             imm32 = Bits32(opcode, 23, 0);
2200             mode = eModeARM;
2201             break;
2202         default:
2203             return false;
2204         }
2205 
2206         EmulateInstruction::Context context;
2207         context.type = EmulateInstruction::eContextSupervisorCall;
2208         context.SetISAAndImmediate (mode, imm32);
2209         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
2210             return false;
2211     }
2212     return true;
2213 }
2214 
2215 // If Then makes up to four following instructions (the IT block) conditional.
2216 bool
2217 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding)
2218 {
2219 #if 0
2220     // ARM pseudo code...
2221     EncodingSpecificOperations();
2222     ITSTATE.IT<7:0> = firstcond:mask;
2223 #endif
2224 
2225     m_it_session.InitIT(Bits32(opcode, 7, 0));
2226     return true;
2227 }
2228 
2229 bool
2230 EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding)
2231 {
2232     // NOP, nothing to do...
2233     return true;
2234 }
2235 
2236 // Branch causes a branch to a target address.
2237 bool
2238 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding)
2239 {
2240 #if 0
2241     // ARM pseudo code...
2242     if (ConditionPassed())
2243     {
2244         EncodingSpecificOperations();
2245         BranchWritePC(PC + imm32);
2246     }
2247 #endif
2248 
2249     bool success = false;
2250 
2251     if (ConditionPassed(opcode))
2252     {
2253         EmulateInstruction::Context context;
2254         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2255         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2256         if (!success)
2257             return false;
2258         addr_t target; // target address
2259         int32_t imm32; // PC-relative offset
2260         switch (encoding) {
2261         case eEncodingT1:
2262             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2263             imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2264             target = pc + imm32;
2265             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2266             break;
2267         case eEncodingT2:
2268             imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0));
2269             target = pc + imm32;
2270             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2271             break;
2272         case eEncodingT3:
2273             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2274             {
2275             uint32_t S = Bit32(opcode, 26);
2276             uint32_t imm6 = Bits32(opcode, 21, 16);
2277             uint32_t J1 = Bit32(opcode, 13);
2278             uint32_t J2 = Bit32(opcode, 11);
2279             uint32_t imm11 = Bits32(opcode, 10, 0);
2280             uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2281             imm32 = llvm::SignExtend32<21>(imm21);
2282             target = pc + imm32;
2283             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2284             break;
2285             }
2286         case eEncodingT4:
2287             {
2288             uint32_t S = Bit32(opcode, 26);
2289             uint32_t imm10 = Bits32(opcode, 25, 16);
2290             uint32_t J1 = Bit32(opcode, 13);
2291             uint32_t J2 = Bit32(opcode, 11);
2292             uint32_t imm11 = Bits32(opcode, 10, 0);
2293             uint32_t I1 = !(J1 ^ S);
2294             uint32_t I2 = !(J2 ^ S);
2295             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2296             imm32 = llvm::SignExtend32<25>(imm25);
2297             target = pc + imm32;
2298             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2299             break;
2300             }
2301         case eEncodingA1:
2302             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2303             target = pc + imm32;
2304             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
2305             break;
2306         default:
2307             return false;
2308         }
2309         if (!BranchWritePC(context, target))
2310             return false;
2311     }
2312     return true;
2313 }
2314 
2315 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
2316 // zero and conditionally branch forward a constant value.  They do not affect the condition flags.
2317 // CBNZ, CBZ
2318 bool
2319 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding)
2320 {
2321 #if 0
2322     // ARM pseudo code...
2323     EncodingSpecificOperations();
2324     if nonzero ^ IsZero(R[n]) then
2325         BranchWritePC(PC + imm32);
2326 #endif
2327 
2328     bool success = false;
2329 
2330     // Read the register value from the operand register Rn.
2331     uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2332     if (!success)
2333         return false;
2334 
2335     EmulateInstruction::Context context;
2336     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2337     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2338     if (!success)
2339         return false;
2340 
2341     addr_t target;  // target address
2342     uint32_t imm32; // PC-relative offset to branch forward
2343     bool nonzero;
2344     switch (encoding) {
2345     case eEncodingT1:
2346         imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2347         nonzero = BitIsSet(opcode, 11);
2348         target = pc + imm32;
2349         context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2350         break;
2351     default:
2352         return false;
2353     }
2354     if (nonzero ^ (reg_val == 0))
2355         if (!BranchWritePC(context, target))
2356             return false;
2357 
2358     return true;
2359 }
2360 
2361 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
2362 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2363 // The branch length is twice the value of the byte returned from the table.
2364 //
2365 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
2366 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2367 // The branch length is twice the value of the halfword returned from the table.
2368 // TBB, TBH
2369 bool
2370 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding)
2371 {
2372 #if 0
2373     // ARM pseudo code...
2374     EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2375     if is_tbh then
2376         halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2377     else
2378         halfwords = UInt(MemU[R[n]+R[m], 1]);
2379     BranchWritePC(PC + 2*halfwords);
2380 #endif
2381 
2382     bool success = false;
2383 
2384     uint32_t Rn;     // the base register which contains the address of the table of branch lengths
2385     uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
2386     bool is_tbh;     // true if table branch halfword
2387     switch (encoding) {
2388     case eEncodingT1:
2389         Rn = Bits32(opcode, 19, 16);
2390         Rm = Bits32(opcode, 3, 0);
2391         is_tbh = BitIsSet(opcode, 4);
2392         if (Rn == 13 || BadReg(Rm))
2393             return false;
2394         if (InITBlock() && !LastInITBlock())
2395             return false;
2396         break;
2397     default:
2398         return false;
2399     }
2400 
2401     // Read the address of the table from the operand register Rn.
2402     // The PC can be used, in which case the table immediately follows this instruction.
2403     uint32_t base = ReadCoreReg(Rm, &success);
2404     if (!success)
2405         return false;
2406 
2407     // the table index
2408     uint32_t index = ReadCoreReg(Rm, &success);
2409     if (!success)
2410         return false;
2411 
2412     // the offsetted table address
2413     addr_t addr = base + (is_tbh ? index*2 : index);
2414 
2415     // PC-relative offset to branch forward
2416     EmulateInstruction::Context context;
2417     context.type = EmulateInstruction::eContextTableBranchReadMemory;
2418     uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2419     if (!success)
2420         return false;
2421 
2422     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2423     if (!success)
2424         return false;
2425 
2426     // target address
2427     addr_t target = pc + offset;
2428     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2429     context.SetISAAndImmediateSigned (eModeThumb, 4 + offset);
2430 
2431     if (!BranchWritePC(context, target))
2432         return false;
2433 
2434     return true;
2435 }
2436 
2437 // This instruction adds an immediate value to a register value, and writes the result to the destination register.
2438 // It can optionally update the condition flags based on the result.
2439 bool
2440 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding)
2441 {
2442 #if 0
2443     if ConditionPassed() then
2444         EncodingSpecificOperations();
2445         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2446         R[d] = result;
2447         if setflags then
2448             APSR.N = result<31>;
2449             APSR.Z = IsZeroBit(result);
2450             APSR.C = carry;
2451             APSR.V = overflow;
2452 #endif
2453 
2454     bool success = false;
2455 
2456     if (ConditionPassed(opcode))
2457     {
2458         uint32_t d;
2459         uint32_t n;
2460         bool setflags;
2461         uint32_t imm32;
2462         uint32_t carry_out;
2463 
2464         //EncodingSpecificOperations();
2465         switch (encoding)
2466         {
2467             case eEncodingT1:
2468                 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32);
2469                 d = Bits32 (opcode, 2, 0);
2470                 n = Bits32 (opcode, 5, 3);
2471                 setflags = !InITBlock();
2472                 imm32 = Bits32 (opcode, 8,6);
2473 
2474                 break;
2475 
2476             case eEncodingT2:
2477                 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32);
2478                 d = Bits32 (opcode, 10, 8);
2479                 n = Bits32 (opcode, 10, 8);
2480                 setflags = !InITBlock();
2481                 imm32 = Bits32 (opcode, 7, 0);
2482 
2483                 break;
2484 
2485             case eEncodingT3:
2486                 // if Rd == '1111' && S == '1' then SEE CMN (immediate);
2487                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2488                 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8);
2489                 d = Bits32 (opcode, 11, 8);
2490                 n = Bits32 (opcode, 19, 16);
2491                 setflags = BitIsSet (opcode, 20);
2492                 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out);
2493 
2494                 // if BadReg(d) || n == 15 then UNPREDICTABLE;
2495                 if (BadReg (d) || (n == 15))
2496                     return false;
2497 
2498                 break;
2499 
2500             case eEncodingT4:
2501             {
2502                 // if Rn == '1111' then SEE ADR;
2503                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2504                 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
2505                 d = Bits32 (opcode, 11, 8);
2506                 n = Bits32 (opcode, 19, 16);
2507                 setflags = false;
2508                 uint32_t i = Bit32 (opcode, 26);
2509                 uint32_t imm3 = Bits32 (opcode, 14, 12);
2510                 uint32_t imm8 = Bits32 (opcode, 7, 0);
2511                 imm32 = (i << 11) | (imm3 << 8) | imm8;
2512 
2513                 // if BadReg(d) then UNPREDICTABLE;
2514                 if (BadReg (d))
2515                     return false;
2516 
2517                 break;
2518             }
2519             default:
2520                 return false;
2521         }
2522 
2523         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2524         if (!success)
2525             return false;
2526 
2527         //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2528         AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
2529 
2530         RegisterInfo reg_n;
2531         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
2532 
2533         EmulateInstruction::Context context;
2534         context.type = eContextArithmetic;
2535         context.SetRegisterPlusOffset (reg_n, imm32);
2536 
2537         //R[d] = result;
2538         //if setflags then
2539             //APSR.N = result<31>;
2540             //APSR.Z = IsZeroBit(result);
2541             //APSR.C = carry;
2542             //APSR.V = overflow;
2543         if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
2544             return false;
2545 
2546     }
2547     return true;
2548 }
2549 
2550 // This instruction adds an immediate value to a register value, and writes the result to the destination
2551 // register.  It can optionally update the condition flags based on the result.
2552 bool
2553 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding)
2554 {
2555 #if 0
2556     // ARM pseudo code...
2557     if ConditionPassed() then
2558         EncodingSpecificOperations();
2559         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2560         if d == 15 then
2561             ALUWritePC(result); // setflags is always FALSE here
2562         else
2563             R[d] = result;
2564             if setflags then
2565                 APSR.N = result<31>;
2566                 APSR.Z = IsZeroBit(result);
2567                 APSR.C = carry;
2568                 APSR.V = overflow;
2569 #endif
2570 
2571     bool success = false;
2572 
2573     if (ConditionPassed(opcode))
2574     {
2575         uint32_t Rd, Rn;
2576         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
2577         bool setflags;
2578         switch (encoding)
2579         {
2580         case eEncodingA1:
2581             Rd = Bits32(opcode, 15, 12);
2582             Rn = Bits32(opcode, 19, 16);
2583             setflags = BitIsSet(opcode, 20);
2584             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2585             break;
2586         default:
2587             return false;
2588         }
2589 
2590         // Read the first operand.
2591         uint32_t val1 = ReadCoreReg(Rn, &success);
2592         if (!success)
2593             return false;
2594 
2595         AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
2596 
2597         EmulateInstruction::Context context;
2598         context.type = eContextArithmetic;
2599         RegisterInfo dwarf_reg;
2600         GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
2601         context.SetRegisterPlusOffset (dwarf_reg, imm32);
2602 
2603         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2604             return false;
2605     }
2606     return true;
2607 }
2608 
2609 // This instruction adds a register value and an optionally-shifted register value, and writes the result
2610 // to the destination register. It can optionally update the condition flags based on the result.
2611 bool
2612 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding)
2613 {
2614 #if 0
2615     // ARM pseudo code...
2616     if ConditionPassed() then
2617         EncodingSpecificOperations();
2618         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2619         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2620         if d == 15 then
2621             ALUWritePC(result); // setflags is always FALSE here
2622         else
2623             R[d] = result;
2624             if setflags then
2625                 APSR.N = result<31>;
2626                 APSR.Z = IsZeroBit(result);
2627                 APSR.C = carry;
2628                 APSR.V = overflow;
2629 #endif
2630 
2631     bool success = false;
2632 
2633     if (ConditionPassed(opcode))
2634     {
2635         uint32_t Rd, Rn, Rm;
2636         ARM_ShifterType shift_t;
2637         uint32_t shift_n; // the shift applied to the value read from Rm
2638         bool setflags;
2639         switch (encoding)
2640         {
2641         case eEncodingT1:
2642             Rd = Bits32(opcode, 2, 0);
2643             Rn = Bits32(opcode, 5, 3);
2644             Rm = Bits32(opcode, 8, 6);
2645             setflags = !InITBlock();
2646             shift_t = SRType_LSL;
2647             shift_n = 0;
2648             break;
2649         case eEncodingT2:
2650             Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2651             Rm = Bits32(opcode, 6, 3);
2652             setflags = false;
2653             shift_t = SRType_LSL;
2654             shift_n = 0;
2655             if (Rn == 15 && Rm == 15)
2656                 return false;
2657             if (Rd == 15 && InITBlock() && !LastInITBlock())
2658                 return false;
2659             break;
2660         case eEncodingA1:
2661             Rd = Bits32(opcode, 15, 12);
2662             Rn = Bits32(opcode, 19, 16);
2663             Rm = Bits32(opcode, 3, 0);
2664             setflags = BitIsSet(opcode, 20);
2665             shift_n = DecodeImmShiftARM(opcode, shift_t);
2666             break;
2667         default:
2668             return false;
2669         }
2670 
2671         // Read the first operand.
2672         uint32_t val1 = ReadCoreReg(Rn, &success);
2673         if (!success)
2674             return false;
2675 
2676         // Read the second operand.
2677         uint32_t val2 = ReadCoreReg(Rm, &success);
2678         if (!success)
2679             return false;
2680 
2681         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2682         if (!success)
2683             return false;
2684         AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2685 
2686         EmulateInstruction::Context context;
2687         context.type = eContextArithmetic;
2688         RegisterInfo op1_reg;
2689         RegisterInfo op2_reg;
2690         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
2691         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
2692         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
2693 
2694         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2695             return false;
2696     }
2697     return true;
2698 }
2699 
2700 // Compare Negative (immediate) adds a register value and an immediate value.
2701 // It updates the condition flags based on the result, and discards the result.
2702 bool
2703 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding)
2704 {
2705 #if 0
2706     // ARM pseudo code...
2707     if ConditionPassed() then
2708         EncodingSpecificOperations();
2709         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2710         APSR.N = result<31>;
2711         APSR.Z = IsZeroBit(result);
2712         APSR.C = carry;
2713         APSR.V = overflow;
2714 #endif
2715 
2716     bool success = false;
2717 
2718     uint32_t Rn; // the first operand
2719     uint32_t imm32; // the immediate value to be compared with
2720     switch (encoding) {
2721     case eEncodingT1:
2722         Rn = Bits32(opcode, 19, 16);
2723         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2724         if (Rn == 15)
2725             return false;
2726         break;
2727     case eEncodingA1:
2728         Rn = Bits32(opcode, 19, 16);
2729         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2730         break;
2731     default:
2732         return false;
2733     }
2734     // Read the register value from the operand register Rn.
2735     uint32_t reg_val = ReadCoreReg(Rn, &success);
2736     if (!success)
2737         return false;
2738 
2739     AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
2740 
2741     EmulateInstruction::Context context;
2742     context.type = EmulateInstruction::eContextImmediate;
2743     context.SetNoArgs ();
2744     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2745         return false;
2746 
2747     return true;
2748 }
2749 
2750 // Compare Negative (register) adds a register value and an optionally-shifted register value.
2751 // It updates the condition flags based on the result, and discards the result.
2752 bool
2753 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding)
2754 {
2755 #if 0
2756     // ARM pseudo code...
2757     if ConditionPassed() then
2758         EncodingSpecificOperations();
2759         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2760         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2761         APSR.N = result<31>;
2762         APSR.Z = IsZeroBit(result);
2763         APSR.C = carry;
2764         APSR.V = overflow;
2765 #endif
2766 
2767     bool success = false;
2768 
2769     uint32_t Rn; // the first operand
2770     uint32_t Rm; // the second operand
2771     ARM_ShifterType shift_t;
2772     uint32_t shift_n; // the shift applied to the value read from Rm
2773     switch (encoding) {
2774     case eEncodingT1:
2775         Rn = Bits32(opcode, 2, 0);
2776         Rm = Bits32(opcode, 5, 3);
2777         shift_t = SRType_LSL;
2778         shift_n = 0;
2779         break;
2780     case eEncodingT2:
2781         Rn = Bits32(opcode, 19, 16);
2782         Rm = Bits32(opcode, 3, 0);
2783         shift_n = DecodeImmShiftThumb(opcode, shift_t);
2784         // if n == 15 || BadReg(m) then UNPREDICTABLE;
2785         if (Rn == 15 || BadReg(Rm))
2786             return false;
2787         break;
2788     case eEncodingA1:
2789         Rn = Bits32(opcode, 19, 16);
2790         Rm = Bits32(opcode, 3, 0);
2791         shift_n = DecodeImmShiftARM(opcode, shift_t);
2792         break;
2793     default:
2794         return false;
2795     }
2796     // Read the register value from register Rn.
2797     uint32_t val1 = ReadCoreReg(Rn, &success);
2798     if (!success)
2799         return false;
2800 
2801     // Read the register value from register Rm.
2802     uint32_t val2 = ReadCoreReg(Rm, &success);
2803     if (!success)
2804         return false;
2805 
2806     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2807     if (!success)
2808         return false;
2809     AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2810 
2811     EmulateInstruction::Context context;
2812     context.type = EmulateInstruction::eContextImmediate;
2813     context.SetNoArgs();
2814     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2815         return false;
2816 
2817     return true;
2818 }
2819 
2820 // Compare (immediate) subtracts an immediate value from a register value.
2821 // It updates the condition flags based on the result, and discards the result.
2822 bool
2823 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding)
2824 {
2825 #if 0
2826     // ARM pseudo code...
2827     if ConditionPassed() then
2828         EncodingSpecificOperations();
2829         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2830         APSR.N = result<31>;
2831         APSR.Z = IsZeroBit(result);
2832         APSR.C = carry;
2833         APSR.V = overflow;
2834 #endif
2835 
2836     bool success = false;
2837 
2838     uint32_t Rn; // the first operand
2839     uint32_t imm32; // the immediate value to be compared with
2840     switch (encoding) {
2841     case eEncodingT1:
2842         Rn = Bits32(opcode, 10, 8);
2843         imm32 = Bits32(opcode, 7, 0);
2844         break;
2845     case eEncodingT2:
2846         Rn = Bits32(opcode, 19, 16);
2847         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2848         if (Rn == 15)
2849             return false;
2850         break;
2851     case eEncodingA1:
2852         Rn = Bits32(opcode, 19, 16);
2853         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2854         break;
2855     default:
2856         return false;
2857     }
2858     // Read the register value from the operand register Rn.
2859     uint32_t reg_val = ReadCoreReg(Rn, &success);
2860     if (!success)
2861         return false;
2862 
2863     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
2864 
2865     EmulateInstruction::Context context;
2866     context.type = EmulateInstruction::eContextImmediate;
2867     context.SetNoArgs ();
2868     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2869         return false;
2870 
2871     return true;
2872 }
2873 
2874 // Compare (register) subtracts an optionally-shifted register value from a register value.
2875 // It updates the condition flags based on the result, and discards the result.
2876 bool
2877 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding)
2878 {
2879 #if 0
2880     // ARM pseudo code...
2881     if ConditionPassed() then
2882         EncodingSpecificOperations();
2883         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2884         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2885         APSR.N = result<31>;
2886         APSR.Z = IsZeroBit(result);
2887         APSR.C = carry;
2888         APSR.V = overflow;
2889 #endif
2890 
2891     bool success = false;
2892 
2893     uint32_t Rn; // the first operand
2894     uint32_t Rm; // the second operand
2895     ARM_ShifterType shift_t;
2896     uint32_t shift_n; // the shift applied to the value read from Rm
2897     switch (encoding) {
2898     case eEncodingT1:
2899         Rn = Bits32(opcode, 2, 0);
2900         Rm = Bits32(opcode, 5, 3);
2901         shift_t = SRType_LSL;
2902         shift_n = 0;
2903         break;
2904     case eEncodingT2:
2905         Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2906         Rm = Bits32(opcode, 6, 3);
2907         shift_t = SRType_LSL;
2908         shift_n = 0;
2909         if (Rn < 8 && Rm < 8)
2910             return false;
2911         if (Rn == 15 || Rm == 15)
2912             return false;
2913         break;
2914     case eEncodingA1:
2915         Rn = Bits32(opcode, 19, 16);
2916         Rm = Bits32(opcode, 3, 0);
2917         shift_n = DecodeImmShiftARM(opcode, shift_t);
2918         break;
2919     default:
2920         return false;
2921     }
2922     // Read the register value from register Rn.
2923     uint32_t val1 = ReadCoreReg(Rn, &success);
2924     if (!success)
2925         return false;
2926 
2927     // Read the register value from register Rm.
2928     uint32_t val2 = ReadCoreReg(Rm, &success);
2929     if (!success)
2930         return false;
2931 
2932     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2933     if (!success)
2934         return false;
2935     AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
2936 
2937     EmulateInstruction::Context context;
2938     context.type = EmulateInstruction::eContextImmediate;
2939     context.SetNoArgs();
2940     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2941         return false;
2942 
2943     return true;
2944 }
2945 
2946 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
2947 // shifting in copies of its sign bit, and writes the result to the destination register.  It can
2948 // optionally update the condition flags based on the result.
2949 bool
2950 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding)
2951 {
2952 #if 0
2953     // ARM pseudo code...
2954     if ConditionPassed() then
2955         EncodingSpecificOperations();
2956         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2957         if d == 15 then         // Can only occur for ARM encoding
2958             ALUWritePC(result); // setflags is always FALSE here
2959         else
2960             R[d] = result;
2961             if setflags then
2962                 APSR.N = result<31>;
2963                 APSR.Z = IsZeroBit(result);
2964                 APSR.C = carry;
2965                 // APSR.V unchanged
2966 #endif
2967 
2968     return EmulateShiftImm (opcode, encoding, SRType_ASR);
2969 }
2970 
2971 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
2972 // shifting in copies of its sign bit, and writes the result to the destination register.
2973 // The variable number of bits is read from the bottom byte of a register. It can optionally update
2974 // the condition flags based on the result.
2975 bool
2976 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding)
2977 {
2978 #if 0
2979     // ARM pseudo code...
2980     if ConditionPassed() then
2981         EncodingSpecificOperations();
2982         shift_n = UInt(R[m]<7:0>);
2983         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2984         R[d] = result;
2985         if setflags then
2986             APSR.N = result<31>;
2987             APSR.Z = IsZeroBit(result);
2988             APSR.C = carry;
2989             // APSR.V unchanged
2990 #endif
2991 
2992     return EmulateShiftReg (opcode, encoding, SRType_ASR);
2993 }
2994 
2995 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
2996 // shifting in zeros, and writes the result to the destination register.  It can optionally
2997 // update the condition flags based on the result.
2998 bool
2999 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding)
3000 {
3001 #if 0
3002     // ARM pseudo code...
3003     if ConditionPassed() then
3004         EncodingSpecificOperations();
3005         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3006         if d == 15 then         // Can only occur for ARM encoding
3007             ALUWritePC(result); // setflags is always FALSE here
3008         else
3009             R[d] = result;
3010             if setflags then
3011                 APSR.N = result<31>;
3012                 APSR.Z = IsZeroBit(result);
3013                 APSR.C = carry;
3014                 // APSR.V unchanged
3015 #endif
3016 
3017     return EmulateShiftImm (opcode, encoding, SRType_LSL);
3018 }
3019 
3020 // Logical Shift Left (register) shifts a register value left by a variable number of bits,
3021 // shifting in zeros, and writes the result to the destination register.  The variable number
3022 // of bits is read from the bottom byte of a register. It can optionally update the condition
3023 // flags based on the result.
3024 bool
3025 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding)
3026 {
3027 #if 0
3028     // ARM pseudo code...
3029     if ConditionPassed() then
3030         EncodingSpecificOperations();
3031         shift_n = UInt(R[m]<7:0>);
3032         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3033         R[d] = result;
3034         if setflags then
3035             APSR.N = result<31>;
3036             APSR.Z = IsZeroBit(result);
3037             APSR.C = carry;
3038             // APSR.V unchanged
3039 #endif
3040 
3041     return EmulateShiftReg (opcode, encoding, SRType_LSL);
3042 }
3043 
3044 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
3045 // shifting in zeros, and writes the result to the destination register.  It can optionally
3046 // update the condition flags based on the result.
3047 bool
3048 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding)
3049 {
3050 #if 0
3051     // ARM pseudo code...
3052     if ConditionPassed() then
3053         EncodingSpecificOperations();
3054         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3055         if d == 15 then         // Can only occur for ARM encoding
3056             ALUWritePC(result); // setflags is always FALSE here
3057         else
3058             R[d] = result;
3059             if setflags then
3060                 APSR.N = result<31>;
3061                 APSR.Z = IsZeroBit(result);
3062                 APSR.C = carry;
3063                 // APSR.V unchanged
3064 #endif
3065 
3066     return EmulateShiftImm (opcode, encoding, SRType_LSR);
3067 }
3068 
3069 // Logical Shift Right (register) shifts a register value right by a variable number of bits,
3070 // shifting in zeros, and writes the result to the destination register.  The variable number
3071 // of bits is read from the bottom byte of a register. It can optionally update the condition
3072 // flags based on the result.
3073 bool
3074 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding)
3075 {
3076 #if 0
3077     // ARM pseudo code...
3078     if ConditionPassed() then
3079         EncodingSpecificOperations();
3080         shift_n = UInt(R[m]<7:0>);
3081         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3082         R[d] = result;
3083         if setflags then
3084             APSR.N = result<31>;
3085             APSR.Z = IsZeroBit(result);
3086             APSR.C = carry;
3087             // APSR.V unchanged
3088 #endif
3089 
3090     return EmulateShiftReg (opcode, encoding, SRType_LSR);
3091 }
3092 
3093 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
3094 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3095 // It can optionally update the condition flags based on the result.
3096 bool
3097 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding)
3098 {
3099 #if 0
3100     // ARM pseudo code...
3101     if ConditionPassed() then
3102         EncodingSpecificOperations();
3103         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3104         if d == 15 then         // Can only occur for ARM encoding
3105             ALUWritePC(result); // setflags is always FALSE here
3106         else
3107             R[d] = result;
3108             if setflags then
3109                 APSR.N = result<31>;
3110                 APSR.Z = IsZeroBit(result);
3111                 APSR.C = carry;
3112                 // APSR.V unchanged
3113 #endif
3114 
3115     return EmulateShiftImm (opcode, encoding, SRType_ROR);
3116 }
3117 
3118 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
3119 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3120 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
3121 // flags based on the result.
3122 bool
3123 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding)
3124 {
3125 #if 0
3126     // ARM pseudo code...
3127     if ConditionPassed() then
3128         EncodingSpecificOperations();
3129         shift_n = UInt(R[m]<7:0>);
3130         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3131         R[d] = result;
3132         if setflags then
3133             APSR.N = result<31>;
3134             APSR.Z = IsZeroBit(result);
3135             APSR.C = carry;
3136             // APSR.V unchanged
3137 #endif
3138 
3139     return EmulateShiftReg (opcode, encoding, SRType_ROR);
3140 }
3141 
3142 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
3143 // with the carry flag shifted into bit [31].
3144 //
3145 // RRX can optionally update the condition flags based on the result.
3146 // In that case, bit [0] is shifted into the carry flag.
3147 bool
3148 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding)
3149 {
3150 #if 0
3151     // ARM pseudo code...
3152     if ConditionPassed() then
3153         EncodingSpecificOperations();
3154         (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3155         if d == 15 then         // Can only occur for ARM encoding
3156             ALUWritePC(result); // setflags is always FALSE here
3157         else
3158             R[d] = result;
3159             if setflags then
3160                 APSR.N = result<31>;
3161                 APSR.Z = IsZeroBit(result);
3162                 APSR.C = carry;
3163                 // APSR.V unchanged
3164 #endif
3165 
3166     return EmulateShiftImm (opcode, encoding, SRType_RRX);
3167 }
3168 
3169 bool
3170 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3171 {
3172 //    assert(shift_type == SRType_ASR
3173 //           || shift_type == SRType_LSL
3174 //           || shift_type == SRType_LSR
3175 //           || shift_type == SRType_ROR
3176 //           || shift_type == SRType_RRX);
3177 
3178     bool success = false;
3179 
3180     if (ConditionPassed(opcode))
3181     {
3182         uint32_t Rd;    // the destination register
3183         uint32_t Rm;    // the first operand register
3184         uint32_t imm5;  // encoding for the shift amount
3185         uint32_t carry; // the carry bit after the shift operation
3186         bool setflags;
3187 
3188         // Special case handling!
3189         // A8.6.139 ROR (immediate) -- Encoding T1
3190         ARMEncoding use_encoding = encoding;
3191         if (shift_type == SRType_ROR && use_encoding == eEncodingT1)
3192         {
3193             // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
3194             // have the same decoding of bit fields as the other Thumb2 shift operations.
3195             use_encoding = eEncodingT2;
3196         }
3197 
3198         switch (use_encoding) {
3199         case eEncodingT1:
3200             // Due to the above special case handling!
3201             if (shift_type == SRType_ROR)
3202                 return false;
3203 
3204             Rd = Bits32(opcode, 2, 0);
3205             Rm = Bits32(opcode, 5, 3);
3206             setflags = !InITBlock();
3207             imm5 = Bits32(opcode, 10, 6);
3208             break;
3209         case eEncodingT2:
3210             // A8.6.141 RRX
3211             // There's no imm form of RRX instructions.
3212             if (shift_type == SRType_RRX)
3213                 return false;
3214 
3215             Rd = Bits32(opcode, 11, 8);
3216             Rm = Bits32(opcode, 3, 0);
3217             setflags = BitIsSet(opcode, 20);
3218             imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3219             if (BadReg(Rd) || BadReg(Rm))
3220                 return false;
3221             break;
3222         case eEncodingA1:
3223             Rd = Bits32(opcode, 15, 12);
3224             Rm = Bits32(opcode, 3, 0);
3225             setflags = BitIsSet(opcode, 20);
3226             imm5 = Bits32(opcode, 11, 7);
3227             break;
3228         default:
3229             return false;
3230         }
3231 
3232         // A8.6.139 ROR (immediate)
3233         if (shift_type == SRType_ROR && imm5 == 0)
3234             shift_type = SRType_RRX;
3235 
3236         // Get the first operand.
3237         uint32_t value = ReadCoreReg (Rm, &success);
3238         if (!success)
3239             return false;
3240 
3241         // Decode the shift amount if not RRX.
3242         uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3243 
3244         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3245         if (!success)
3246             return false;
3247 
3248         // The context specifies that an immediate is to be moved into Rd.
3249         EmulateInstruction::Context context;
3250         context.type = EmulateInstruction::eContextImmediate;
3251         context.SetNoArgs ();
3252 
3253         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3254             return false;
3255     }
3256     return true;
3257 }
3258 
3259 bool
3260 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3261 {
3262     // assert(shift_type == SRType_ASR
3263     //        || shift_type == SRType_LSL
3264     //        || shift_type == SRType_LSR
3265     //        || shift_type == SRType_ROR);
3266 
3267     bool success = false;
3268 
3269     if (ConditionPassed(opcode))
3270     {
3271         uint32_t Rd;    // the destination register
3272         uint32_t Rn;    // the first operand register
3273         uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
3274         uint32_t carry; // the carry bit after the shift operation
3275         bool setflags;
3276         switch (encoding) {
3277         case eEncodingT1:
3278             Rd = Bits32(opcode, 2, 0);
3279             Rn = Rd;
3280             Rm = Bits32(opcode, 5, 3);
3281             setflags = !InITBlock();
3282             break;
3283         case eEncodingT2:
3284             Rd = Bits32(opcode, 11, 8);
3285             Rn = Bits32(opcode, 19, 16);
3286             Rm = Bits32(opcode, 3, 0);
3287             setflags = BitIsSet(opcode, 20);
3288             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3289                 return false;
3290             break;
3291         case eEncodingA1:
3292             Rd = Bits32(opcode, 15, 12);
3293             Rn = Bits32(opcode, 3, 0);
3294             Rm = Bits32(opcode, 11, 8);
3295             setflags = BitIsSet(opcode, 20);
3296             if (Rd == 15 || Rn == 15 || Rm == 15)
3297                 return false;
3298             break;
3299         default:
3300             return false;
3301         }
3302 
3303         // Get the first operand.
3304         uint32_t value = ReadCoreReg (Rn, &success);
3305         if (!success)
3306             return false;
3307         // Get the Rm register content.
3308         uint32_t val = ReadCoreReg (Rm, &success);
3309         if (!success)
3310             return false;
3311 
3312         // Get the shift amount.
3313         uint32_t amt = Bits32(val, 7, 0);
3314 
3315         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3316         if (!success)
3317             return false;
3318 
3319         // The context specifies that an immediate is to be moved into Rd.
3320         EmulateInstruction::Context context;
3321         context.type = EmulateInstruction::eContextImmediate;
3322         context.SetNoArgs ();
3323 
3324         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3325             return false;
3326     }
3327     return true;
3328 }
3329 
3330 // LDM loads multiple registers from consecutive memory locations, using an
3331 // address from a base register.  Optionally the address just above the highest of those locations
3332 // can be written back to the base register.
3333 bool
3334 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding)
3335 {
3336 #if 0
3337     // ARM pseudo code...
3338     if ConditionPassed()
3339         EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3340         address = R[n];
3341 
3342         for i = 0 to 14
3343             if registers<i> == '1' then
3344                 R[i] = MemA[address, 4]; address = address + 4;
3345         if registers<15> == '1' then
3346             LoadWritePC (MemA[address, 4]);
3347 
3348         if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3349         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3350 
3351 #endif
3352 
3353     bool success = false;
3354     bool conditional = false;
3355     if (ConditionPassed(opcode, &conditional))
3356     {
3357         uint32_t n;
3358         uint32_t registers = 0;
3359         bool wback;
3360         const uint32_t addr_byte_size = GetAddressByteSize();
3361         switch (encoding)
3362         {
3363             case eEncodingT1:
3364                 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0');
3365                 n = Bits32 (opcode, 10, 8);
3366                 registers = Bits32 (opcode, 7, 0);
3367                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3368                 wback = BitIsClear (registers, n);
3369                 // if BitCount(registers) < 1 then UNPREDICTABLE;
3370                 if (BitCount(registers) < 1)
3371                     return false;
3372                 break;
3373             case eEncodingT2:
3374                 // if W == '1' && Rn == '1101' then SEE POP;
3375                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3376                 n = Bits32 (opcode, 19, 16);
3377                 registers = Bits32 (opcode, 15, 0);
3378                 registers = registers & 0xdfff; // Make sure bit 13 is zero.
3379                 wback = BitIsSet (opcode, 21);
3380 
3381                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3382                 if ((n == 15)
3383                     || (BitCount (registers) < 2)
3384                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3385                     return false;
3386 
3387                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3388                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3389                     return false;
3390 
3391                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3392                 if (wback
3393                     && BitIsSet (registers, n))
3394                     return false;
3395                 break;
3396 
3397             case eEncodingA1:
3398                 n = Bits32 (opcode, 19, 16);
3399                 registers = Bits32 (opcode, 15, 0);
3400                 wback = BitIsSet (opcode, 21);
3401                 if ((n == 15)
3402                     || (BitCount (registers) < 1))
3403                     return false;
3404                 break;
3405             default:
3406                 return false;
3407         }
3408 
3409         int32_t offset = 0;
3410         const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3411         if (!success)
3412             return false;
3413 
3414         EmulateInstruction::Context context;
3415         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3416         RegisterInfo dwarf_reg;
3417         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3418         context.SetRegisterPlusOffset (dwarf_reg, offset);
3419 
3420         for (int i = 0; i < 14; ++i)
3421         {
3422             if (BitIsSet (registers, i))
3423             {
3424                 context.type = EmulateInstruction::eContextRegisterPlusOffset;
3425                 context.SetRegisterPlusOffset (dwarf_reg, offset);
3426                 if (wback && (n == 13)) // Pop Instruction
3427                 {
3428                     if (conditional)
3429                         context.type = EmulateInstruction::eContextRegisterLoad;
3430                     else
3431                         context.type = EmulateInstruction::eContextPopRegisterOffStack;
3432                 }
3433 
3434                 // R[i] = MemA [address, 4]; address = address + 4;
3435                 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3436                 if (!success)
3437                     return false;
3438 
3439                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3440                     return false;
3441 
3442                 offset += addr_byte_size;
3443             }
3444         }
3445 
3446         if (BitIsSet (registers, 15))
3447         {
3448             //LoadWritePC (MemA [address, 4]);
3449             context.type = EmulateInstruction::eContextRegisterPlusOffset;
3450             context.SetRegisterPlusOffset (dwarf_reg, offset);
3451             uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3452             if (!success)
3453                 return false;
3454             // In ARMv5T and above, this is an interworking branch.
3455             if (!LoadWritePC(context, data))
3456                 return false;
3457         }
3458 
3459         if (wback && BitIsClear (registers, n))
3460         {
3461             // R[n] = R[n] + 4 * BitCount (registers)
3462             int32_t offset = addr_byte_size * BitCount (registers);
3463             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3464             context.SetRegisterPlusOffset (dwarf_reg, offset);
3465 
3466             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
3467                 return false;
3468         }
3469         if (wback && BitIsSet (registers, n))
3470             // R[n] bits(32) UNKNOWN;
3471             return WriteBits32Unknown (n);
3472     }
3473     return true;
3474 }
3475 
3476 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register.
3477 // The consecutive memory locations end at this address and the address just below the lowest of those locations
3478 // can optionally be written back to the base register.
3479 bool
3480 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding)
3481 {
3482 #if 0
3483     // ARM pseudo code...
3484     if ConditionPassed() then
3485         EncodingSpecificOperations();
3486         address = R[n] - 4*BitCount(registers) + 4;
3487 
3488         for i = 0 to 14
3489             if registers<i> == '1' then
3490                   R[i] = MemA[address,4]; address = address + 4;
3491 
3492         if registers<15> == '1' then
3493             LoadWritePC(MemA[address,4]);
3494 
3495         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3496         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3497 #endif
3498 
3499     bool success = false;
3500 
3501     if (ConditionPassed(opcode))
3502     {
3503         uint32_t n;
3504         uint32_t registers = 0;
3505         bool wback;
3506         const uint32_t addr_byte_size = GetAddressByteSize();
3507 
3508         // EncodingSpecificOperations();
3509         switch (encoding)
3510         {
3511             case eEncodingA1:
3512                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3513                 n = Bits32 (opcode, 19, 16);
3514                 registers = Bits32 (opcode, 15, 0);
3515                 wback = BitIsSet (opcode, 21);
3516 
3517                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3518                 if ((n == 15) || (BitCount (registers) < 1))
3519                     return false;
3520 
3521                 break;
3522 
3523             default:
3524                 return false;
3525         }
3526         // address = R[n] - 4*BitCount(registers) + 4;
3527 
3528         int32_t offset = 0;
3529         addr_t Rn = ReadCoreReg (n, &success);
3530 
3531         if (!success)
3532             return false;
3533 
3534         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size;
3535 
3536         EmulateInstruction::Context context;
3537         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3538         RegisterInfo dwarf_reg;
3539         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3540         context.SetRegisterPlusOffset (dwarf_reg, offset);
3541 
3542         // for i = 0 to 14
3543         for (int i = 0; i < 14; ++i)
3544         {
3545             // if registers<i> == '1' then
3546             if (BitIsSet (registers, i))
3547             {
3548                   // R[i] = MemA[address,4]; address = address + 4;
3549                   context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3550                   uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3551                   if (!success)
3552                       return false;
3553                   if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3554                       return false;
3555                   offset += addr_byte_size;
3556             }
3557         }
3558 
3559         // if registers<15> == '1' then
3560         //     LoadWritePC(MemA[address,4]);
3561         if (BitIsSet (registers, 15))
3562         {
3563             context.SetRegisterPlusOffset (dwarf_reg, offset);
3564             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3565             if (!success)
3566                 return false;
3567             // In ARMv5T and above, this is an interworking branch.
3568             if (!LoadWritePC(context, data))
3569                 return false;
3570         }
3571 
3572         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3573         if (wback && BitIsClear (registers, n))
3574         {
3575             if (!success)
3576                 return false;
3577 
3578             offset = (addr_byte_size * BitCount (registers)) * -1;
3579             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3580             context.SetImmediateSigned (offset);
3581             addr_t addr = Rn + offset;
3582             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3583                 return false;
3584         }
3585 
3586         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3587         if (wback && BitIsSet (registers, n))
3588             return WriteBits32Unknown (n);
3589     }
3590     return true;
3591 }
3592 
3593 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
3594 // consecutive memory lcoations end just below this address, and the address of the lowest of those locations can
3595 // be optionally written back to the base register.
3596 bool
3597 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding)
3598 {
3599 #if 0
3600     // ARM pseudo code...
3601     if ConditionPassed() then
3602         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3603         address = R[n] - 4*BitCount(registers);
3604 
3605         for i = 0 to 14
3606             if registers<i> == '1' then
3607                   R[i] = MemA[address,4]; address = address + 4;
3608         if registers<15> == '1' then
3609                   LoadWritePC(MemA[address,4]);
3610 
3611         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3612         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3613 #endif
3614 
3615     bool success = false;
3616 
3617     if (ConditionPassed(opcode))
3618     {
3619         uint32_t n;
3620         uint32_t registers = 0;
3621         bool wback;
3622         const uint32_t addr_byte_size = GetAddressByteSize();
3623         switch (encoding)
3624         {
3625             case eEncodingT1:
3626                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3627                 n = Bits32 (opcode, 19, 16);
3628                 registers = Bits32 (opcode, 15, 0);
3629                 registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
3630                 wback = BitIsSet (opcode, 21);
3631 
3632                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3633                 if ((n == 15)
3634                     || (BitCount (registers) < 2)
3635                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3636                     return false;
3637 
3638                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3639                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3640                     return false;
3641 
3642                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3643                 if (wback && BitIsSet (registers, n))
3644                     return false;
3645 
3646                 break;
3647 
3648             case eEncodingA1:
3649                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3650                 n = Bits32 (opcode, 19, 16);
3651                 registers = Bits32 (opcode, 15, 0);
3652                 wback = BitIsSet (opcode, 21);
3653 
3654                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3655                 if ((n == 15) || (BitCount (registers) < 1))
3656                     return false;
3657 
3658                 break;
3659 
3660             default:
3661                 return false;
3662         }
3663 
3664         // address = R[n] - 4*BitCount(registers);
3665 
3666         int32_t offset = 0;
3667         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3668 
3669         if (!success)
3670             return false;
3671 
3672         addr_t address = Rn - (addr_byte_size * BitCount (registers));
3673         EmulateInstruction::Context context;
3674         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3675         RegisterInfo dwarf_reg;
3676         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3677         context.SetRegisterPlusOffset (dwarf_reg, Rn - address);
3678 
3679         for (int i = 0; i < 14; ++i)
3680         {
3681             if (BitIsSet (registers, i))
3682             {
3683                 // R[i] = MemA[address,4]; address = address + 4;
3684                 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3685                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3686                 if (!success)
3687                     return false;
3688 
3689                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3690                     return false;
3691 
3692                 offset += addr_byte_size;
3693             }
3694         }
3695 
3696         // if registers<15> == '1' then
3697         //     LoadWritePC(MemA[address,4]);
3698         if (BitIsSet (registers, 15))
3699         {
3700             context.SetRegisterPlusOffset (dwarf_reg, offset);
3701             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3702             if (!success)
3703                 return false;
3704             // In ARMv5T and above, this is an interworking branch.
3705             if (!LoadWritePC(context, data))
3706                 return false;
3707         }
3708 
3709         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3710         if (wback && BitIsClear (registers, n))
3711         {
3712             if (!success)
3713                 return false;
3714 
3715             offset = (addr_byte_size * BitCount (registers)) * -1;
3716             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3717             context.SetImmediateSigned (offset);
3718             addr_t addr = Rn + offset;
3719             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3720                 return false;
3721         }
3722 
3723         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3724         if (wback && BitIsSet (registers, n))
3725             return WriteBits32Unknown (n);
3726     }
3727     return true;
3728 }
3729 
3730 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
3731 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can
3732 // optinoally be written back to the base register.
3733 bool
3734 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding)
3735 {
3736 #if 0
3737     if ConditionPassed() then
3738         EncodingSpecificOperations();
3739         address = R[n] + 4;
3740 
3741         for i = 0 to 14
3742             if registers<i> == '1' then
3743                   R[i] = MemA[address,4]; address = address + 4;
3744         if registers<15> == '1' then
3745             LoadWritePC(MemA[address,4]);
3746 
3747         if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3748         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3749 #endif
3750 
3751     bool success = false;
3752 
3753     if (ConditionPassed(opcode))
3754     {
3755         uint32_t n;
3756         uint32_t registers = 0;
3757         bool wback;
3758         const uint32_t addr_byte_size = GetAddressByteSize();
3759         switch (encoding)
3760         {
3761             case eEncodingA1:
3762                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3763                 n = Bits32 (opcode, 19, 16);
3764                 registers = Bits32 (opcode, 15, 0);
3765                 wback = BitIsSet (opcode, 21);
3766 
3767                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3768                 if ((n == 15) || (BitCount (registers) < 1))
3769                     return false;
3770 
3771                 break;
3772             default:
3773                 return false;
3774         }
3775         // address = R[n] + 4;
3776 
3777         int32_t offset = 0;
3778         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3779 
3780         if (!success)
3781             return false;
3782 
3783         addr_t address = Rn + addr_byte_size;
3784 
3785         EmulateInstruction::Context context;
3786         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3787         RegisterInfo dwarf_reg;
3788         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3789         context.SetRegisterPlusOffset (dwarf_reg, offset);
3790 
3791         for (int i = 0; i < 14; ++i)
3792         {
3793             if (BitIsSet (registers, i))
3794             {
3795                 // R[i] = MemA[address,4]; address = address + 4;
3796 
3797                 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size);
3798                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3799                 if (!success)
3800                     return false;
3801 
3802                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3803                     return false;
3804 
3805                 offset += addr_byte_size;
3806             }
3807         }
3808 
3809         // if registers<15> == '1' then
3810         //     LoadWritePC(MemA[address,4]);
3811         if (BitIsSet (registers, 15))
3812         {
3813             context.SetRegisterPlusOffset (dwarf_reg, offset);
3814             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3815             if (!success)
3816                 return false;
3817             // In ARMv5T and above, this is an interworking branch.
3818             if (!LoadWritePC(context, data))
3819                 return false;
3820         }
3821 
3822         // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3823         if (wback && BitIsClear (registers, n))
3824         {
3825             if (!success)
3826                 return false;
3827 
3828             offset = addr_byte_size * BitCount (registers);
3829             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3830             context.SetImmediateSigned (offset);
3831             addr_t addr = Rn + offset;
3832             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3833                 return false;
3834         }
3835 
3836         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3837         if (wback && BitIsSet (registers, n))
3838             return WriteBits32Unknown (n);
3839     }
3840     return true;
3841 }
3842 
3843 // Load Register (immediate) calculates an address from a base register value and
3844 // an immediate offset, loads a word from memory, and writes to a register.
3845 // LDR (immediate, Thumb)
3846 bool
3847 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding)
3848 {
3849 #if 0
3850     // ARM pseudo code...
3851     if (ConditionPassed())
3852     {
3853         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3854         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3855         address = if index then offset_addr else R[n];
3856         data = MemU[address,4];
3857         if wback then R[n] = offset_addr;
3858         if t == 15 then
3859             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3860         elsif UnalignedSupport() || address<1:0> = '00' then
3861             R[t] = data;
3862         else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3863     }
3864 #endif
3865 
3866     bool success = false;
3867 
3868     if (ConditionPassed(opcode))
3869     {
3870         uint32_t Rt; // the destination register
3871         uint32_t Rn; // the base register
3872         uint32_t imm32; // the immediate offset used to form the address
3873         addr_t offset_addr; // the offset address
3874         addr_t address; // the calculated address
3875         uint32_t data; // the literal data value from memory load
3876         bool add, index, wback;
3877         switch (encoding) {
3878             case eEncodingT1:
3879                 Rt = Bits32(opcode, 2, 0);
3880                 Rn = Bits32(opcode, 5, 3);
3881                 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3882                 // index = TRUE; add = TRUE; wback = FALSE
3883                 add = true;
3884                 index = true;
3885                 wback = false;
3886 
3887                 break;
3888 
3889             case eEncodingT2:
3890                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
3891                 Rt = Bits32 (opcode, 10, 8);
3892                 Rn = 13;
3893                 imm32 = Bits32 (opcode, 7, 0) << 2;
3894 
3895                 // index = TRUE; add = TRUE; wback = FALSE;
3896                 index = true;
3897                 add = true;
3898                 wback = false;
3899 
3900                 break;
3901 
3902             case eEncodingT3:
3903                 // if Rn == '1111' then SEE LDR (literal);
3904                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
3905                 Rt = Bits32 (opcode, 15, 12);
3906                 Rn = Bits32 (opcode, 19, 16);
3907                 imm32 = Bits32 (opcode, 11, 0);
3908 
3909                 // index = TRUE; add = TRUE; wback = FALSE;
3910                 index = true;
3911                 add = true;
3912                 wback = false;
3913 
3914                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3915                 if ((Rt == 15) && InITBlock() && !LastInITBlock())
3916                     return false;
3917 
3918                 break;
3919 
3920             case eEncodingT4:
3921                 // if Rn == '1111' then SEE LDR (literal);
3922                 // if P == '1' && U == '1' && W == '0' then SEE LDRT;
3923                 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
3924                 // if P == '0' && W == '0' then UNDEFINED;
3925                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
3926                     return false;
3927 
3928                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
3929                 Rt = Bits32 (opcode, 15, 12);
3930                 Rn = Bits32 (opcode, 19, 16);
3931                 imm32 = Bits32 (opcode, 7, 0);
3932 
3933                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
3934                 index = BitIsSet (opcode, 10);
3935                 add = BitIsSet (opcode, 9);
3936                 wback = BitIsSet (opcode, 8);
3937 
3938                 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
3939                 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock()))
3940                     return false;
3941 
3942                 break;
3943 
3944             default:
3945                 return false;
3946         }
3947         uint32_t base = ReadCoreReg (Rn, &success);
3948         if (!success)
3949             return false;
3950         if (add)
3951             offset_addr = base + imm32;
3952         else
3953             offset_addr = base - imm32;
3954 
3955         address = (index ? offset_addr : base);
3956 
3957         RegisterInfo base_reg;
3958         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
3959         if (wback)
3960         {
3961             EmulateInstruction::Context ctx;
3962             ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
3963             ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3964 
3965             if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
3966                 return false;
3967         }
3968 
3969         // Prepare to write to the Rt register.
3970         EmulateInstruction::Context context;
3971         context.type = EmulateInstruction::eContextRegisterLoad;
3972         context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3973 
3974         // Read memory from the address.
3975         data = MemURead(context, address, 4, 0, &success);
3976         if (!success)
3977             return false;
3978 
3979         if (Rt == 15)
3980         {
3981             if (Bits32(address, 1, 0) == 0)
3982             {
3983                 if (!LoadWritePC(context, data))
3984                     return false;
3985             }
3986             else
3987                 return false;
3988         }
3989         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
3990         {
3991             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
3992                 return false;
3993         }
3994         else
3995             WriteBits32Unknown (Rt);
3996     }
3997     return true;
3998 }
3999 
4000 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
4001 // from a base register.  The consecutive memory locations start at this address, and teh address just above the last
4002 // of those locations can optionally be written back to the base register.
4003 bool
4004 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding)
4005 {
4006 #if 0
4007     if ConditionPassed() then
4008         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4009         address = R[n];
4010 
4011         for i = 0 to 14
4012             if registers<i> == '1' then
4013                 if i == n && wback && i != LowestSetBit(registers) then
4014                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4015                 else
4016                     MemA[address,4] = R[i];
4017                 address = address + 4;
4018 
4019         if registers<15> == '1' then // Only possible for encoding A1
4020             MemA[address,4] = PCStoreValue();
4021         if wback then R[n] = R[n] + 4*BitCount(registers);
4022 #endif
4023 
4024     bool success = false;
4025 
4026     if (ConditionPassed(opcode))
4027     {
4028         uint32_t n;
4029         uint32_t registers = 0;
4030         bool wback;
4031         const uint32_t addr_byte_size = GetAddressByteSize();
4032 
4033         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4034         switch (encoding)
4035         {
4036             case eEncodingT1:
4037                 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4038                 n = Bits32 (opcode, 10, 8);
4039                 registers = Bits32 (opcode, 7, 0);
4040                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
4041                 wback = true;
4042 
4043                 // if BitCount(registers) < 1 then UNPREDICTABLE;
4044                 if (BitCount (registers) < 1)
4045                     return false;
4046 
4047                 break;
4048 
4049             case eEncodingT2:
4050                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4051                 n = Bits32 (opcode, 19, 16);
4052                 registers = Bits32 (opcode, 15, 0);
4053                 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4054                 wback = BitIsSet (opcode, 21);
4055 
4056                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4057                 if ((n == 15) || (BitCount (registers) < 2))
4058                     return false;
4059 
4060                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4061                 if (wback && BitIsSet (registers, n))
4062                     return false;
4063 
4064                 break;
4065 
4066             case eEncodingA1:
4067                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4068                 n = Bits32 (opcode, 19, 16);
4069                 registers = Bits32 (opcode, 15, 0);
4070                 wback = BitIsSet (opcode, 21);
4071 
4072                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4073                 if ((n == 15) || (BitCount (registers) < 1))
4074                     return false;
4075 
4076                 break;
4077 
4078             default:
4079                 return false;
4080         }
4081 
4082         // address = R[n];
4083         int32_t offset = 0;
4084         const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4085         if (!success)
4086             return false;
4087 
4088         EmulateInstruction::Context context;
4089         context.type = EmulateInstruction::eContextRegisterStore;
4090         RegisterInfo base_reg;
4091         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4092 
4093         // for i = 0 to 14
4094         int lowest_set_bit = 14;
4095         for (int i = 0; i < 14; ++i)
4096         {
4097             // if registers<i> == '1' then
4098             if (BitIsSet (registers, i))
4099             {
4100                   if (i < lowest_set_bit)
4101                       lowest_set_bit = i;
4102                   // if i == n && wback && i != LowestSetBit(registers) then
4103                   if ((i == n) && wback && (i != lowest_set_bit))
4104                       // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4105                       WriteBits32UnknownToMemory (address + offset);
4106                   else
4107                   {
4108                      // MemA[address,4] = R[i];
4109                       uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4110                       if (!success)
4111                           return false;
4112 
4113                       RegisterInfo data_reg;
4114                       GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4115                       context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4116                       if (!MemAWrite (context, address + offset, data, addr_byte_size))
4117                           return false;
4118                   }
4119 
4120                   // address = address + 4;
4121                   offset += addr_byte_size;
4122             }
4123         }
4124 
4125         // if registers<15> == '1' then // Only possible for encoding A1
4126         //     MemA[address,4] = PCStoreValue();
4127         if (BitIsSet (registers, 15))
4128         {
4129             RegisterInfo pc_reg;
4130             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4131             context.SetRegisterPlusOffset (pc_reg, 8);
4132             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4133             if (!success)
4134                 return false;
4135 
4136             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4137                 return false;
4138         }
4139 
4140         // if wback then R[n] = R[n] + 4*BitCount(registers);
4141         if (wback)
4142         {
4143             offset = addr_byte_size * BitCount (registers);
4144             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4145             context.SetImmediateSigned (offset);
4146             addr_t data = address + offset;
4147             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4148                 return false;
4149         }
4150     }
4151     return true;
4152 }
4153 
4154 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
4155 // from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
4156 // of those locations can optionally be written back to the base register.
4157 bool
4158 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding)
4159 {
4160 #if 0
4161     if ConditionPassed() then
4162         EncodingSpecificOperations();
4163         address = R[n] - 4*BitCount(registers) + 4;
4164 
4165         for i = 0 to 14
4166             if registers<i> == '1' then
4167                 if i == n && wback && i != LowestSetBit(registers) then
4168                     MemA[address,4] = bits(32) UNKNOWN;
4169                 else
4170                     MemA[address,4] = R[i];
4171                 address = address + 4;
4172 
4173         if registers<15> == '1' then
4174             MemA[address,4] = PCStoreValue();
4175 
4176         if wback then R[n] = R[n] - 4*BitCount(registers);
4177 #endif
4178 
4179     bool success = false;
4180 
4181     if (ConditionPassed(opcode))
4182     {
4183         uint32_t n;
4184         uint32_t registers = 0;
4185         bool wback;
4186         const uint32_t addr_byte_size = GetAddressByteSize();
4187 
4188         // EncodingSpecificOperations();
4189         switch (encoding)
4190         {
4191             case eEncodingA1:
4192                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4193                 n = Bits32 (opcode, 19, 16);
4194                 registers = Bits32 (opcode, 15, 0);
4195                 wback = BitIsSet (opcode, 21);
4196 
4197                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4198                 if ((n == 15) || (BitCount (registers) < 1))
4199                     return false;
4200                 break;
4201             default:
4202                 return false;
4203         }
4204 
4205         // address = R[n] - 4*BitCount(registers) + 4;
4206         int32_t offset = 0;
4207         addr_t Rn = ReadCoreReg (n, &success);
4208         if (!success)
4209             return false;
4210 
4211         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4;
4212 
4213         EmulateInstruction::Context context;
4214         context.type = EmulateInstruction::eContextRegisterStore;
4215         RegisterInfo base_reg;
4216         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4217 
4218         // for i = 0 to 14
4219         int lowest_bit_set = 14;
4220         for (int i = 0; i < 14; ++i)
4221         {
4222             // if registers<i> == '1' then
4223             if (BitIsSet (registers, i))
4224             {
4225                 if (i < lowest_bit_set)
4226                     lowest_bit_set = i;
4227                 //if i == n && wback && i != LowestSetBit(registers) then
4228                 if ((i == n) && wback && (i != lowest_bit_set))
4229                     // MemA[address,4] = bits(32) UNKNOWN;
4230                     WriteBits32UnknownToMemory (address + offset);
4231                 else
4232                 {
4233                     // MemA[address,4] = R[i];
4234                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4235                     if (!success)
4236                         return false;
4237 
4238                     RegisterInfo data_reg;
4239                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4240                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4241                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4242                         return false;
4243                 }
4244 
4245                 // address = address + 4;
4246                 offset += addr_byte_size;
4247             }
4248         }
4249 
4250         // if registers<15> == '1' then
4251         //    MemA[address,4] = PCStoreValue();
4252         if (BitIsSet (registers, 15))
4253         {
4254             RegisterInfo pc_reg;
4255             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4256             context.SetRegisterPlusOffset (pc_reg, 8);
4257             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4258             if (!success)
4259                 return false;
4260 
4261             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4262                 return false;
4263         }
4264 
4265         // if wback then R[n] = R[n] - 4*BitCount(registers);
4266         if (wback)
4267         {
4268             offset = (addr_byte_size * BitCount (registers)) * -1;
4269             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4270             context.SetImmediateSigned (offset);
4271             addr_t data = Rn + offset;
4272             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4273                 return false;
4274         }
4275     }
4276     return true;
4277 }
4278 
4279 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
4280 // from a base register.  The consecutive memory locations end just below this address, and the address of the first of
4281 // those locations can optionally be written back to the base register.
4282 bool
4283 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding)
4284 {
4285 #if 0
4286     if ConditionPassed() then
4287         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4288         address = R[n] - 4*BitCount(registers);
4289 
4290         for i = 0 to 14
4291             if registers<i> == '1' then
4292                 if i == n && wback && i != LowestSetBit(registers) then
4293                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4294                 else
4295                     MemA[address,4] = R[i];
4296                 address = address + 4;
4297 
4298         if registers<15> == '1' then // Only possible for encoding A1
4299             MemA[address,4] = PCStoreValue();
4300 
4301         if wback then R[n] = R[n] - 4*BitCount(registers);
4302 #endif
4303 
4304 
4305     bool success = false;
4306 
4307     if (ConditionPassed(opcode))
4308     {
4309         uint32_t n;
4310         uint32_t registers = 0;
4311         bool wback;
4312         const uint32_t addr_byte_size = GetAddressByteSize();
4313 
4314         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4315         switch (encoding)
4316         {
4317             case eEncodingT1:
4318                 // if W == '1' && Rn == '1101' then SEE PUSH;
4319                 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
4320                 {
4321                     // See PUSH
4322                 }
4323                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4324                 n = Bits32 (opcode, 19, 16);
4325                 registers = Bits32 (opcode, 15, 0);
4326                 registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
4327                 wback = BitIsSet (opcode, 21);
4328                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4329                 if ((n == 15) || BitCount (registers) < 2)
4330                     return false;
4331                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4332                 if (wback && BitIsSet (registers, n))
4333                     return false;
4334                 break;
4335 
4336             case eEncodingA1:
4337                 // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH;
4338                 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
4339                 {
4340                     // See Push
4341                 }
4342                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4343                 n = Bits32 (opcode, 19, 16);
4344                 registers = Bits32 (opcode, 15, 0);
4345                 wback = BitIsSet (opcode, 21);
4346                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4347                 if ((n == 15) || BitCount (registers) < 1)
4348                     return false;
4349                 break;
4350 
4351             default:
4352                 return false;
4353         }
4354 
4355         // address = R[n] - 4*BitCount(registers);
4356 
4357         int32_t offset = 0;
4358         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4359         if (!success)
4360         return false;
4361 
4362         addr_t address = Rn - (addr_byte_size * BitCount (registers));
4363 
4364         EmulateInstruction::Context context;
4365         context.type = EmulateInstruction::eContextRegisterStore;
4366         RegisterInfo base_reg;
4367         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4368 
4369         // for i = 0 to 14
4370         uint32_t lowest_set_bit = 14;
4371         for (int i = 0; i < 14; ++i)
4372         {
4373             // if registers<i> == '1' then
4374             if (BitIsSet (registers, i))
4375             {
4376                 if (i < lowest_set_bit)
4377                     lowest_set_bit = i;
4378                 // if i == n && wback && i != LowestSetBit(registers) then
4379                 if ((i == n) && wback && (i != lowest_set_bit))
4380                     // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4381                     WriteBits32UnknownToMemory (address + offset);
4382                 else
4383                 {
4384                     // MemA[address,4] = R[i];
4385                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4386                     if (!success)
4387                         return false;
4388 
4389                     RegisterInfo data_reg;
4390                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4391                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4392                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4393                         return false;
4394                 }
4395 
4396                 // address = address + 4;
4397                 offset += addr_byte_size;
4398             }
4399         }
4400 
4401         // if registers<15> == '1' then // Only possible for encoding A1
4402         //     MemA[address,4] = PCStoreValue();
4403         if (BitIsSet (registers, 15))
4404         {
4405             RegisterInfo pc_reg;
4406             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4407             context.SetRegisterPlusOffset (pc_reg, 8);
4408             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4409             if (!success)
4410                 return false;
4411 
4412             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4413                 return false;
4414         }
4415 
4416         // if wback then R[n] = R[n] - 4*BitCount(registers);
4417         if (wback)
4418         {
4419             offset = (addr_byte_size * BitCount (registers)) * -1;
4420             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4421             context.SetImmediateSigned (offset);
4422             addr_t data = Rn + offset;
4423             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4424                 return false;
4425         }
4426     }
4427     return true;
4428 }
4429 
4430 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
4431 // from a base register.  The consecutive memory locations start just above this address, and the address of the last
4432 // of those locations can optionally be written back to the base register.
4433 bool
4434 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding)
4435 {
4436 #if 0
4437     if ConditionPassed() then
4438         EncodingSpecificOperations();
4439         address = R[n] + 4;
4440 
4441         for i = 0 to 14
4442             if registers<i> == '1' then
4443                 if i == n && wback && i != LowestSetBit(registers) then
4444                     MemA[address,4] = bits(32) UNKNOWN;
4445                 else
4446                     MemA[address,4] = R[i];
4447                 address = address + 4;
4448 
4449         if registers<15> == '1' then
4450             MemA[address,4] = PCStoreValue();
4451 
4452         if wback then R[n] = R[n] + 4*BitCount(registers);
4453 #endif
4454 
4455     bool success = false;
4456 
4457     if (ConditionPassed(opcode))
4458     {
4459         uint32_t n;
4460         uint32_t registers = 0;
4461         bool wback;
4462         const uint32_t addr_byte_size = GetAddressByteSize();
4463 
4464         // EncodingSpecificOperations();
4465         switch (encoding)
4466         {
4467             case eEncodingA1:
4468                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4469                 n = Bits32 (opcode, 19, 16);
4470                 registers = Bits32 (opcode, 15, 0);
4471                 wback = BitIsSet (opcode, 21);
4472 
4473                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4474                 if ((n == 15) && (BitCount (registers) < 1))
4475                     return false;
4476                 break;
4477             default:
4478                 return false;
4479         }
4480         // address = R[n] + 4;
4481 
4482         int32_t offset = 0;
4483         addr_t Rn = ReadCoreReg (n, &success);
4484         if (!success)
4485             return false;
4486 
4487         addr_t address = Rn + addr_byte_size;
4488 
4489         EmulateInstruction::Context context;
4490         context.type = EmulateInstruction::eContextRegisterStore;
4491         RegisterInfo base_reg;
4492         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4493 
4494         uint32_t lowest_set_bit = 14;
4495         // for i = 0 to 14
4496         for (int i = 0; i < 14; ++i)
4497         {
4498             // if registers<i> == '1' then
4499             if (BitIsSet (registers, i))
4500             {
4501                 if (i < lowest_set_bit)
4502                     lowest_set_bit = i;
4503                 // if i == n && wback && i != LowestSetBit(registers) then
4504                 if ((i == n) && wback && (i != lowest_set_bit))
4505                     // MemA[address,4] = bits(32) UNKNOWN;
4506                     WriteBits32UnknownToMemory (address + offset);
4507                 // else
4508                 else
4509                 {
4510                     // MemA[address,4] = R[i];
4511                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4512                     if (!success)
4513                         return false;
4514 
4515                     RegisterInfo data_reg;
4516                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4517                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size);
4518                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4519                         return false;
4520                 }
4521 
4522                 // address = address + 4;
4523                 offset += addr_byte_size;
4524             }
4525         }
4526 
4527         // if registers<15> == '1' then
4528             // MemA[address,4] = PCStoreValue();
4529         if (BitIsSet (registers, 15))
4530         {
4531             RegisterInfo pc_reg;
4532             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4533             context.SetRegisterPlusOffset (pc_reg, 8);
4534             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4535             if (!success)
4536             return false;
4537 
4538             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4539                 return false;
4540         }
4541 
4542         // if wback then R[n] = R[n] + 4*BitCount(registers);
4543         if (wback)
4544         {
4545             offset = addr_byte_size * BitCount (registers);
4546             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4547             context.SetImmediateSigned (offset);
4548             addr_t data = Rn + offset;
4549             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4550                 return false;
4551         }
4552     }
4553     return true;
4554 }
4555 
4556 // STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word
4557 // from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
4558 bool
4559 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding)
4560 {
4561 #if 0
4562     if ConditionPassed() then
4563         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4564         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4565         address = if index then offset_addr else R[n];
4566         if UnalignedSupport() || address<1:0> == '00' then
4567             MemU[address,4] = R[t];
4568         else // Can only occur before ARMv7
4569             MemU[address,4] = bits(32) UNKNOWN;
4570         if wback then R[n] = offset_addr;
4571 #endif
4572 
4573     bool success = false;
4574 
4575     if (ConditionPassed(opcode))
4576     {
4577         const uint32_t addr_byte_size = GetAddressByteSize();
4578 
4579         uint32_t t;
4580         uint32_t n;
4581         uint32_t imm32;
4582         bool index;
4583         bool add;
4584         bool wback;
4585         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4586         switch (encoding)
4587         {
4588             case eEncodingT1:
4589                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
4590                 t = Bits32 (opcode, 2, 0);
4591                 n = Bits32 (opcode, 5, 3);
4592                 imm32 = Bits32 (opcode, 10, 6) << 2;
4593 
4594                 // index = TRUE; add = TRUE; wback = FALSE;
4595                 index = true;
4596                 add = false;
4597                 wback = false;
4598                 break;
4599 
4600             case eEncodingT2:
4601                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4602                 t = Bits32 (opcode, 10, 8);
4603                 n = 13;
4604                 imm32 = Bits32 (opcode, 7, 0) << 2;
4605 
4606                 // index = TRUE; add = TRUE; wback = FALSE;
4607                 index = true;
4608                 add = true;
4609                 wback = false;
4610                 break;
4611 
4612             case eEncodingT3:
4613                 // if Rn == '1111' then UNDEFINED;
4614                 if (Bits32 (opcode, 19, 16) == 15)
4615                     return false;
4616 
4617                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4618                 t = Bits32 (opcode, 15, 12);
4619                 n = Bits32 (opcode, 19, 16);
4620                 imm32 = Bits32 (opcode, 11, 0);
4621 
4622                 // index = TRUE; add = TRUE; wback = FALSE;
4623                 index = true;
4624                 add = true;
4625                 wback = false;
4626 
4627                 // if t == 15 then UNPREDICTABLE;
4628                 if (t == 15)
4629                     return false;
4630                 break;
4631 
4632             case eEncodingT4:
4633                 // if P == '1' && U == '1' && W == '0' then SEE STRT;
4634                 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH;
4635                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4636                 if ((Bits32 (opcode, 19, 16) == 15)
4637                       || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
4638                     return false;
4639 
4640                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4641                 t = Bits32 (opcode, 15, 12);
4642                 n = Bits32 (opcode, 19, 16);
4643                 imm32 = Bits32 (opcode, 7, 0);
4644 
4645                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4646                 index = BitIsSet (opcode, 10);
4647                 add = BitIsSet (opcode, 9);
4648                 wback = BitIsSet (opcode, 8);
4649 
4650                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
4651                 if ((t == 15) || (wback && (n == t)))
4652                     return false;
4653                 break;
4654 
4655             default:
4656                 return false;
4657         }
4658 
4659         addr_t offset_addr;
4660         addr_t address;
4661 
4662         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4663         uint32_t base_address = ReadCoreReg (n, &success);
4664         if (!success)
4665             return false;
4666 
4667         if (add)
4668             offset_addr = base_address + imm32;
4669         else
4670             offset_addr = base_address - imm32;
4671 
4672         // address = if index then offset_addr else R[n];
4673         if (index)
4674             address = offset_addr;
4675         else
4676             address = base_address;
4677 
4678         EmulateInstruction::Context context;
4679         context.type = eContextRegisterStore;
4680         RegisterInfo base_reg;
4681         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4682 
4683         // if UnalignedSupport() || address<1:0> == '00' then
4684         if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
4685         {
4686             // MemU[address,4] = R[t];
4687             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4688             if (!success)
4689                 return false;
4690 
4691             RegisterInfo data_reg;
4692             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4693             int32_t offset = address - base_address;
4694             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4695             if (!MemUWrite (context, address, data, addr_byte_size))
4696                 return false;
4697         }
4698         else
4699         {
4700             // MemU[address,4] = bits(32) UNKNOWN;
4701             WriteBits32UnknownToMemory (address);
4702         }
4703 
4704         // if wback then R[n] = offset_addr;
4705         if (wback)
4706         {
4707             context.type = eContextRegisterLoad;
4708             context.SetAddress (offset_addr);
4709             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4710                 return false;
4711         }
4712     }
4713     return true;
4714 }
4715 
4716 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a
4717 // word from a register to memory.   The offset register value can optionally be shifted.
4718 bool
4719 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding)
4720 {
4721 #if 0
4722     if ConditionPassed() then
4723         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4724         offset = Shift(R[m], shift_t, shift_n, APSR.C);
4725         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4726         address = if index then offset_addr else R[n];
4727         if t == 15 then // Only possible for encoding A1
4728             data = PCStoreValue();
4729         else
4730             data = R[t];
4731         if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4732             MemU[address,4] = data;
4733         else // Can only occur before ARMv7
4734             MemU[address,4] = bits(32) UNKNOWN;
4735         if wback then R[n] = offset_addr;
4736 #endif
4737 
4738     bool success = false;
4739 
4740     if (ConditionPassed(opcode))
4741     {
4742         const uint32_t addr_byte_size = GetAddressByteSize();
4743 
4744         uint32_t t;
4745         uint32_t n;
4746         uint32_t m;
4747         ARM_ShifterType shift_t;
4748         uint32_t shift_n;
4749         bool index;
4750         bool add;
4751         bool wback;
4752 
4753         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4754         switch (encoding)
4755         {
4756             case eEncodingT1:
4757                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4758                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4759                 t = Bits32 (opcode, 2, 0);
4760                 n = Bits32 (opcode, 5, 3);
4761                 m = Bits32 (opcode, 8, 6);
4762 
4763                 // index = TRUE; add = TRUE; wback = FALSE;
4764                 index = true;
4765                 add = true;
4766                 wback = false;
4767 
4768                 // (shift_t, shift_n) = (SRType_LSL, 0);
4769                 shift_t = SRType_LSL;
4770                 shift_n = 0;
4771                 break;
4772 
4773             case eEncodingT2:
4774                 // if Rn == '1111' then UNDEFINED;
4775                 if (Bits32 (opcode, 19, 16) == 15)
4776                     return false;
4777 
4778                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4779                 t = Bits32 (opcode, 15, 12);
4780                 n = Bits32 (opcode, 19, 16);
4781                 m = Bits32 (opcode, 3, 0);
4782 
4783                 // index = TRUE; add = TRUE; wback = FALSE;
4784                 index = true;
4785                 add = true;
4786                 wback = false;
4787 
4788                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4789                 shift_t = SRType_LSL;
4790                 shift_n = Bits32 (opcode, 5, 4);
4791 
4792                 // if t == 15 || BadReg(m) then UNPREDICTABLE;
4793                 if ((t == 15) || (BadReg (m)))
4794                     return false;
4795                 break;
4796 
4797             case eEncodingA1:
4798             {
4799                 // if P == '0' && W == '1' then SEE STRT;
4800                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4801                 t = Bits32 (opcode, 15, 12);
4802                 n = Bits32 (opcode, 19, 16);
4803                 m = Bits32 (opcode, 3, 0);
4804 
4805                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
4806                 index = BitIsSet (opcode, 24);
4807                 add = BitIsSet (opcode, 23);
4808                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
4809 
4810                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
4811                 uint32_t typ = Bits32 (opcode, 6, 5);
4812                 uint32_t imm5 = Bits32 (opcode, 11, 7);
4813                 shift_n = DecodeImmShift(typ, imm5, shift_t);
4814 
4815                 // if m == 15 then UNPREDICTABLE;
4816                 if (m == 15)
4817                     return false;
4818 
4819                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
4820                 if (wback && ((n == 15) || (n == t)))
4821                     return false;
4822 
4823                 break;
4824             }
4825             default:
4826                 return false;
4827         }
4828 
4829         addr_t offset_addr;
4830         addr_t address;
4831         int32_t offset = 0;
4832 
4833         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4834         if (!success)
4835             return false;
4836 
4837         uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
4838         if (!success)
4839             return false;
4840 
4841         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4842         offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success);
4843         if (!success)
4844             return false;
4845 
4846         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4847         if (add)
4848             offset_addr = base_address + offset;
4849         else
4850             offset_addr = base_address - offset;
4851 
4852         // address = if index then offset_addr else R[n];
4853         if (index)
4854             address = offset_addr;
4855         else
4856             address = base_address;
4857 
4858         uint32_t data;
4859         // if t == 15 then // Only possible for encoding A1
4860         if (t == 15)
4861             // data = PCStoreValue();
4862             data = ReadCoreReg (PC_REG, &success);
4863         else
4864             // data = R[t];
4865             data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4866 
4867         if (!success)
4868             return false;
4869 
4870         EmulateInstruction::Context context;
4871         context.type = eContextRegisterStore;
4872 
4873         // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4874         if (UnalignedSupport ()
4875             || (BitIsClear (address, 1) && BitIsClear (address, 0))
4876             || CurrentInstrSet() == eModeARM)
4877         {
4878             // MemU[address,4] = data;
4879 
4880             RegisterInfo base_reg;
4881             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 +  n, base_reg);
4882 
4883             RegisterInfo data_reg;
4884             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4885 
4886             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4887             if (!MemUWrite (context, address, data, addr_byte_size))
4888                 return false;
4889 
4890         }
4891         else
4892             // MemU[address,4] = bits(32) UNKNOWN;
4893             WriteBits32UnknownToMemory (address);
4894 
4895         // if wback then R[n] = offset_addr;
4896         if (wback)
4897         {
4898             context.type = eContextRegisterLoad;
4899             context.SetAddress (offset_addr);
4900             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4901                 return false;
4902         }
4903 
4904     }
4905     return true;
4906 }
4907 
4908 bool
4909 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding)
4910 {
4911 #if 0
4912     if ConditionPassed() then
4913         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4914         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4915         address = if index then offset_addr else R[n];
4916         MemU[address,1] = R[t]<7:0>;
4917         if wback then R[n] = offset_addr;
4918 #endif
4919 
4920 
4921     bool success = false;
4922 
4923     if (ConditionPassed(opcode))
4924     {
4925         uint32_t t;
4926         uint32_t n;
4927         uint32_t imm32;
4928         bool index;
4929         bool add;
4930         bool wback;
4931         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4932         switch (encoding)
4933         {
4934             case eEncodingT1:
4935                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
4936                 t = Bits32 (opcode, 2, 0);
4937                 n = Bits32 (opcode, 5, 3);
4938                 imm32 = Bits32 (opcode, 10, 6);
4939 
4940                 // index = TRUE; add = TRUE; wback = FALSE;
4941                 index = true;
4942                 add = true;
4943                 wback = false;
4944                 break;
4945 
4946             case eEncodingT2:
4947                 // if Rn == '1111' then UNDEFINED;
4948                 if (Bits32 (opcode, 19, 16) == 15)
4949                     return false;
4950 
4951                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4952                 t = Bits32 (opcode, 15, 12);
4953                 n = Bits32 (opcode, 19, 16);
4954                 imm32 = Bits32 (opcode, 11, 0);
4955 
4956                 // index = TRUE; add = TRUE; wback = FALSE;
4957                 index = true;
4958                 add = true;
4959                 wback = false;
4960 
4961                 // if BadReg(t) then UNPREDICTABLE;
4962                 if (BadReg (t))
4963                     return false;
4964                 break;
4965 
4966             case eEncodingT3:
4967                 // if P == '1' && U == '1' && W == '0' then SEE STRBT;
4968                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4969                 if (Bits32 (opcode, 19, 16) == 15)
4970                     return false;
4971 
4972                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4973                 t = Bits32 (opcode, 15, 12);
4974                 n = Bits32 (opcode, 19, 16);
4975                 imm32 = Bits32 (opcode, 7, 0);
4976 
4977                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4978                 index = BitIsSet (opcode, 10);
4979                 add = BitIsSet (opcode, 9);
4980                 wback = BitIsSet (opcode, 8);
4981 
4982                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
4983                 if ((BadReg (t)) || (wback && (n == t)))
4984                     return false;
4985                 break;
4986 
4987             default:
4988                 return false;
4989         }
4990 
4991         addr_t offset_addr;
4992         addr_t address;
4993         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4994         if (!success)
4995             return false;
4996 
4997         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4998         if (add)
4999             offset_addr = base_address + imm32;
5000         else
5001             offset_addr = base_address - imm32;
5002 
5003         // address = if index then offset_addr else R[n];
5004         if (index)
5005             address = offset_addr;
5006         else
5007             address = base_address;
5008 
5009         // MemU[address,1] = R[t]<7:0>
5010         RegisterInfo base_reg;
5011         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5012 
5013         RegisterInfo data_reg;
5014         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5015 
5016         EmulateInstruction::Context context;
5017         context.type = eContextRegisterStore;
5018         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
5019 
5020         uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5021         if (!success)
5022             return false;
5023 
5024         data = Bits32 (data, 7, 0);
5025 
5026         if (!MemUWrite (context, address, data, 1))
5027             return false;
5028 
5029         // if wback then R[n] = offset_addr;
5030         if (wback)
5031         {
5032             context.type = eContextRegisterLoad;
5033             context.SetAddress (offset_addr);
5034             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5035                 return false;
5036         }
5037 
5038     }
5039 
5040     return true;
5041 }
5042 
5043 // STRH (register) calculates an address from a base register value and an offset register value, and stores a
5044 // halfword from a register to memory.  The offset register alue can be shifted left by 0, 1, 2, or 3 bits.
5045 bool
5046 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding)
5047 {
5048 #if 0
5049     if ConditionPassed() then
5050         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5051         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5052         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5053         address = if index then offset_addr else R[n];
5054         if UnalignedSupport() || address<0> == '0' then
5055             MemU[address,2] = R[t]<15:0>;
5056         else // Can only occur before ARMv7
5057             MemU[address,2] = bits(16) UNKNOWN;
5058         if wback then R[n] = offset_addr;
5059 #endif
5060 
5061     bool success = false;
5062 
5063     if (ConditionPassed(opcode))
5064     {
5065         uint32_t t;
5066         uint32_t n;
5067         uint32_t m;
5068         bool index;
5069         bool add;
5070         bool wback;
5071         ARM_ShifterType shift_t;
5072         uint32_t shift_n;
5073 
5074         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5075         switch (encoding)
5076         {
5077             case eEncodingT1:
5078                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5079                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5080                 t = Bits32 (opcode, 2, 0);
5081                 n = Bits32 (opcode, 5, 3);
5082                 m = Bits32 (opcode, 8, 6);
5083 
5084                 // index = TRUE; add = TRUE; wback = FALSE;
5085                 index = true;
5086                 add = true;
5087                 wback = false;
5088 
5089                 // (shift_t, shift_n) = (SRType_LSL, 0);
5090                 shift_t = SRType_LSL;
5091                 shift_n = 0;
5092 
5093                 break;
5094 
5095             case eEncodingT2:
5096                 // if Rn == '1111' then UNDEFINED;
5097                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5098                 t = Bits32 (opcode, 15, 12);
5099                 n = Bits32 (opcode, 19, 16);
5100                 m = Bits32 (opcode, 3, 0);
5101                 if (n == 15)
5102                     return false;
5103 
5104                 // index = TRUE; add = TRUE; wback = FALSE;
5105                 index = true;
5106                 add = true;
5107                 wback = false;
5108 
5109                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5110                 shift_t = SRType_LSL;
5111                 shift_n = Bits32 (opcode, 5, 4);
5112 
5113                 // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5114                 if (BadReg (t) || BadReg (m))
5115                     return false;
5116 
5117                 break;
5118 
5119             case eEncodingA1:
5120                 // if P == '0' && W == '1' then SEE STRHT;
5121                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5122                 t = Bits32 (opcode, 15, 12);
5123                 n = Bits32 (opcode, 19, 16);
5124                 m = Bits32 (opcode, 3, 0);
5125 
5126                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5127                 index = BitIsSet (opcode, 24);
5128                 add = BitIsSet (opcode, 23);
5129                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5130 
5131                 // (shift_t, shift_n) = (SRType_LSL, 0);
5132                 shift_t = SRType_LSL;
5133                 shift_n = 0;
5134 
5135                 // if t == 15 || m == 15 then UNPREDICTABLE;
5136                 if ((t == 15) || (m == 15))
5137                     return false;
5138 
5139                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5140                 if (wback && ((n == 15) || (n == t)))
5141                     return false;
5142 
5143                 break;
5144 
5145             default:
5146                 return false;
5147         }
5148 
5149         uint32_t Rm = ReadCoreReg (m, &success);
5150         if (!success)
5151             return false;
5152 
5153         uint32_t Rn = ReadCoreReg (n, &success);
5154         if (!success)
5155             return false;
5156 
5157         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5158         uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
5159         if (!success)
5160             return false;
5161 
5162         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5163         addr_t offset_addr;
5164         if (add)
5165             offset_addr = Rn + offset;
5166         else
5167             offset_addr = Rn - offset;
5168 
5169         // address = if index then offset_addr else R[n];
5170         addr_t address;
5171         if (index)
5172             address = offset_addr;
5173         else
5174             address = Rn;
5175 
5176         EmulateInstruction::Context context;
5177         context.type = eContextRegisterStore;
5178         RegisterInfo base_reg;
5179         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5180         RegisterInfo offset_reg;
5181         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5182 
5183         // if UnalignedSupport() || address<0> == '0' then
5184         if (UnalignedSupport() || BitIsClear (address, 0))
5185         {
5186             // MemU[address,2] = R[t]<15:0>;
5187             uint32_t Rt = ReadCoreReg (t, &success);
5188             if (!success)
5189                 return false;
5190 
5191             EmulateInstruction::Context context;
5192             context.type = eContextRegisterStore;
5193             RegisterInfo base_reg;
5194             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5195             RegisterInfo offset_reg;
5196             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5197             RegisterInfo data_reg;
5198             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5199             context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
5200 
5201             if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2))
5202                 return false;
5203         }
5204         else // Can only occur before ARMv7
5205         {
5206             // MemU[address,2] = bits(16) UNKNOWN;
5207         }
5208 
5209         // if wback then R[n] = offset_addr;
5210         if (wback)
5211         {
5212             context.type = eContextAdjustBaseRegister;
5213             context.SetAddress (offset_addr);
5214             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5215                 return false;
5216         }
5217     }
5218 
5219     return true;
5220 }
5221 
5222 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value,
5223 // and writes the result to the destination register.  It can optionally update the condition flags
5224 // based on the result.
5225 bool
5226 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding)
5227 {
5228 #if 0
5229     // ARM pseudo code...
5230     if ConditionPassed() then
5231         EncodingSpecificOperations();
5232         (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5233         if d == 15 then         // Can only occur for ARM encoding
5234             ALUWritePC(result); // setflags is always FALSE here
5235         else
5236             R[d] = result;
5237             if setflags then
5238                 APSR.N = result<31>;
5239                 APSR.Z = IsZeroBit(result);
5240                 APSR.C = carry;
5241                 APSR.V = overflow;
5242 #endif
5243 
5244     bool success = false;
5245 
5246     if (ConditionPassed(opcode))
5247     {
5248         uint32_t Rd, Rn;
5249         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
5250         bool setflags;
5251         switch (encoding)
5252         {
5253         case eEncodingT1:
5254             Rd = Bits32(opcode, 11, 8);
5255             Rn = Bits32(opcode, 19, 16);
5256             setflags = BitIsSet(opcode, 20);
5257             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5258             if (BadReg(Rd) || BadReg(Rn))
5259                 return false;
5260             break;
5261         case eEncodingA1:
5262             Rd = Bits32(opcode, 15, 12);
5263             Rn = Bits32(opcode, 19, 16);
5264             setflags = BitIsSet(opcode, 20);
5265             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5266 
5267             if (Rd == 15 && setflags)
5268                 return EmulateSUBSPcLrEtc (opcode, encoding);
5269             break;
5270         default:
5271             return false;
5272         }
5273 
5274         // Read the first operand.
5275         int32_t val1 = ReadCoreReg(Rn, &success);
5276         if (!success)
5277             return false;
5278 
5279         AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5280 
5281         EmulateInstruction::Context context;
5282         context.type = EmulateInstruction::eContextImmediate;
5283         context.SetNoArgs ();
5284 
5285         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5286             return false;
5287     }
5288     return true;
5289 }
5290 
5291 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted
5292 // register value, and writes the result to the destination register.  It can optionally update the
5293 // condition flags based on the result.
5294 bool
5295 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding)
5296 {
5297 #if 0
5298     // ARM pseudo code...
5299     if ConditionPassed() then
5300         EncodingSpecificOperations();
5301         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5302         (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5303         if d == 15 then         // Can only occur for ARM encoding
5304             ALUWritePC(result); // setflags is always FALSE here
5305         else
5306             R[d] = result;
5307             if setflags then
5308                 APSR.N = result<31>;
5309                 APSR.Z = IsZeroBit(result);
5310                 APSR.C = carry;
5311                 APSR.V = overflow;
5312 #endif
5313 
5314     bool success = false;
5315 
5316     if (ConditionPassed(opcode))
5317     {
5318         uint32_t Rd, Rn, Rm;
5319         ARM_ShifterType shift_t;
5320         uint32_t shift_n; // the shift applied to the value read from Rm
5321         bool setflags;
5322         switch (encoding)
5323         {
5324         case eEncodingT1:
5325             Rd = Rn = Bits32(opcode, 2, 0);
5326             Rm = Bits32(opcode, 5, 3);
5327             setflags = !InITBlock();
5328             shift_t = SRType_LSL;
5329             shift_n = 0;
5330             break;
5331         case eEncodingT2:
5332             Rd = Bits32(opcode, 11, 8);
5333             Rn = Bits32(opcode, 19, 16);
5334             Rm = Bits32(opcode, 3, 0);
5335             setflags = BitIsSet(opcode, 20);
5336             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5337             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5338                 return false;
5339             break;
5340         case eEncodingA1:
5341             Rd = Bits32(opcode, 15, 12);
5342             Rn = Bits32(opcode, 19, 16);
5343             Rm = Bits32(opcode, 3, 0);
5344             setflags = BitIsSet(opcode, 20);
5345             shift_n = DecodeImmShiftARM(opcode, shift_t);
5346 
5347             if (Rd == 15 && setflags)
5348                 return EmulateSUBSPcLrEtc (opcode, encoding);
5349             break;
5350         default:
5351             return false;
5352         }
5353 
5354         // Read the first operand.
5355         int32_t val1 = ReadCoreReg(Rn, &success);
5356         if (!success)
5357             return false;
5358 
5359         // Read the second operand.
5360         int32_t val2 = ReadCoreReg(Rm, &success);
5361         if (!success)
5362             return false;
5363 
5364         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5365         if (!success)
5366             return false;
5367         AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5368 
5369         EmulateInstruction::Context context;
5370         context.type = EmulateInstruction::eContextImmediate;
5371         context.SetNoArgs ();
5372 
5373         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5374             return false;
5375     }
5376     return true;
5377 }
5378 
5379 // This instruction adds an immediate value to the PC value to form a PC-relative address,
5380 // and writes the result to the destination register.
5381 bool
5382 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding)
5383 {
5384 #if 0
5385     // ARM pseudo code...
5386     if ConditionPassed() then
5387         EncodingSpecificOperations();
5388         result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5389         if d == 15 then         // Can only occur for ARM encodings
5390             ALUWritePC(result);
5391         else
5392             R[d] = result;
5393 #endif
5394 
5395     bool success = false;
5396 
5397     if (ConditionPassed(opcode))
5398     {
5399         uint32_t Rd;
5400         uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5401         bool add;
5402         switch (encoding)
5403         {
5404         case eEncodingT1:
5405             Rd = Bits32(opcode, 10, 8);
5406             imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5407             add = true;
5408             break;
5409         case eEncodingT2:
5410         case eEncodingT3:
5411             Rd = Bits32(opcode, 11, 8);
5412             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5413             add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5414             if (BadReg(Rd))
5415                 return false;
5416             break;
5417         case eEncodingA1:
5418         case eEncodingA2:
5419             Rd = Bits32(opcode, 15, 12);
5420             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5421             add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5422             break;
5423         default:
5424             return false;
5425         }
5426 
5427         // Read the PC value.
5428         uint32_t pc = ReadCoreReg(PC_REG, &success);
5429         if (!success)
5430             return false;
5431 
5432         uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5433 
5434         EmulateInstruction::Context context;
5435         context.type = EmulateInstruction::eContextImmediate;
5436         context.SetNoArgs ();
5437 
5438         if (!WriteCoreReg(context, result, Rd))
5439             return false;
5440     }
5441     return true;
5442 }
5443 
5444 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result
5445 // to the destination register.  It can optionally update the condition flags based on the result.
5446 bool
5447 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding)
5448 {
5449 #if 0
5450     // ARM pseudo code...
5451     if ConditionPassed() then
5452         EncodingSpecificOperations();
5453         result = R[n] AND imm32;
5454         if d == 15 then         // Can only occur for ARM encoding
5455             ALUWritePC(result); // setflags is always FALSE here
5456         else
5457             R[d] = result;
5458             if setflags then
5459                 APSR.N = result<31>;
5460                 APSR.Z = IsZeroBit(result);
5461                 APSR.C = carry;
5462                 // APSR.V unchanged
5463 #endif
5464 
5465     bool success = false;
5466 
5467     if (ConditionPassed(opcode))
5468     {
5469         uint32_t Rd, Rn;
5470         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
5471         bool setflags;
5472         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5473         switch (encoding)
5474         {
5475         case eEncodingT1:
5476             Rd = Bits32(opcode, 11, 8);
5477             Rn = Bits32(opcode, 19, 16);
5478             setflags = BitIsSet(opcode, 20);
5479             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5480             // if Rd == '1111' && S == '1' then SEE TST (immediate);
5481             if (Rd == 15 && setflags)
5482                 return EmulateTSTImm(opcode, eEncodingT1);
5483             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
5484                 return false;
5485             break;
5486         case eEncodingA1:
5487             Rd = Bits32(opcode, 15, 12);
5488             Rn = Bits32(opcode, 19, 16);
5489             setflags = BitIsSet(opcode, 20);
5490             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5491 
5492             if (Rd == 15 && setflags)
5493                 return EmulateSUBSPcLrEtc (opcode, encoding);
5494             break;
5495         default:
5496             return false;
5497         }
5498 
5499         // Read the first operand.
5500         uint32_t val1 = ReadCoreReg(Rn, &success);
5501         if (!success)
5502             return false;
5503 
5504         uint32_t result = val1 & imm32;
5505 
5506         EmulateInstruction::Context context;
5507         context.type = EmulateInstruction::eContextImmediate;
5508         context.SetNoArgs ();
5509 
5510         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5511             return false;
5512     }
5513     return true;
5514 }
5515 
5516 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value,
5517 // and writes the result to the destination register.  It can optionally update the condition flags
5518 // based on the result.
5519 bool
5520 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding)
5521 {
5522 #if 0
5523     // ARM pseudo code...
5524     if ConditionPassed() then
5525         EncodingSpecificOperations();
5526         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5527         result = R[n] AND shifted;
5528         if d == 15 then         // Can only occur for ARM encoding
5529             ALUWritePC(result); // setflags is always FALSE here
5530         else
5531             R[d] = result;
5532             if setflags then
5533                 APSR.N = result<31>;
5534                 APSR.Z = IsZeroBit(result);
5535                 APSR.C = carry;
5536                 // APSR.V unchanged
5537 #endif
5538 
5539     bool success = false;
5540 
5541     if (ConditionPassed(opcode))
5542     {
5543         uint32_t Rd, Rn, Rm;
5544         ARM_ShifterType shift_t;
5545         uint32_t shift_n; // the shift applied to the value read from Rm
5546         bool setflags;
5547         uint32_t carry;
5548         switch (encoding)
5549         {
5550         case eEncodingT1:
5551             Rd = Rn = Bits32(opcode, 2, 0);
5552             Rm = Bits32(opcode, 5, 3);
5553             setflags = !InITBlock();
5554             shift_t = SRType_LSL;
5555             shift_n = 0;
5556             break;
5557         case eEncodingT2:
5558             Rd = Bits32(opcode, 11, 8);
5559             Rn = Bits32(opcode, 19, 16);
5560             Rm = Bits32(opcode, 3, 0);
5561             setflags = BitIsSet(opcode, 20);
5562             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5563             // if Rd == '1111' && S == '1' then SEE TST (register);
5564             if (Rd == 15 && setflags)
5565                 return EmulateTSTReg(opcode, eEncodingT2);
5566             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
5567                 return false;
5568             break;
5569         case eEncodingA1:
5570             Rd = Bits32(opcode, 15, 12);
5571             Rn = Bits32(opcode, 19, 16);
5572             Rm = Bits32(opcode, 3, 0);
5573             setflags = BitIsSet(opcode, 20);
5574             shift_n = DecodeImmShiftARM(opcode, shift_t);
5575 
5576             if (Rd == 15 && setflags)
5577                 return EmulateSUBSPcLrEtc (opcode, encoding);
5578             break;
5579         default:
5580             return false;
5581         }
5582 
5583         // Read the first operand.
5584         uint32_t val1 = ReadCoreReg(Rn, &success);
5585         if (!success)
5586             return false;
5587 
5588         // Read the second operand.
5589         uint32_t val2 = ReadCoreReg(Rm, &success);
5590         if (!success)
5591             return false;
5592 
5593         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5594         if (!success)
5595             return false;
5596         uint32_t result = val1 & shifted;
5597 
5598         EmulateInstruction::Context context;
5599         context.type = EmulateInstruction::eContextImmediate;
5600         context.SetNoArgs ();
5601 
5602         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5603             return false;
5604     }
5605     return true;
5606 }
5607 
5608 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an
5609 // immediate value, and writes the result to the destination register.  It can optionally update the
5610 // condition flags based on the result.
5611 bool
5612 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding)
5613 {
5614 #if 0
5615     // ARM pseudo code...
5616     if ConditionPassed() then
5617         EncodingSpecificOperations();
5618         result = R[n] AND NOT(imm32);
5619         if d == 15 then         // Can only occur for ARM encoding
5620             ALUWritePC(result); // setflags is always FALSE here
5621         else
5622             R[d] = result;
5623             if setflags then
5624                 APSR.N = result<31>;
5625                 APSR.Z = IsZeroBit(result);
5626                 APSR.C = carry;
5627                 // APSR.V unchanged
5628 #endif
5629 
5630     bool success = false;
5631 
5632     if (ConditionPassed(opcode))
5633     {
5634         uint32_t Rd, Rn;
5635         uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn
5636         bool setflags;
5637         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5638         switch (encoding)
5639         {
5640         case eEncodingT1:
5641             Rd = Bits32(opcode, 11, 8);
5642             Rn = Bits32(opcode, 19, 16);
5643             setflags = BitIsSet(opcode, 20);
5644             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5645             if (BadReg(Rd) || BadReg(Rn))
5646                 return false;
5647             break;
5648         case eEncodingA1:
5649             Rd = Bits32(opcode, 15, 12);
5650             Rn = Bits32(opcode, 19, 16);
5651             setflags = BitIsSet(opcode, 20);
5652             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5653 
5654             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5655             if (Rd == 15 && setflags)
5656                 return EmulateSUBSPcLrEtc (opcode, encoding);
5657             break;
5658         default:
5659             return false;
5660         }
5661 
5662         // Read the first operand.
5663         uint32_t val1 = ReadCoreReg(Rn, &success);
5664         if (!success)
5665             return false;
5666 
5667         uint32_t result = val1 & ~imm32;
5668 
5669         EmulateInstruction::Context context;
5670         context.type = EmulateInstruction::eContextImmediate;
5671         context.SetNoArgs ();
5672 
5673         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5674             return false;
5675     }
5676     return true;
5677 }
5678 
5679 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an
5680 // optionally-shifted register value, and writes the result to the destination register.
5681 // It can optionally update the condition flags based on the result.
5682 bool
5683 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding)
5684 {
5685 #if 0
5686     // ARM pseudo code...
5687     if ConditionPassed() then
5688         EncodingSpecificOperations();
5689         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5690         result = R[n] AND NOT(shifted);
5691         if d == 15 then         // Can only occur for ARM encoding
5692             ALUWritePC(result); // setflags is always FALSE here
5693         else
5694             R[d] = result;
5695             if setflags then
5696                 APSR.N = result<31>;
5697                 APSR.Z = IsZeroBit(result);
5698                 APSR.C = carry;
5699                 // APSR.V unchanged
5700 #endif
5701 
5702     bool success = false;
5703 
5704     if (ConditionPassed(opcode))
5705     {
5706         uint32_t Rd, Rn, Rm;
5707         ARM_ShifterType shift_t;
5708         uint32_t shift_n; // the shift applied to the value read from Rm
5709         bool setflags;
5710         uint32_t carry;
5711         switch (encoding)
5712         {
5713         case eEncodingT1:
5714             Rd = Rn = Bits32(opcode, 2, 0);
5715             Rm = Bits32(opcode, 5, 3);
5716             setflags = !InITBlock();
5717             shift_t = SRType_LSL;
5718             shift_n = 0;
5719             break;
5720         case eEncodingT2:
5721             Rd = Bits32(opcode, 11, 8);
5722             Rn = Bits32(opcode, 19, 16);
5723             Rm = Bits32(opcode, 3, 0);
5724             setflags = BitIsSet(opcode, 20);
5725             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5726             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5727                 return false;
5728             break;
5729         case eEncodingA1:
5730             Rd = Bits32(opcode, 15, 12);
5731             Rn = Bits32(opcode, 19, 16);
5732             Rm = Bits32(opcode, 3, 0);
5733             setflags = BitIsSet(opcode, 20);
5734             shift_n = DecodeImmShiftARM(opcode, shift_t);
5735 
5736             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5737             if (Rd == 15 && setflags)
5738                 return EmulateSUBSPcLrEtc (opcode, encoding);
5739             break;
5740         default:
5741             return false;
5742         }
5743 
5744         // Read the first operand.
5745         uint32_t val1 = ReadCoreReg(Rn, &success);
5746         if (!success)
5747             return false;
5748 
5749         // Read the second operand.
5750         uint32_t val2 = ReadCoreReg(Rm, &success);
5751         if (!success)
5752             return false;
5753 
5754         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5755         if (!success)
5756             return false;
5757         uint32_t result = val1 & ~shifted;
5758 
5759         EmulateInstruction::Context context;
5760         context.type = EmulateInstruction::eContextImmediate;
5761         context.SetNoArgs ();
5762 
5763         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5764             return false;
5765     }
5766     return true;
5767 }
5768 
5769 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
5770 // from memory, and writes it to a register.  It can use offset, post-indexed, or pre-indexed addressing.
5771 bool
5772 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding)
5773 {
5774 #if 0
5775     if ConditionPassed() then
5776         EncodingSpecificOperations();
5777         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5778         address = if index then offset_addr else R[n];
5779         data = MemU[address,4];
5780         if wback then R[n] = offset_addr;
5781         if t == 15 then
5782             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5783         elsif UnalignedSupport() || address<1:0> = '00' then
5784             R[t] = data;
5785         else // Can only apply before ARMv7
5786             R[t] = ROR(data, 8*UInt(address<1:0>));
5787 #endif
5788 
5789     bool success = false;
5790 
5791     if (ConditionPassed(opcode))
5792     {
5793         const uint32_t addr_byte_size = GetAddressByteSize();
5794 
5795         uint32_t t;
5796         uint32_t n;
5797         uint32_t imm32;
5798         bool index;
5799         bool add;
5800         bool wback;
5801 
5802         switch (encoding)
5803         {
5804             case eEncodingA1:
5805                 // if Rn == '1111' then SEE LDR (literal);
5806                 // if P == '0' && W == '1' then SEE LDRT;
5807                 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP;
5808                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5809                 t = Bits32 (opcode, 15, 12);
5810                 n = Bits32 (opcode, 19, 16);
5811                 imm32 = Bits32 (opcode, 11, 0);
5812 
5813                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5814                 index = BitIsSet (opcode, 24);
5815                 add = BitIsSet (opcode, 23);
5816                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5817 
5818                 // if wback && n == t then UNPREDICTABLE;
5819                 if (wback && (n == t))
5820                     return false;
5821 
5822                 break;
5823 
5824             default:
5825                 return false;
5826         }
5827 
5828         addr_t address;
5829         addr_t offset_addr;
5830         addr_t base_address = ReadCoreReg (n, &success);
5831         if (!success)
5832             return false;
5833 
5834         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5835         if (add)
5836             offset_addr = base_address + imm32;
5837         else
5838             offset_addr = base_address - imm32;
5839 
5840         // address = if index then offset_addr else R[n];
5841         if (index)
5842             address = offset_addr;
5843         else
5844             address = base_address;
5845 
5846         // data = MemU[address,4];
5847 
5848         RegisterInfo base_reg;
5849         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5850 
5851         EmulateInstruction::Context context;
5852         context.type = eContextRegisterLoad;
5853         context.SetRegisterPlusOffset (base_reg, address - base_address);
5854 
5855         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5856         if (!success)
5857             return false;
5858 
5859         // if wback then R[n] = offset_addr;
5860         if (wback)
5861         {
5862             context.type = eContextAdjustBaseRegister;
5863             context.SetAddress (offset_addr);
5864             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5865                 return false;
5866         }
5867 
5868         // if t == 15 then
5869         if (t == 15)
5870         {
5871             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5872             if (BitIsClear (address, 1) && BitIsClear (address, 0))
5873             {
5874                 // LoadWritePC (data);
5875                 context.type = eContextRegisterLoad;
5876                 context.SetRegisterPlusOffset (base_reg, address - base_address);
5877                 LoadWritePC (context, data);
5878             }
5879             else
5880                   return false;
5881         }
5882         // elsif UnalignedSupport() || address<1:0> = '00' then
5883         else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5884         {
5885             // R[t] = data;
5886             context.type = eContextRegisterLoad;
5887             context.SetRegisterPlusOffset (base_reg, address - base_address);
5888             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5889                 return false;
5890         }
5891         // else // Can only apply before ARMv7
5892         else
5893         {
5894             // R[t] = ROR(data, 8*UInt(address<1:0>));
5895             data = ROR (data, Bits32 (address, 1, 0), &success);
5896             if (!success)
5897                 return false;
5898             context.type = eContextRegisterLoad;
5899             context.SetImmediate (data);
5900             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5901                 return false;
5902         }
5903 
5904     }
5905     return true;
5906 }
5907 
5908 // LDR (register) calculates an address from a base register value and an offset register value, loads a word
5909 // from memory, and writes it to a resgister.  The offset register value can optionally be shifted.
5910 bool
5911 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding)
5912 {
5913 #if 0
5914     if ConditionPassed() then
5915         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5916         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5917         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5918         address = if index then offset_addr else R[n];
5919         data = MemU[address,4];
5920         if wback then R[n] = offset_addr;
5921         if t == 15 then
5922             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5923         elsif UnalignedSupport() || address<1:0> = '00' then
5924             R[t] = data;
5925         else // Can only apply before ARMv7
5926             if CurrentInstrSet() == InstrSet_ARM then
5927                 R[t] = ROR(data, 8*UInt(address<1:0>));
5928             else
5929                 R[t] = bits(32) UNKNOWN;
5930 #endif
5931 
5932     bool success = false;
5933 
5934     if (ConditionPassed(opcode))
5935     {
5936         const uint32_t addr_byte_size = GetAddressByteSize();
5937 
5938         uint32_t t;
5939         uint32_t n;
5940         uint32_t m;
5941         bool index;
5942         bool add;
5943         bool wback;
5944         ARM_ShifterType shift_t;
5945         uint32_t shift_n;
5946 
5947         switch (encoding)
5948         {
5949             case eEncodingT1:
5950                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5951                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5952                 t = Bits32 (opcode, 2, 0);
5953                 n = Bits32 (opcode, 5, 3);
5954                 m = Bits32 (opcode, 8, 6);
5955 
5956                 // index = TRUE; add = TRUE; wback = FALSE;
5957                 index = true;
5958                 add = true;
5959                 wback = false;
5960 
5961                 // (shift_t, shift_n) = (SRType_LSL, 0);
5962                 shift_t = SRType_LSL;
5963                 shift_n = 0;
5964 
5965                 break;
5966 
5967             case eEncodingT2:
5968                 // if Rn == '1111' then SEE LDR (literal);
5969                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5970                 t = Bits32 (opcode, 15, 12);
5971                 n = Bits32 (opcode, 19, 16);
5972                 m = Bits32 (opcode, 3, 0);
5973 
5974                 // index = TRUE; add = TRUE; wback = FALSE;
5975                 index = true;
5976                 add = true;
5977                 wback = false;
5978 
5979                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5980                 shift_t = SRType_LSL;
5981                 shift_n = Bits32 (opcode, 5, 4);
5982 
5983                 // if BadReg(m) then UNPREDICTABLE;
5984                 if (BadReg (m))
5985                     return false;
5986 
5987                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
5988                 if ((t == 15) && InITBlock() && !LastInITBlock())
5989                     return false;
5990 
5991                 break;
5992 
5993             case eEncodingA1:
5994             {
5995                 // if P == '0' && W == '1' then SEE LDRT;
5996                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5997                 t = Bits32 (opcode, 15, 12);
5998                 n = Bits32 (opcode, 19, 16);
5999                 m = Bits32 (opcode, 3, 0);
6000 
6001                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6002                 index = BitIsSet (opcode, 24);
6003                 add = BitIsSet (opcode, 23);
6004                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6005 
6006                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6007                 uint32_t type = Bits32 (opcode, 6, 5);
6008                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6009                 shift_n = DecodeImmShift (type, imm5, shift_t);
6010 
6011                 // if m == 15 then UNPREDICTABLE;
6012                 if (m == 15)
6013                     return false;
6014 
6015                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6016                 if (wback && ((n == 15) || (n == t)))
6017                     return false;
6018             }
6019                 break;
6020 
6021 
6022             default:
6023                 return false;
6024         }
6025 
6026         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6027         if (!success)
6028             return false;
6029 
6030         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6031         if (!success)
6032             return false;
6033 
6034         addr_t offset_addr;
6035         addr_t address;
6036 
6037         // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an application level alias for the CPSR".
6038         addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success);
6039         if (!success)
6040             return false;
6041 
6042         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6043         if (add)
6044             offset_addr = Rn + offset;
6045         else
6046             offset_addr = Rn - offset;
6047 
6048         // address = if index then offset_addr else R[n];
6049             if (index)
6050                 address = offset_addr;
6051             else
6052                 address = Rn;
6053 
6054         // data = MemU[address,4];
6055         RegisterInfo base_reg;
6056         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6057 
6058         EmulateInstruction::Context context;
6059         context.type = eContextRegisterLoad;
6060         context.SetRegisterPlusOffset (base_reg, address - Rn);
6061 
6062         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
6063         if (!success)
6064             return false;
6065 
6066         // if wback then R[n] = offset_addr;
6067         if (wback)
6068         {
6069             context.type = eContextAdjustBaseRegister;
6070             context.SetAddress (offset_addr);
6071             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6072                 return false;
6073         }
6074 
6075         // if t == 15 then
6076         if (t == 15)
6077         {
6078             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6079             if (BitIsClear (address, 1) && BitIsClear (address, 0))
6080             {
6081                 context.type = eContextRegisterLoad;
6082                 context.SetRegisterPlusOffset (base_reg, address - Rn);
6083                 LoadWritePC (context, data);
6084             }
6085             else
6086                 return false;
6087         }
6088         // elsif UnalignedSupport() || address<1:0> = '00' then
6089         else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
6090         {
6091             // R[t] = data;
6092             context.type = eContextRegisterLoad;
6093             context.SetRegisterPlusOffset (base_reg, address - Rn);
6094             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6095                 return false;
6096         }
6097         else // Can only apply before ARMv7
6098         {
6099             // if CurrentInstrSet() == InstrSet_ARM then
6100             if (CurrentInstrSet () == eModeARM)
6101             {
6102                 // R[t] = ROR(data, 8*UInt(address<1:0>));
6103                 data = ROR (data, Bits32 (address, 1, 0), &success);
6104                 if (!success)
6105                     return false;
6106                 context.type = eContextRegisterLoad;
6107                 context.SetImmediate (data);
6108                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6109                     return false;
6110             }
6111             else
6112             {
6113                 // R[t] = bits(32) UNKNOWN;
6114                 WriteBits32Unknown (t);
6115             }
6116         }
6117     }
6118     return true;
6119 }
6120 
6121 // LDRB (immediate, Thumb)
6122 bool
6123 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6124 {
6125 #if 0
6126     if ConditionPassed() then
6127         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6128         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6129         address = if index then offset_addr else R[n];
6130         R[t] = ZeroExtend(MemU[address,1], 32);
6131         if wback then R[n] = offset_addr;
6132 #endif
6133 
6134     bool success = false;
6135 
6136     if (ConditionPassed(opcode))
6137     {
6138         uint32_t t;
6139         uint32_t n;
6140         uint32_t imm32;
6141         bool index;
6142         bool add;
6143         bool wback;
6144 
6145         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6146         switch (encoding)
6147         {
6148             case eEncodingT1:
6149                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6150                 t = Bits32 (opcode, 2, 0);
6151                 n = Bits32 (opcode, 5, 3);
6152                 imm32 = Bits32 (opcode, 10, 6);
6153 
6154                 // index = TRUE; add = TRUE; wback = FALSE;
6155                 index = true;
6156                 add = true;
6157                 wback= false;
6158 
6159                 break;
6160 
6161             case eEncodingT2:
6162                 // if Rt == '1111' then SEE PLD;
6163                 // if Rn == '1111' then SEE LDRB (literal);
6164                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6165                 t = Bits32 (opcode, 15, 12);
6166                 n = Bits32 (opcode, 19, 16);
6167                 imm32 = Bits32 (opcode, 11, 0);
6168 
6169                 // index = TRUE; add = TRUE; wback = FALSE;
6170                 index = true;
6171                 add = true;
6172                 wback = false;
6173 
6174                 // if t == 13 then UNPREDICTABLE;
6175                 if (t == 13)
6176                     return false;
6177 
6178                 break;
6179 
6180             case eEncodingT3:
6181                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6182                 // if Rn == '1111' then SEE LDRB (literal);
6183                 // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6184                 // if P == '0' && W == '0' then UNDEFINED;
6185                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6186                     return false;
6187 
6188                   // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6189                 t = Bits32 (opcode, 15, 12);
6190                 n = Bits32 (opcode, 19, 16);
6191                 imm32 = Bits32 (opcode, 7, 0);
6192 
6193                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6194                 index = BitIsSet (opcode, 10);
6195                 add = BitIsSet (opcode, 9);
6196                 wback = BitIsSet (opcode, 8);
6197 
6198                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6199                 if (BadReg (t) || (wback && (n == t)))
6200                     return false;
6201 
6202                 break;
6203 
6204             default:
6205                 return false;
6206         }
6207 
6208         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6209         if (!success)
6210             return false;
6211 
6212         addr_t address;
6213         addr_t offset_addr;
6214 
6215         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6216         if (add)
6217             offset_addr = Rn + imm32;
6218         else
6219             offset_addr = Rn - imm32;
6220 
6221         // address = if index then offset_addr else R[n];
6222         if (index)
6223             address = offset_addr;
6224         else
6225             address = Rn;
6226 
6227         // R[t] = ZeroExtend(MemU[address,1], 32);
6228         RegisterInfo base_reg;
6229         RegisterInfo data_reg;
6230         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6231         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6232 
6233         EmulateInstruction::Context context;
6234         context.type = eContextRegisterLoad;
6235         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
6236 
6237         uint64_t data = MemURead (context, address, 1, 0, &success);
6238         if (!success)
6239             return false;
6240 
6241         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6242             return false;
6243 
6244         // if wback then R[n] = offset_addr;
6245         if (wback)
6246         {
6247             context.type = eContextAdjustBaseRegister;
6248             context.SetAddress (offset_addr);
6249             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6250                 return false;
6251         }
6252     }
6253     return true;
6254 }
6255 
6256 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6257 // zero-extends it to form a 32-bit word and writes it to a register.
6258 bool
6259 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6260 {
6261 #if 0
6262     if ConditionPassed() then
6263         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6264         base = Align(PC,4);
6265         address = if add then (base + imm32) else (base - imm32);
6266         R[t] = ZeroExtend(MemU[address,1], 32);
6267 #endif
6268 
6269     bool success = false;
6270 
6271     if (ConditionPassed(opcode))
6272     {
6273         uint32_t t;
6274         uint32_t imm32;
6275         bool add;
6276         switch (encoding)
6277         {
6278             case eEncodingT1:
6279                 // if Rt == '1111' then SEE PLD;
6280                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6281                 t = Bits32 (opcode, 15, 12);
6282                 imm32 = Bits32 (opcode, 11, 0);
6283                 add = BitIsSet (opcode, 23);
6284 
6285                 // if t == 13 then UNPREDICTABLE;
6286                 if (t == 13)
6287                     return false;
6288 
6289                 break;
6290 
6291             case eEncodingA1:
6292                 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6293                 t = Bits32 (opcode, 15, 12);
6294                 imm32 = Bits32 (opcode, 11, 0);
6295                 add = BitIsSet (opcode, 23);
6296 
6297                 // if t == 15 then UNPREDICTABLE;
6298                 if (t == 15)
6299                     return false;
6300                 break;
6301 
6302             default:
6303                 return false;
6304         }
6305 
6306         // base = Align(PC,4);
6307         uint32_t pc_val = ReadCoreReg (PC_REG, &success);
6308         if (!success)
6309             return false;
6310 
6311         uint32_t base = AlignPC (pc_val);
6312 
6313         addr_t address;
6314         // address = if add then (base + imm32) else (base - imm32);
6315         if (add)
6316             address = base + imm32;
6317         else
6318             address = base - imm32;
6319 
6320         // R[t] = ZeroExtend(MemU[address,1], 32);
6321         EmulateInstruction::Context context;
6322         context.type = eContextRelativeBranchImmediate;
6323         context.SetImmediate (address - base);
6324 
6325         uint64_t data = MemURead (context, address, 1, 0, &success);
6326         if (!success)
6327             return false;
6328 
6329         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6330             return false;
6331     }
6332     return true;
6333 }
6334 
6335 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from
6336 // memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6337 // optionally be shifted.
6338 bool
6339 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding)
6340 {
6341 #if 0
6342     if ConditionPassed() then
6343         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6344         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6345         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6346         address = if index then offset_addr else R[n];
6347         R[t] = ZeroExtend(MemU[address,1],32);
6348         if wback then R[n] = offset_addr;
6349 #endif
6350 
6351     bool success = false;
6352 
6353     if (ConditionPassed(opcode))
6354     {
6355         uint32_t t;
6356         uint32_t n;
6357         uint32_t m;
6358         bool index;
6359         bool add;
6360         bool wback;
6361         ARM_ShifterType shift_t;
6362         uint32_t shift_n;
6363 
6364         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6365         switch (encoding)
6366         {
6367             case eEncodingT1:
6368                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6369                 t = Bits32 (opcode, 2, 0);
6370                 n = Bits32 (opcode, 5, 3);
6371                 m = Bits32 (opcode, 8, 6);
6372 
6373                 // index = TRUE; add = TRUE; wback = FALSE;
6374                 index = true;
6375                 add = true;
6376                 wback = false;
6377 
6378                 // (shift_t, shift_n) = (SRType_LSL, 0);
6379                 shift_t = SRType_LSL;
6380                 shift_n = 0;
6381                 break;
6382 
6383             case eEncodingT2:
6384                 // if Rt == '1111' then SEE PLD;
6385                 // if Rn == '1111' then SEE LDRB (literal);
6386                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6387                 t = Bits32 (opcode, 15, 12);
6388                 n = Bits32 (opcode, 19, 16);
6389                 m = Bits32 (opcode, 3, 0);
6390 
6391                 // index = TRUE; add = TRUE; wback = FALSE;
6392                 index = true;
6393                 add = true;
6394                 wback = false;
6395 
6396                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6397                 shift_t = SRType_LSL;
6398                 shift_n = Bits32 (opcode, 5, 4);
6399 
6400                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6401                 if ((t == 13) || BadReg (m))
6402                     return false;
6403                 break;
6404 
6405             case eEncodingA1:
6406             {
6407                 // if P == '0' && W == '1' then SEE LDRBT;
6408                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6409                 t = Bits32 (opcode, 15, 12);
6410                 n = Bits32 (opcode, 19, 16);
6411                 m = Bits32 (opcode, 3, 0);
6412 
6413                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6414                 index = BitIsSet (opcode, 24);
6415                 add = BitIsSet (opcode, 23);
6416                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6417 
6418                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6419                 uint32_t type = Bits32 (opcode, 6, 5);
6420                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6421                 shift_n = DecodeImmShift (type, imm5, shift_t);
6422 
6423                 // if t == 15 || m == 15 then UNPREDICTABLE;
6424                 if ((t == 15) || (m == 15))
6425                     return false;
6426 
6427                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6428                 if (wback && ((n == 15) || (n == t)))
6429                     return false;
6430             }
6431                 break;
6432 
6433             default:
6434                 return false;
6435         }
6436 
6437         addr_t offset_addr;
6438         addr_t address;
6439 
6440         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6441         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6442         if (!success)
6443             return false;
6444 
6445         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6446         if (!success)
6447             return false;
6448 
6449         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6450         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6451         if (!success)
6452             return false;
6453 
6454         if (add)
6455             offset_addr = Rn + offset;
6456         else
6457             offset_addr = Rn - offset;
6458 
6459         // address = if index then offset_addr else R[n];
6460         if (index)
6461             address = offset_addr;
6462         else
6463             address = Rn;
6464 
6465         // R[t] = ZeroExtend(MemU[address,1],32);
6466         RegisterInfo base_reg;
6467         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6468 
6469         EmulateInstruction::Context context;
6470         context.type = eContextRegisterLoad;
6471         context.SetRegisterPlusOffset (base_reg, address - Rn);
6472 
6473         uint64_t data = MemURead (context, address, 1, 0, &success);
6474         if (!success)
6475             return false;
6476 
6477         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6478             return false;
6479 
6480         // if wback then R[n] = offset_addr;
6481         if (wback)
6482         {
6483             context.type = eContextAdjustBaseRegister;
6484             context.SetAddress (offset_addr);
6485             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6486                 return false;
6487         }
6488     }
6489     return true;
6490 }
6491 
6492 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a
6493 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register.  It can use offset,
6494 // post-indexed, or pre-indexed addressing.
6495 bool
6496 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding)
6497 {
6498 #if 0
6499     if ConditionPassed() then
6500         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6501         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6502         address = if index then offset_addr else R[n];
6503         data = MemU[address,2];
6504         if wback then R[n] = offset_addr;
6505         if UnalignedSupport() || address<0> = '0' then
6506             R[t] = ZeroExtend(data, 32);
6507         else // Can only apply before ARMv7
6508             R[t] = bits(32) UNKNOWN;
6509 #endif
6510 
6511 
6512     bool success = false;
6513 
6514     if (ConditionPassed(opcode))
6515     {
6516         uint32_t t;
6517         uint32_t n;
6518         uint32_t imm32;
6519         bool index;
6520         bool add;
6521         bool wback;
6522 
6523         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6524         switch (encoding)
6525         {
6526             case eEncodingT1:
6527                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
6528                 t = Bits32 (opcode, 2, 0);
6529                 n = Bits32 (opcode, 5, 3);
6530                 imm32 = Bits32 (opcode, 10, 6) << 1;
6531 
6532                 // index = TRUE; add = TRUE; wback = FALSE;
6533                 index = true;
6534                 add = true;
6535                 wback = false;
6536 
6537                 break;
6538 
6539             case eEncodingT2:
6540                 // if Rt == '1111' then SEE "Unallocated memory hints";
6541                 // if Rn == '1111' then SEE LDRH (literal);
6542                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6543                 t = Bits32 (opcode, 15, 12);
6544                 n = Bits32 (opcode, 19, 16);
6545                 imm32 = Bits32 (opcode, 11, 0);
6546 
6547                 // index = TRUE; add = TRUE; wback = FALSE;
6548                 index = true;
6549                 add = true;
6550                 wback = false;
6551 
6552                 // if t == 13 then UNPREDICTABLE;
6553                 if (t == 13)
6554                     return false;
6555                 break;
6556 
6557             case eEncodingT3:
6558                 // if Rn == '1111' then SEE LDRH (literal);
6559                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
6560                 // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
6561                 // if P == '0' && W == '0' then UNDEFINED;
6562                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6563                     return false;
6564 
6565                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6566                 t = Bits32 (opcode, 15, 12);
6567                 n = Bits32 (opcode, 19, 16);
6568                 imm32 = Bits32 (opcode, 7, 0);
6569 
6570                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6571                 index = BitIsSet (opcode, 10);
6572                 add = BitIsSet (opcode, 9);
6573                 wback = BitIsSet (opcode, 8);
6574 
6575                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6576                 if (BadReg (t) || (wback && (n == t)))
6577                     return false;
6578                 break;
6579 
6580             default:
6581                 return false;
6582         }
6583 
6584         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6585         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6586         if (!success)
6587             return false;
6588 
6589         addr_t offset_addr;
6590         addr_t address;
6591 
6592         if (add)
6593             offset_addr = Rn + imm32;
6594         else
6595             offset_addr = Rn - imm32;
6596 
6597         // address = if index then offset_addr else R[n];
6598         if (index)
6599             address = offset_addr;
6600         else
6601             address = Rn;
6602 
6603         // data = MemU[address,2];
6604         RegisterInfo base_reg;
6605         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6606 
6607         EmulateInstruction::Context context;
6608         context.type = eContextRegisterLoad;
6609         context.SetRegisterPlusOffset (base_reg, address - Rn);
6610 
6611         uint64_t data = MemURead (context, address, 2, 0, &success);
6612         if (!success)
6613             return false;
6614 
6615         // if wback then R[n] = offset_addr;
6616         if (wback)
6617         {
6618             context.type = eContextAdjustBaseRegister;
6619             context.SetAddress (offset_addr);
6620             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6621                 return false;
6622         }
6623 
6624         // if UnalignedSupport() || address<0> = '0' then
6625         if (UnalignedSupport () || BitIsClear (address, 0))
6626         {
6627             // R[t] = ZeroExtend(data, 32);
6628             context.type = eContextRegisterLoad;
6629             context.SetRegisterPlusOffset (base_reg, address - Rn);
6630             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6631                 return false;
6632         }
6633         else // Can only apply before ARMv7
6634         {
6635             // R[t] = bits(32) UNKNOWN;
6636             WriteBits32Unknown (t);
6637         }
6638     }
6639     return true;
6640 }
6641 
6642 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory,
6643 // zero-extends it to form a 32-bit word, and writes it to a register.
6644 bool
6645 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding)
6646 {
6647 #if 0
6648     if ConditionPassed() then
6649         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6650         base = Align(PC,4);
6651         address = if add then (base + imm32) else (base - imm32);
6652         data = MemU[address,2];
6653         if UnalignedSupport() || address<0> = '0' then
6654             R[t] = ZeroExtend(data, 32);
6655         else // Can only apply before ARMv7
6656             R[t] = bits(32) UNKNOWN;
6657 #endif
6658 
6659     bool success = false;
6660 
6661     if (ConditionPassed(opcode))
6662     {
6663         uint32_t t;
6664         uint32_t imm32;
6665         bool add;
6666 
6667         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6668         switch (encoding)
6669         {
6670             case eEncodingT1:
6671                 // if Rt == '1111' then SEE "Unallocated memory hints";
6672                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6673                 t = Bits32 (opcode, 15, 12);
6674                 imm32 = Bits32 (opcode, 11, 0);
6675                 add = BitIsSet (opcode, 23);
6676 
6677                 // if t == 13 then UNPREDICTABLE;
6678                 if (t == 13)
6679                     return false;
6680 
6681                 break;
6682 
6683             case eEncodingA1:
6684             {
6685                 uint32_t imm4H = Bits32 (opcode, 11, 8);
6686                 uint32_t imm4L = Bits32 (opcode, 3, 0);
6687 
6688                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6689                 t = Bits32 (opcode, 15, 12);
6690                 imm32 = (imm4H << 4) | imm4L;
6691                 add = BitIsSet (opcode, 23);
6692 
6693                 // if t == 15 then UNPREDICTABLE;
6694                 if (t == 15)
6695                     return false;
6696                 break;
6697             }
6698 
6699             default:
6700                 return false;
6701         }
6702 
6703         // base = Align(PC,4);
6704         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6705         if (!success)
6706             return false;
6707 
6708         addr_t base = AlignPC (pc_value);
6709         addr_t address;
6710 
6711         // address = if add then (base + imm32) else (base - imm32);
6712         if (add)
6713             address = base + imm32;
6714         else
6715             address = base - imm32;
6716 
6717         // data = MemU[address,2];
6718         RegisterInfo base_reg;
6719         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
6720 
6721         EmulateInstruction::Context context;
6722         context.type = eContextRegisterLoad;
6723         context.SetRegisterPlusOffset (base_reg, address - base);
6724 
6725         uint64_t data = MemURead (context, address, 2, 0, &success);
6726         if (!success)
6727             return false;
6728 
6729 
6730         // if UnalignedSupport() || address<0> = '0' then
6731         if (UnalignedSupport () || BitIsClear (address, 0))
6732         {
6733             // R[t] = ZeroExtend(data, 32);
6734             context.type = eContextRegisterLoad;
6735             context.SetRegisterPlusOffset (base_reg, address - base);
6736             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6737                 return false;
6738 
6739         }
6740         else // Can only apply before ARMv7
6741         {
6742             // R[t] = bits(32) UNKNOWN;
6743             WriteBits32Unknown (t);
6744         }
6745     }
6746     return true;
6747 }
6748 
6749 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword
6750 // from memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6751 // be shifted left by 0, 1, 2, or 3 bits.
6752 bool
6753 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding)
6754 {
6755 #if 0
6756     if ConditionPassed() then
6757         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6758         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6759         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6760         address = if index then offset_addr else R[n];
6761         data = MemU[address,2];
6762         if wback then R[n] = offset_addr;
6763         if UnalignedSupport() || address<0> = '0' then
6764             R[t] = ZeroExtend(data, 32);
6765         else // Can only apply before ARMv7
6766             R[t] = bits(32) UNKNOWN;
6767 #endif
6768 
6769     bool success = false;
6770 
6771     if (ConditionPassed(opcode))
6772     {
6773         uint32_t t;
6774         uint32_t n;
6775         uint32_t m;
6776         bool index;
6777         bool add;
6778         bool wback;
6779         ARM_ShifterType shift_t;
6780         uint32_t shift_n;
6781 
6782         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6783         switch (encoding)
6784         {
6785             case eEncodingT1:
6786                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6787                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6788                 t = Bits32 (opcode, 2, 0);
6789                 n = Bits32 (opcode, 5, 3);
6790                 m = Bits32 (opcode, 8, 6);
6791 
6792                 // index = TRUE; add = TRUE; wback = FALSE;
6793                 index = true;
6794                 add = true;
6795                 wback = false;
6796 
6797                 // (shift_t, shift_n) = (SRType_LSL, 0);
6798                 shift_t = SRType_LSL;
6799                 shift_n = 0;
6800 
6801                 break;
6802 
6803             case eEncodingT2:
6804                 // if Rn == '1111' then SEE LDRH (literal);
6805                 // if Rt == '1111' then SEE "Unallocated memory hints";
6806                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6807                 t = Bits32 (opcode, 15, 12);
6808                 n = Bits32 (opcode, 19, 16);
6809                 m = Bits32 (opcode, 3, 0);
6810 
6811                 // index = TRUE; add = TRUE; wback = FALSE;
6812                 index = true;
6813                 add = true;
6814                 wback = false;
6815 
6816                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6817                 shift_t = SRType_LSL;
6818                 shift_n = Bits32 (opcode, 5, 4);
6819 
6820                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6821                 if ((t == 13) || BadReg (m))
6822                     return false;
6823                 break;
6824 
6825             case eEncodingA1:
6826                 // if P == '0' && W == '1' then SEE LDRHT;
6827                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6828                 t = Bits32 (opcode, 15, 12);
6829                 n = Bits32 (opcode, 19, 16);
6830                 m = Bits32 (opcode, 3, 0);
6831 
6832                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6833                 index = BitIsSet (opcode, 24);
6834                 add = BitIsSet (opcode, 23);
6835                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6836 
6837                 // (shift_t, shift_n) = (SRType_LSL, 0);
6838                 shift_t = SRType_LSL;
6839                 shift_n = 0;
6840 
6841                 // if t == 15 || m == 15 then UNPREDICTABLE;
6842                 if ((t == 15) || (m == 15))
6843                     return false;
6844 
6845                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6846                 if (wback && ((n == 15) || (n == t)))
6847                     return false;
6848 
6849                 break;
6850 
6851             default:
6852                 return false;
6853         }
6854 
6855         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6856 
6857         uint64_t Rm  = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6858         if (!success)
6859             return false;
6860 
6861         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6862         if (!success)
6863             return false;
6864 
6865         addr_t offset_addr;
6866         addr_t address;
6867 
6868         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6869         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6870         if (!success)
6871             return false;
6872 
6873         if (add)
6874             offset_addr = Rn + offset;
6875         else
6876             offset_addr = Rn - offset;
6877 
6878         // address = if index then offset_addr else R[n];
6879         if (index)
6880             address = offset_addr;
6881         else
6882             address = Rn;
6883 
6884         // data = MemU[address,2];
6885         RegisterInfo base_reg;
6886         RegisterInfo offset_reg;
6887         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6888         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
6889 
6890         EmulateInstruction::Context context;
6891         context.type = eContextRegisterLoad;
6892         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6893         uint64_t data = MemURead (context, address, 2, 0, &success);
6894         if (!success)
6895             return false;
6896 
6897         // if wback then R[n] = offset_addr;
6898         if (wback)
6899         {
6900             context.type = eContextAdjustBaseRegister;
6901             context.SetAddress (offset_addr);
6902             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6903                 return false;
6904         }
6905 
6906         // if UnalignedSupport() || address<0> = '0' then
6907         if (UnalignedSupport() || BitIsClear (address, 0))
6908         {
6909             // R[t] = ZeroExtend(data, 32);
6910             context.type = eContextRegisterLoad;
6911             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6912             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6913                 return false;
6914         }
6915         else // Can only apply before ARMv7
6916         {
6917             // R[t] = bits(32) UNKNOWN;
6918             WriteBits32Unknown (t);
6919         }
6920     }
6921     return true;
6922 }
6923 
6924 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from
6925 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed,
6926 // or pre-indexed addressing.
6927 bool
6928 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6929 {
6930 #if 0
6931     if ConditionPassed() then
6932         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6933         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6934         address = if index then offset_addr else R[n];
6935         R[t] = SignExtend(MemU[address,1], 32);
6936         if wback then R[n] = offset_addr;
6937 #endif
6938 
6939     bool success = false;
6940 
6941     if (ConditionPassed(opcode))
6942     {
6943         uint32_t t;
6944         uint32_t n;
6945         uint32_t imm32;
6946         bool index;
6947         bool add;
6948         bool wback;
6949 
6950         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6951         switch (encoding)
6952         {
6953             case eEncodingT1:
6954                 // if Rt == '1111' then SEE PLI;
6955                 // if Rn == '1111' then SEE LDRSB (literal);
6956                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6957                 t = Bits32 (opcode, 15, 12);
6958                 n = Bits32 (opcode, 19, 16);
6959                 imm32 = Bits32 (opcode, 11, 0);
6960 
6961                 // index = TRUE; add = TRUE; wback = FALSE;
6962                 index = true;
6963                 add = true;
6964                 wback = false;
6965 
6966                 // if t == 13 then UNPREDICTABLE;
6967                 if (t == 13)
6968                     return false;
6969 
6970                 break;
6971 
6972             case eEncodingT2:
6973                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
6974                 // if Rn == '1111' then SEE LDRSB (literal);
6975                 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
6976                 // if P == '0' && W == '0' then UNDEFINED;
6977                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6978                     return false;
6979 
6980                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6981                 t = Bits32 (opcode, 15, 12);
6982                 n = Bits32 (opcode, 19, 16);
6983                 imm32 = Bits32 (opcode, 7, 0);
6984 
6985                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6986                 index = BitIsSet (opcode, 10);
6987                 add = BitIsSet (opcode, 9);
6988                 wback = BitIsSet (opcode, 8);
6989 
6990                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6991                   if (((t == 13) || ((t == 15)
6992                                      && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8))))
6993                       || (wback && (n == t)))
6994                     return false;
6995 
6996                 break;
6997 
6998             case eEncodingA1:
6999             {
7000                 // if Rn == '1111' then SEE LDRSB (literal);
7001                 // if P == '0' && W == '1' then SEE LDRSBT;
7002                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7003                 t = Bits32 (opcode, 15, 12);
7004                 n = Bits32 (opcode, 19, 16);
7005 
7006                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7007                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7008                 imm32 = (imm4H << 4) | imm4L;
7009 
7010                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7011                 index = BitIsSet (opcode, 24);
7012                 add = BitIsSet (opcode, 23);
7013                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
7014 
7015                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7016                 if ((t == 15) || (wback && (n == t)))
7017                     return false;
7018 
7019                 break;
7020             }
7021 
7022             default:
7023                 return false;
7024         }
7025 
7026         uint64_t Rn = ReadCoreReg (n, &success);
7027         if (!success)
7028             return false;
7029 
7030         addr_t offset_addr;
7031         addr_t address;
7032 
7033         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7034         if (add)
7035             offset_addr = Rn + imm32;
7036         else
7037             offset_addr = Rn - imm32;
7038 
7039         // address = if index then offset_addr else R[n];
7040         if (index)
7041             address = offset_addr;
7042         else
7043             address = Rn;
7044 
7045         // R[t] = SignExtend(MemU[address,1], 32);
7046         RegisterInfo base_reg;
7047         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7048 
7049         EmulateInstruction::Context context;
7050         context.type = eContextRegisterLoad;
7051         context.SetRegisterPlusOffset (base_reg, address - Rn);
7052 
7053         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7054         if (!success)
7055             return false;
7056 
7057         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7058         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7059             return false;
7060 
7061         // if wback then R[n] = offset_addr;
7062         if (wback)
7063         {
7064             context.type = eContextAdjustBaseRegister;
7065             context.SetAddress (offset_addr);
7066             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7067                 return false;
7068         }
7069     }
7070 
7071     return true;
7072 }
7073 
7074 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
7075 // sign-extends it to form a 32-bit word, and writes tit to a register.
7076 bool
7077 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding)
7078 {
7079 #if 0
7080     if ConditionPassed() then
7081         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7082         base = Align(PC,4);
7083         address = if add then (base + imm32) else (base - imm32);
7084         R[t] = SignExtend(MemU[address,1], 32);
7085 #endif
7086 
7087     bool success = false;
7088 
7089     if (ConditionPassed(opcode))
7090     {
7091         uint32_t t;
7092         uint32_t imm32;
7093         bool add;
7094 
7095         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7096         switch (encoding)
7097         {
7098             case eEncodingT1:
7099                 // if Rt == '1111' then SEE PLI;
7100                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7101                 t = Bits32 (opcode, 15, 12);
7102                 imm32 = Bits32 (opcode, 11, 0);
7103                 add = BitIsSet (opcode, 23);
7104 
7105                 // if t == 13 then UNPREDICTABLE;
7106                 if (t == 13)
7107                     return false;
7108 
7109                 break;
7110 
7111             case eEncodingA1:
7112             {
7113                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7114                 t = Bits32 (opcode, 15, 12);
7115                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7116                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7117                 imm32 = (imm4H << 4) | imm4L;
7118                 add = BitIsSet (opcode, 23);
7119 
7120                 // if t == 15 then UNPREDICTABLE;
7121                 if (t == 15)
7122                     return false;
7123 
7124                 break;
7125             }
7126 
7127             default:
7128                 return false;
7129         }
7130 
7131         // base = Align(PC,4);
7132         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7133         if (!success)
7134             return false;
7135         uint64_t base = AlignPC (pc_value);
7136 
7137         // address = if add then (base + imm32) else (base - imm32);
7138         addr_t address;
7139         if (add)
7140             address = base + imm32;
7141         else
7142             address = base - imm32;
7143 
7144         // R[t] = SignExtend(MemU[address,1], 32);
7145         RegisterInfo base_reg;
7146         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7147 
7148         EmulateInstruction::Context context;
7149         context.type = eContextRegisterLoad;
7150         context.SetRegisterPlusOffset (base_reg, address - base);
7151 
7152         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7153         if (!success)
7154             return false;
7155 
7156         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7157         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7158             return false;
7159     }
7160     return true;
7161 }
7162 
7163 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from
7164 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7165 // shifted left by 0, 1, 2, or 3 bits.
7166 bool
7167 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding)
7168 {
7169 #if 0
7170     if ConditionPassed() then
7171         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7172         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7173         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7174         address = if index then offset_addr else R[n];
7175         R[t] = SignExtend(MemU[address,1], 32);
7176         if wback then R[n] = offset_addr;
7177 #endif
7178 
7179     bool success = false;
7180 
7181     if (ConditionPassed(opcode))
7182     {
7183         uint32_t t;
7184         uint32_t n;
7185         uint32_t m;
7186         bool index;
7187         bool add;
7188         bool wback;
7189         ARM_ShifterType shift_t;
7190         uint32_t shift_n;
7191 
7192         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7193         switch (encoding)
7194         {
7195             case eEncodingT1:
7196                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7197                 t = Bits32 (opcode, 2, 0);
7198                 n = Bits32 (opcode, 5, 3);
7199                 m = Bits32 (opcode, 8, 6);
7200 
7201                 // index = TRUE; add = TRUE; wback = FALSE;
7202                 index = true;
7203                 add = true;
7204                 wback = false;
7205 
7206                 // (shift_t, shift_n) = (SRType_LSL, 0);
7207                 shift_t = SRType_LSL;
7208                 shift_n = 0;
7209 
7210                 break;
7211 
7212             case eEncodingT2:
7213                 // if Rt == '1111' then SEE PLI;
7214                 // if Rn == '1111' then SEE LDRSB (literal);
7215                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7216                 t = Bits32 (opcode, 15, 12);
7217                 n = Bits32 (opcode, 19, 16);
7218                 m = Bits32 (opcode, 3, 0);
7219 
7220                 // index = TRUE; add = TRUE; wback = FALSE;
7221                 index = true;
7222                 add = true;
7223                 wback = false;
7224 
7225                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7226                 shift_t = SRType_LSL;
7227                 shift_n = Bits32 (opcode, 5, 4);
7228 
7229                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7230                 if ((t == 13) || BadReg (m))
7231                     return false;
7232                 break;
7233 
7234             case eEncodingA1:
7235                 // if P == '0' && W == '1' then SEE LDRSBT;
7236                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7237                 t = Bits32 (opcode, 15, 12);
7238                 n = Bits32 (opcode, 19, 16);
7239                 m = Bits32 (opcode, 3, 0);
7240 
7241                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7242                 index = BitIsSet (opcode, 24);
7243                 add = BitIsSet (opcode, 23);
7244                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7245 
7246                 // (shift_t, shift_n) = (SRType_LSL, 0);
7247                 shift_t = SRType_LSL;
7248                 shift_n = 0;
7249 
7250                 // if t == 15 || m == 15 then UNPREDICTABLE;
7251                 if ((t == 15) || (m == 15))
7252                     return false;
7253 
7254                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7255                 if (wback && ((n == 15) || (n == t)))
7256                     return false;
7257                 break;
7258 
7259             default:
7260                 return false;
7261         }
7262 
7263         uint64_t Rm =  ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7264         if (!success)
7265             return false;
7266 
7267         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7268         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7269         if (!success)
7270             return false;
7271 
7272         addr_t offset_addr;
7273         addr_t address;
7274 
7275         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7276         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7277         if (!success)
7278             return false;
7279 
7280         if (add)
7281             offset_addr = Rn + offset;
7282         else
7283             offset_addr = Rn - offset;
7284 
7285         // address = if index then offset_addr else R[n];
7286         if (index)
7287             address = offset_addr;
7288         else
7289             address = Rn;
7290 
7291         // R[t] = SignExtend(MemU[address,1], 32);
7292         RegisterInfo base_reg;
7293         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7294         RegisterInfo offset_reg;
7295         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7296 
7297         EmulateInstruction::Context context;
7298         context.type = eContextRegisterLoad;
7299         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7300 
7301         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7302         if (!success)
7303             return false;
7304 
7305         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7306         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7307             return false;
7308 
7309         // if wback then R[n] = offset_addr;
7310         if (wback)
7311         {
7312             context.type = eContextAdjustBaseRegister;
7313             context.SetAddress (offset_addr);
7314             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7315                 return false;
7316         }
7317     }
7318     return true;
7319 }
7320 
7321 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from
7322 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed, or
7323 // pre-indexed addressing.
7324 bool
7325 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding)
7326 {
7327 #if 0
7328     if ConditionPassed() then
7329         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7330         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7331         address = if index then offset_addr else R[n];
7332         data = MemU[address,2];
7333         if wback then R[n] = offset_addr;
7334         if UnalignedSupport() || address<0> = '0' then
7335             R[t] = SignExtend(data, 32);
7336         else // Can only apply before ARMv7
7337             R[t] = bits(32) UNKNOWN;
7338 #endif
7339 
7340     bool success = false;
7341 
7342     if (ConditionPassed(opcode))
7343     {
7344         uint32_t t;
7345         uint32_t n;
7346         uint32_t imm32;
7347         bool index;
7348         bool add;
7349         bool wback;
7350 
7351         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7352         switch (encoding)
7353         {
7354             case eEncodingT1:
7355                 // if Rn == '1111' then SEE LDRSH (literal);
7356                 // if Rt == '1111' then SEE "Unallocated memory hints";
7357                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7358                 t = Bits32 (opcode, 15, 12);
7359                 n = Bits32 (opcode, 19, 16);
7360                 imm32 = Bits32 (opcode, 11, 0);
7361 
7362                 // index = TRUE; add = TRUE; wback = FALSE;
7363                 index = true;
7364                 add = true;
7365                 wback = false;
7366 
7367                 // if t == 13 then UNPREDICTABLE;
7368                 if (t == 13)
7369                     return false;
7370 
7371                 break;
7372 
7373             case eEncodingT2:
7374                 // if Rn == '1111' then SEE LDRSH (literal);
7375                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
7376                 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7377                 // if P == '0' && W == '0' then UNDEFINED;
7378                   if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7379                   return false;
7380 
7381                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7382                 t = Bits32 (opcode, 15, 12);
7383                 n = Bits32 (opcode, 19, 16);
7384                 imm32 = Bits32 (opcode, 7, 0);
7385 
7386                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7387                 index = BitIsSet (opcode, 10);
7388                 add = BitIsSet (opcode, 9);
7389                 wback = BitIsSet (opcode, 8);
7390 
7391                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7392                 if (BadReg (t) || (wback && (n == t)))
7393                     return false;
7394 
7395                 break;
7396 
7397             case eEncodingA1:
7398             {
7399                 // if Rn == '1111' then SEE LDRSH (literal);
7400                 // if P == '0' && W == '1' then SEE LDRSHT;
7401                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7402                 t = Bits32 (opcode, 15, 12);
7403                 n = Bits32 (opcode, 19, 16);
7404                 uint32_t imm4H = Bits32 (opcode, 11,8);
7405                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7406                 imm32 = (imm4H << 4) | imm4L;
7407 
7408                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7409                 index = BitIsSet (opcode, 24);
7410                 add = BitIsSet (opcode, 23);
7411                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7412 
7413                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7414                 if ((t == 15) || (wback && (n == t)))
7415                     return false;
7416 
7417                 break;
7418             }
7419 
7420             default:
7421                 return false;
7422         }
7423 
7424         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7425         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7426         if (!success)
7427             return false;
7428 
7429         addr_t offset_addr;
7430         if (add)
7431             offset_addr = Rn + imm32;
7432         else
7433             offset_addr = Rn - imm32;
7434 
7435         // address = if index then offset_addr else R[n];
7436         addr_t address;
7437         if (index)
7438             address = offset_addr;
7439         else
7440             address = Rn;
7441 
7442         // data = MemU[address,2];
7443         RegisterInfo base_reg;
7444         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7445 
7446         EmulateInstruction::Context context;
7447         context.type = eContextRegisterLoad;
7448         context.SetRegisterPlusOffset (base_reg, address - Rn);
7449 
7450         uint64_t data = MemURead (context, address, 2, 0, &success);
7451         if (!success)
7452             return false;
7453 
7454         // if wback then R[n] = offset_addr;
7455         if (wback)
7456         {
7457             context.type = eContextAdjustBaseRegister;
7458             context.SetAddress (offset_addr);
7459             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7460                 return false;
7461         }
7462 
7463         // if UnalignedSupport() || address<0> = '0' then
7464         if (UnalignedSupport() || BitIsClear (address, 0))
7465         {
7466             // R[t] = SignExtend(data, 32);
7467             int64_t signed_data = llvm::SignExtend64<16>(data);
7468             context.type = eContextRegisterLoad;
7469             context.SetRegisterPlusOffset (base_reg, address - Rn);
7470             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7471                 return false;
7472         }
7473         else // Can only apply before ARMv7
7474         {
7475             // R[t] = bits(32) UNKNOWN;
7476             WriteBits32Unknown (t);
7477         }
7478     }
7479     return true;
7480 }
7481 
7482 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory,
7483 // sign-extends it to from a 32-bit word, and writes it to a register.
7484 bool
7485 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding)
7486 {
7487 #if 0
7488     if ConditionPassed() then
7489         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7490         base = Align(PC,4);
7491         address = if add then (base + imm32) else (base - imm32);
7492         data = MemU[address,2];
7493         if UnalignedSupport() || address<0> = '0' then
7494             R[t] = SignExtend(data, 32);
7495         else // Can only apply before ARMv7
7496             R[t] = bits(32) UNKNOWN;
7497 #endif
7498 
7499     bool success = false;
7500 
7501     if (ConditionPassed(opcode))
7502     {
7503         uint32_t t;
7504         uint32_t imm32;
7505         bool add;
7506 
7507         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7508         switch (encoding)
7509         {
7510             case eEncodingT1:
7511                 // if Rt == '1111' then SEE "Unallocated memory hints";
7512                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7513                 t = Bits32  (opcode, 15, 12);
7514                 imm32 = Bits32 (opcode, 11, 0);
7515                 add = BitIsSet (opcode, 23);
7516 
7517                 // if t == 13 then UNPREDICTABLE;
7518                 if (t == 13)
7519                     return false;
7520 
7521                 break;
7522 
7523             case eEncodingA1:
7524             {
7525                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7526                 t = Bits32 (opcode, 15, 12);
7527                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7528                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7529                 imm32 = (imm4H << 4) | imm4L;
7530                 add = BitIsSet (opcode, 23);
7531 
7532                 // if t == 15 then UNPREDICTABLE;
7533                 if (t == 15)
7534                     return false;
7535 
7536                 break;
7537             }
7538             default:
7539                 return false;
7540         }
7541 
7542         // base = Align(PC,4);
7543         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7544         if (!success)
7545             return false;
7546 
7547         uint64_t base = AlignPC (pc_value);
7548 
7549         addr_t address;
7550         // address = if add then (base + imm32) else (base - imm32);
7551         if (add)
7552             address = base + imm32;
7553         else
7554             address = base - imm32;
7555 
7556         // data = MemU[address,2];
7557         RegisterInfo base_reg;
7558         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7559 
7560         EmulateInstruction::Context context;
7561         context.type = eContextRegisterLoad;
7562         context.SetRegisterPlusOffset (base_reg, imm32);
7563 
7564         uint64_t data = MemURead (context, address, 2, 0, &success);
7565         if (!success)
7566             return false;
7567 
7568         // if UnalignedSupport() || address<0> = '0' then
7569         if (UnalignedSupport() || BitIsClear (address, 0))
7570         {
7571             // R[t] = SignExtend(data, 32);
7572             int64_t signed_data = llvm::SignExtend64<16>(data);
7573             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7574                 return false;
7575         }
7576         else // Can only apply before ARMv7
7577         {
7578             // R[t] = bits(32) UNKNOWN;
7579             WriteBits32Unknown (t);
7580         }
7581     }
7582     return true;
7583 }
7584 
7585 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword
7586 // from memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7587 // shifted left by 0, 1, 2, or 3 bits.
7588 bool
7589 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding)
7590 {
7591 #if 0
7592     if ConditionPassed() then
7593         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7594         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7595         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7596         address = if index then offset_addr else R[n];
7597         data = MemU[address,2];
7598         if wback then R[n] = offset_addr;
7599         if UnalignedSupport() || address<0> = '0' then
7600             R[t] = SignExtend(data, 32);
7601         else // Can only apply before ARMv7
7602             R[t] = bits(32) UNKNOWN;
7603 #endif
7604 
7605     bool success = false;
7606 
7607     if (ConditionPassed(opcode))
7608     {
7609         uint32_t t;
7610         uint32_t n;
7611         uint32_t m;
7612         bool index;
7613         bool add;
7614         bool wback;
7615         ARM_ShifterType shift_t;
7616         uint32_t shift_n;
7617 
7618         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7619         switch (encoding)
7620         {
7621             case eEncodingT1:
7622                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
7623                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7624                 t = Bits32 (opcode, 2, 0);
7625                 n = Bits32 (opcode, 5, 3);
7626                 m = Bits32 (opcode, 8, 6);
7627 
7628                 // index = TRUE; add = TRUE; wback = FALSE;
7629                 index = true;
7630                 add = true;
7631                 wback = false;
7632 
7633                 // (shift_t, shift_n) = (SRType_LSL, 0);
7634                 shift_t = SRType_LSL;
7635                 shift_n = 0;
7636 
7637                 break;
7638 
7639             case eEncodingT2:
7640                 // if Rn == '1111' then SEE LDRSH (literal);
7641                 // if Rt == '1111' then SEE "Unallocated memory hints";
7642                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7643                 t = Bits32 (opcode, 15, 12);
7644                 n = Bits32 (opcode, 19, 16);
7645                 m = Bits32 (opcode, 3, 0);
7646 
7647                 // index = TRUE; add = TRUE; wback = FALSE;
7648                 index = true;
7649                 add = true;
7650                 wback = false;
7651 
7652                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7653                 shift_t = SRType_LSL;
7654                 shift_n = Bits32 (opcode, 5, 4);
7655 
7656                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7657                 if ((t == 13) || BadReg (m))
7658                     return false;
7659 
7660                 break;
7661 
7662             case eEncodingA1:
7663                 // if P == '0' && W == '1' then SEE LDRSHT;
7664                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7665                 t = Bits32 (opcode, 15, 12);
7666                 n = Bits32 (opcode, 19, 16);
7667                 m = Bits32 (opcode, 3, 0);
7668 
7669                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7670                 index = BitIsSet (opcode, 24);
7671                 add = BitIsSet (opcode, 23);
7672                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7673 
7674                 // (shift_t, shift_n) = (SRType_LSL, 0);
7675                 shift_t = SRType_LSL;
7676                 shift_n = 0;
7677 
7678                 // if t == 15 || m == 15 then UNPREDICTABLE;
7679                 if ((t == 15) || (m == 15))
7680                     return false;
7681 
7682                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7683                 if (wback && ((n == 15) || (n == t)))
7684                     return false;
7685 
7686                 break;
7687 
7688             default:
7689                 return false;
7690         }
7691 
7692         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7693         if (!success)
7694             return false;
7695 
7696         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7697         if (!success)
7698             return false;
7699 
7700         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7701         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7702         if (!success)
7703             return false;
7704 
7705         addr_t offset_addr;
7706         addr_t address;
7707 
7708         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7709         if (add)
7710             offset_addr = Rn + offset;
7711         else
7712             offset_addr = Rn - offset;
7713 
7714         // address = if index then offset_addr else R[n];
7715         if (index)
7716             address = offset_addr;
7717         else
7718             address = Rn;
7719 
7720         // data = MemU[address,2];
7721         RegisterInfo base_reg;
7722         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7723 
7724         RegisterInfo offset_reg;
7725         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7726 
7727         EmulateInstruction::Context context;
7728         context.type = eContextRegisterLoad;
7729         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7730 
7731         uint64_t data = MemURead (context, address, 2, 0, &success);
7732         if (!success)
7733             return false;
7734 
7735         // if wback then R[n] = offset_addr;
7736         if (wback)
7737         {
7738             context.type = eContextAdjustBaseRegister;
7739             context.SetAddress (offset_addr);
7740             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7741                 return false;
7742         }
7743 
7744         // if UnalignedSupport() || address<0> = '0' then
7745         if (UnalignedSupport() || BitIsClear (address, 0))
7746         {
7747             // R[t] = SignExtend(data, 32);
7748             context.type = eContextRegisterLoad;
7749             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7750 
7751             int64_t signed_data = llvm::SignExtend64<16>(data);
7752             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7753                 return false;
7754         }
7755         else // Can only apply before ARMv7
7756         {
7757             // R[t] = bits(32) UNKNOWN;
7758             WriteBits32Unknown (t);
7759         }
7760     }
7761     return true;
7762 }
7763 
7764 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7765 // register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7766 bool
7767 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding)
7768 {
7769 #if 0
7770     if ConditionPassed() then
7771         EncodingSpecificOperations();
7772         rotated = ROR(R[m], rotation);
7773         R[d] = SignExtend(rotated<7:0>, 32);
7774 #endif
7775 
7776     bool success = false;
7777 
7778     if (ConditionPassed(opcode))
7779     {
7780         uint32_t d;
7781         uint32_t m;
7782         uint32_t rotation;
7783 
7784         // EncodingSpecificOperations();
7785         switch (encoding)
7786         {
7787             case eEncodingT1:
7788                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7789                 d = Bits32 (opcode, 2, 0);
7790                 m = Bits32 (opcode, 5, 3);
7791                 rotation = 0;
7792 
7793                 break;
7794 
7795             case eEncodingT2:
7796                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7797                 d = Bits32 (opcode, 11, 8);
7798                 m = Bits32 (opcode, 3, 0);
7799                 rotation = Bits32 (opcode, 5, 4) << 3;
7800 
7801                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7802                 if (BadReg (d) || BadReg (m))
7803                     return false;
7804 
7805                 break;
7806 
7807             case eEncodingA1:
7808                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7809                 d = Bits32 (opcode, 15, 12);
7810                 m = Bits32 (opcode, 3, 0);
7811                 rotation = Bits32 (opcode, 11, 10) << 3;
7812 
7813                 // if d == 15 || m == 15 then UNPREDICTABLE;
7814                 if ((d == 15) || (m == 15))
7815                     return false;
7816 
7817                 break;
7818 
7819             default:
7820                 return false;
7821         }
7822 
7823         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7824         if (!success)
7825             return false;
7826 
7827         // rotated = ROR(R[m], rotation);
7828         uint64_t rotated = ROR (Rm, rotation, &success);
7829         if (!success)
7830             return false;
7831 
7832         // R[d] = SignExtend(rotated<7:0>, 32);
7833         int64_t data = llvm::SignExtend64<8>(rotated);
7834 
7835         RegisterInfo source_reg;
7836         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7837 
7838         EmulateInstruction::Context context;
7839         context.type = eContextRegisterLoad;
7840         context.SetRegister (source_reg);
7841 
7842         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7843             return false;
7844     }
7845     return true;
7846 }
7847 
7848 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7849 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7850 bool
7851 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding)
7852 {
7853 #if 0
7854     if ConditionPassed() then
7855         EncodingSpecificOperations();
7856         rotated = ROR(R[m], rotation);
7857         R[d] = SignExtend(rotated<15:0>, 32);
7858 #endif
7859 
7860     bool success = false;
7861 
7862     if (ConditionPassed(opcode))
7863     {
7864         uint32_t d;
7865         uint32_t m;
7866         uint32_t rotation;
7867 
7868         // EncodingSpecificOperations();
7869         switch (encoding)
7870         {
7871             case eEncodingT1:
7872                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7873                 d = Bits32 (opcode, 2, 0);
7874                 m = Bits32 (opcode, 5, 3);
7875                 rotation = 0;
7876 
7877                 break;
7878 
7879             case eEncodingT2:
7880                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7881                 d = Bits32 (opcode, 11, 8);
7882                 m = Bits32 (opcode, 3, 0);
7883                 rotation = Bits32 (opcode, 5, 4) << 3;
7884 
7885                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7886                 if (BadReg (d) || BadReg (m))
7887                     return false;
7888 
7889                 break;
7890 
7891             case eEncodingA1:
7892                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7893                 d = Bits32 (opcode, 15, 12);
7894                 m = Bits32 (opcode, 3, 0);
7895                 rotation = Bits32 (opcode, 11, 10) << 3;
7896 
7897                 // if d == 15 || m == 15 then UNPREDICTABLE;
7898                 if ((d == 15) || (m == 15))
7899                     return false;
7900 
7901                 break;
7902 
7903             default:
7904                 return false;
7905         }
7906 
7907         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7908         if (!success)
7909             return false;
7910 
7911         // rotated = ROR(R[m], rotation);
7912         uint64_t rotated = ROR (Rm, rotation, &success);
7913         if (!success)
7914             return false;
7915 
7916         // R[d] = SignExtend(rotated<15:0>, 32);
7917         RegisterInfo source_reg;
7918         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7919 
7920         EmulateInstruction::Context context;
7921         context.type = eContextRegisterLoad;
7922         context.SetRegister (source_reg);
7923 
7924         int64_t data = llvm::SignExtend64<16> (rotated);
7925         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7926             return false;
7927     }
7928 
7929     return true;
7930 }
7931 
7932 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination
7933 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7934 bool
7935 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding)
7936 {
7937 #if 0
7938     if ConditionPassed() then
7939         EncodingSpecificOperations();
7940         rotated = ROR(R[m], rotation);
7941         R[d] = ZeroExtend(rotated<7:0>, 32);
7942 #endif
7943 
7944     bool success = false;
7945 
7946     if (ConditionPassed(opcode))
7947     {
7948         uint32_t d;
7949         uint32_t m;
7950         uint32_t rotation;
7951 
7952         // EncodingSpecificOperations();
7953         switch (encoding)
7954         {
7955             case eEncodingT1:
7956                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7957                 d = Bits32 (opcode, 2, 0);
7958                 m = Bits32 (opcode, 5, 3);
7959                 rotation = 0;
7960 
7961                 break;
7962 
7963             case eEncodingT2:
7964                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7965                 d = Bits32 (opcode, 11, 8);
7966                 m = Bits32 (opcode, 3, 0);
7967                   rotation = Bits32 (opcode, 5, 4) << 3;
7968 
7969                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7970                 if (BadReg (d) || BadReg (m))
7971                   return false;
7972 
7973                 break;
7974 
7975             case eEncodingA1:
7976                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7977                 d = Bits32 (opcode, 15, 12);
7978                 m = Bits32 (opcode, 3, 0);
7979                 rotation = Bits32 (opcode, 11, 10) << 3;
7980 
7981                 // if d == 15 || m == 15 then UNPREDICTABLE;
7982                 if ((d == 15) || (m == 15))
7983                     return false;
7984 
7985                 break;
7986 
7987             default:
7988                 return false;
7989         }
7990 
7991         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7992         if (!success)
7993             return false;
7994 
7995         // rotated = ROR(R[m], rotation);
7996         uint64_t rotated = ROR (Rm, rotation, &success);
7997         if (!success)
7998             return false;
7999 
8000         // R[d] = ZeroExtend(rotated<7:0>, 32);
8001         RegisterInfo source_reg;
8002         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8003 
8004         EmulateInstruction::Context context;
8005         context.type = eContextRegisterLoad;
8006         context.SetRegister (source_reg);
8007 
8008         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0)))
8009             return false;
8010     }
8011     return true;
8012 }
8013 
8014 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination
8015 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
8016 bool
8017 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding)
8018 {
8019 #if 0
8020     if ConditionPassed() then
8021         EncodingSpecificOperations();
8022         rotated = ROR(R[m], rotation);
8023         R[d] = ZeroExtend(rotated<15:0>, 32);
8024 #endif
8025 
8026     bool success = false;
8027 
8028     if (ConditionPassed(opcode))
8029     {
8030         uint32_t d;
8031         uint32_t m;
8032         uint32_t rotation;
8033 
8034         switch (encoding)
8035         {
8036             case eEncodingT1:
8037                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8038                 d = Bits32 (opcode, 2, 0);
8039                 m = Bits32 (opcode, 5, 3);
8040                 rotation = 0;
8041 
8042                 break;
8043 
8044             case eEncodingT2:
8045                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8046                 d = Bits32 (opcode, 11, 8);
8047                 m = Bits32 (opcode, 3, 0);
8048                 rotation = Bits32 (opcode, 5, 4) << 3;
8049 
8050                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8051                 if (BadReg (d) || BadReg (m))
8052                   return false;
8053 
8054                 break;
8055 
8056             case eEncodingA1:
8057                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8058                 d = Bits32 (opcode, 15, 12);
8059                 m = Bits32 (opcode, 3, 0);
8060                 rotation = Bits32 (opcode, 11, 10) << 3;
8061 
8062                 // if d == 15 || m == 15 then UNPREDICTABLE;
8063                 if ((d == 15) || (m == 15))
8064                     return false;
8065 
8066                 break;
8067 
8068             default:
8069                 return false;
8070         }
8071 
8072         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8073         if (!success)
8074             return false;
8075 
8076         // rotated = ROR(R[m], rotation);
8077         uint64_t rotated = ROR (Rm, rotation, &success);
8078         if (!success)
8079             return false;
8080 
8081         // R[d] = ZeroExtend(rotated<15:0>, 32);
8082         RegisterInfo source_reg;
8083         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8084 
8085         EmulateInstruction::Context context;
8086         context.type = eContextRegisterLoad;
8087         context.SetRegister (source_reg);
8088 
8089         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0)))
8090             return false;
8091     }
8092     return true;
8093 }
8094 
8095 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following
8096 // word respectively.
8097 bool
8098 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding)
8099 {
8100 #if 0
8101     if ConditionPassed() then
8102         EncodingSpecificOperations();
8103         if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8104             UNPREDICTABLE;
8105         else
8106             address = if increment then R[n] else R[n]-8;
8107             if wordhigher then address = address+4;
8108             CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8109             BranchWritePC(MemA[address,4]);
8110             if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8111 #endif
8112 
8113     bool success = false;
8114 
8115     if (ConditionPassed(opcode))
8116     {
8117         uint32_t n;
8118         bool wback;
8119         bool increment;
8120         bool wordhigher;
8121 
8122         // EncodingSpecificOperations();
8123         switch (encoding)
8124         {
8125             case eEncodingT1:
8126                 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE;
8127                 n = Bits32 (opcode, 19, 16);
8128                 wback = BitIsSet (opcode, 21);
8129                 increment = false;
8130                 wordhigher = false;
8131 
8132                 // if n == 15 then UNPREDICTABLE;
8133                 if (n == 15)
8134                     return false;
8135 
8136                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8137                 if (InITBlock() && !LastInITBlock())
8138                     return false;
8139 
8140                 break;
8141 
8142             case eEncodingT2:
8143                 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8144                 n = Bits32 (opcode, 19, 16);
8145                 wback = BitIsSet (opcode, 21);
8146                 increment = true;
8147                 wordhigher = false;
8148 
8149                 // if n == 15 then UNPREDICTABLE;
8150                 if (n == 15)
8151                     return false;
8152 
8153                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8154                 if (InITBlock() && !LastInITBlock())
8155                     return false;
8156 
8157                 break;
8158 
8159             case eEncodingA1:
8160                 // n = UInt(Rn);
8161                 n = Bits32 (opcode, 19, 16);
8162 
8163                 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8164                 wback = BitIsSet (opcode, 21);
8165                 increment = BitIsSet (opcode, 23);
8166                 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23));
8167 
8168                 // if n == 15 then UNPREDICTABLE;
8169                 if (n == 15)
8170                     return false;
8171 
8172                 break;
8173 
8174             default:
8175                 return false;
8176         }
8177 
8178         // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8179         if (!CurrentModeIsPrivileged ())
8180             // UNPREDICTABLE;
8181             return false;
8182         else
8183         {
8184             uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8185             if (!success)
8186                 return false;
8187 
8188             addr_t address;
8189             // address = if increment then R[n] else R[n]-8;
8190             if (increment)
8191                 address = Rn;
8192             else
8193                 address = Rn - 8;
8194 
8195             // if wordhigher then address = address+4;
8196             if (wordhigher)
8197                 address = address + 4;
8198 
8199             // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8200             RegisterInfo base_reg;
8201             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8202 
8203             EmulateInstruction::Context context;
8204             context.type = eContextReturnFromException;
8205             context.SetRegisterPlusOffset (base_reg, address - Rn);
8206 
8207             uint64_t data = MemARead (context, address + 4, 4, 0, &success);
8208             if (!success)
8209                 return false;
8210 
8211             CPSRWriteByInstr (data, 15, true);
8212 
8213             // BranchWritePC(MemA[address,4]);
8214             uint64_t data2 = MemARead (context, address, 4, 0, &success);
8215             if (!success)
8216                 return false;
8217 
8218             BranchWritePC (context, data2);
8219 
8220             // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8221             if (wback)
8222             {
8223                 context.type = eContextAdjustBaseRegister;
8224                 if (increment)
8225                 {
8226                     context.SetOffset (8);
8227                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8))
8228                         return false;
8229                 }
8230                 else
8231                 {
8232                     context.SetOffset (-8);
8233                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8))
8234                         return false;
8235                 }
8236             } // if wback
8237         }
8238     } // if ConditionPassed()
8239     return true;
8240 }
8241 
8242 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
8243 // and writes the result to the destination register.  It can optionally update the condition flags based on
8244 // the result.
8245 bool
8246 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding)
8247 {
8248 #if 0
8249     // ARM pseudo code...
8250     if ConditionPassed() then
8251         EncodingSpecificOperations();
8252         result = R[n] EOR imm32;
8253         if d == 15 then         // Can only occur for ARM encoding
8254             ALUWritePC(result); // setflags is always FALSE here
8255         else
8256             R[d] = result;
8257             if setflags then
8258                 APSR.N = result<31>;
8259                 APSR.Z = IsZeroBit(result);
8260                 APSR.C = carry;
8261                 // APSR.V unchanged
8262 #endif
8263 
8264     bool success = false;
8265 
8266     if (ConditionPassed(opcode))
8267     {
8268         uint32_t Rd, Rn;
8269         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8270         bool setflags;
8271         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8272         switch (encoding)
8273         {
8274         case eEncodingT1:
8275             Rd = Bits32(opcode, 11, 8);
8276             Rn = Bits32(opcode, 19, 16);
8277             setflags = BitIsSet(opcode, 20);
8278             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8279             // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8280             if (Rd == 15 && setflags)
8281                 return EmulateTEQImm (opcode, eEncodingT1);
8282             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8283                 return false;
8284             break;
8285         case eEncodingA1:
8286             Rd = Bits32(opcode, 15, 12);
8287             Rn = Bits32(opcode, 19, 16);
8288             setflags = BitIsSet(opcode, 20);
8289             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8290 
8291             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8292             if (Rd == 15 && setflags)
8293                 return EmulateSUBSPcLrEtc (opcode, encoding);
8294             break;
8295         default:
8296             return false;
8297         }
8298 
8299         // Read the first operand.
8300         uint32_t val1 = ReadCoreReg(Rn, &success);
8301         if (!success)
8302             return false;
8303 
8304         uint32_t result = val1 ^ imm32;
8305 
8306         EmulateInstruction::Context context;
8307         context.type = EmulateInstruction::eContextImmediate;
8308         context.SetNoArgs ();
8309 
8310         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8311             return false;
8312     }
8313     return true;
8314 }
8315 
8316 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an
8317 // optionally-shifted register value, and writes the result to the destination register.
8318 // It can optionally update the condition flags based on the result.
8319 bool
8320 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding)
8321 {
8322 #if 0
8323     // ARM pseudo code...
8324     if ConditionPassed() then
8325         EncodingSpecificOperations();
8326         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8327         result = R[n] EOR shifted;
8328         if d == 15 then         // Can only occur for ARM encoding
8329             ALUWritePC(result); // setflags is always FALSE here
8330         else
8331             R[d] = result;
8332             if setflags then
8333                 APSR.N = result<31>;
8334                 APSR.Z = IsZeroBit(result);
8335                 APSR.C = carry;
8336                 // APSR.V unchanged
8337 #endif
8338 
8339     bool success = false;
8340 
8341     if (ConditionPassed(opcode))
8342     {
8343         uint32_t Rd, Rn, Rm;
8344         ARM_ShifterType shift_t;
8345         uint32_t shift_n; // the shift applied to the value read from Rm
8346         bool setflags;
8347         uint32_t carry;
8348         switch (encoding)
8349         {
8350         case eEncodingT1:
8351             Rd = Rn = Bits32(opcode, 2, 0);
8352             Rm = Bits32(opcode, 5, 3);
8353             setflags = !InITBlock();
8354             shift_t = SRType_LSL;
8355             shift_n = 0;
8356             break;
8357         case eEncodingT2:
8358             Rd = Bits32(opcode, 11, 8);
8359             Rn = Bits32(opcode, 19, 16);
8360             Rm = Bits32(opcode, 3, 0);
8361             setflags = BitIsSet(opcode, 20);
8362             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8363             // if Rd == '1111' && S == '1' then SEE TEQ (register);
8364             if (Rd == 15 && setflags)
8365                 return EmulateTEQReg (opcode, eEncodingT1);
8366             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8367                 return false;
8368             break;
8369         case eEncodingA1:
8370             Rd = Bits32(opcode, 15, 12);
8371             Rn = Bits32(opcode, 19, 16);
8372             Rm = Bits32(opcode, 3, 0);
8373             setflags = BitIsSet(opcode, 20);
8374             shift_n = DecodeImmShiftARM(opcode, shift_t);
8375 
8376             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8377             if (Rd == 15 && setflags)
8378                 return EmulateSUBSPcLrEtc (opcode, encoding);
8379             break;
8380         default:
8381             return false;
8382         }
8383 
8384         // Read the first operand.
8385         uint32_t val1 = ReadCoreReg(Rn, &success);
8386         if (!success)
8387             return false;
8388 
8389         // Read the second operand.
8390         uint32_t val2 = ReadCoreReg(Rm, &success);
8391         if (!success)
8392             return false;
8393 
8394         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8395         if (!success)
8396             return false;
8397         uint32_t result = val1 ^ shifted;
8398 
8399         EmulateInstruction::Context context;
8400         context.type = EmulateInstruction::eContextImmediate;
8401         context.SetNoArgs ();
8402 
8403         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8404             return false;
8405     }
8406     return true;
8407 }
8408 
8409 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and
8410 // writes the result to the destination register.  It can optionally update the condition flags based
8411 // on the result.
8412 bool
8413 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding)
8414 {
8415 #if 0
8416     // ARM pseudo code...
8417     if ConditionPassed() then
8418         EncodingSpecificOperations();
8419         result = R[n] OR imm32;
8420         if d == 15 then         // Can only occur for ARM encoding
8421             ALUWritePC(result); // setflags is always FALSE here
8422         else
8423             R[d] = result;
8424             if setflags then
8425                 APSR.N = result<31>;
8426                 APSR.Z = IsZeroBit(result);
8427                 APSR.C = carry;
8428                 // APSR.V unchanged
8429 #endif
8430 
8431     bool success = false;
8432 
8433     if (ConditionPassed(opcode))
8434     {
8435         uint32_t Rd, Rn;
8436         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8437         bool setflags;
8438         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8439         switch (encoding)
8440         {
8441         case eEncodingT1:
8442             Rd = Bits32(opcode, 11, 8);
8443             Rn = Bits32(opcode, 19, 16);
8444             setflags = BitIsSet(opcode, 20);
8445             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8446             // if Rn == '1111' then SEE MOV (immediate);
8447             if (Rn == 15)
8448                 return EmulateMOVRdImm (opcode, eEncodingT2);
8449             if (BadReg(Rd) || Rn == 13)
8450                 return false;
8451             break;
8452         case eEncodingA1:
8453             Rd = Bits32(opcode, 15, 12);
8454             Rn = Bits32(opcode, 19, 16);
8455             setflags = BitIsSet(opcode, 20);
8456             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8457 
8458             if (Rd == 15 && setflags)
8459                 return EmulateSUBSPcLrEtc (opcode, encoding);
8460             break;
8461         default:
8462             return false;
8463         }
8464 
8465         // Read the first operand.
8466         uint32_t val1 = ReadCoreReg(Rn, &success);
8467         if (!success)
8468             return false;
8469 
8470         uint32_t result = val1 | imm32;
8471 
8472         EmulateInstruction::Context context;
8473         context.type = EmulateInstruction::eContextImmediate;
8474         context.SetNoArgs ();
8475 
8476         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8477             return false;
8478     }
8479     return true;
8480 }
8481 
8482 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register
8483 // value, and writes the result to the destination register.  It can optionally update the condition flags based
8484 // on the result.
8485 bool
8486 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding)
8487 {
8488 #if 0
8489     // ARM pseudo code...
8490     if ConditionPassed() then
8491         EncodingSpecificOperations();
8492         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8493         result = R[n] OR shifted;
8494         if d == 15 then         // Can only occur for ARM encoding
8495             ALUWritePC(result); // setflags is always FALSE here
8496         else
8497             R[d] = result;
8498             if setflags then
8499                 APSR.N = result<31>;
8500                 APSR.Z = IsZeroBit(result);
8501                 APSR.C = carry;
8502                 // APSR.V unchanged
8503 #endif
8504 
8505     bool success = false;
8506 
8507     if (ConditionPassed(opcode))
8508     {
8509         uint32_t Rd, Rn, Rm;
8510         ARM_ShifterType shift_t;
8511         uint32_t shift_n; // the shift applied to the value read from Rm
8512         bool setflags;
8513         uint32_t carry;
8514         switch (encoding)
8515         {
8516         case eEncodingT1:
8517             Rd = Rn = Bits32(opcode, 2, 0);
8518             Rm = Bits32(opcode, 5, 3);
8519             setflags = !InITBlock();
8520             shift_t = SRType_LSL;
8521             shift_n = 0;
8522             break;
8523         case eEncodingT2:
8524             Rd = Bits32(opcode, 11, 8);
8525             Rn = Bits32(opcode, 19, 16);
8526             Rm = Bits32(opcode, 3, 0);
8527             setflags = BitIsSet(opcode, 20);
8528             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8529             // if Rn == '1111' then SEE MOV (register);
8530             if (Rn == 15)
8531                 return EmulateMOVRdRm (opcode, eEncodingT3);
8532             if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
8533                 return false;
8534             break;
8535         case eEncodingA1:
8536             Rd = Bits32(opcode, 15, 12);
8537             Rn = Bits32(opcode, 19, 16);
8538             Rm = Bits32(opcode, 3, 0);
8539             setflags = BitIsSet(opcode, 20);
8540             shift_n = DecodeImmShiftARM(opcode, shift_t);
8541 
8542             if (Rd == 15 && setflags)
8543                 return EmulateSUBSPcLrEtc (opcode, encoding);
8544             break;
8545         default:
8546             return false;
8547         }
8548 
8549         // Read the first operand.
8550         uint32_t val1 = ReadCoreReg(Rn, &success);
8551         if (!success)
8552             return false;
8553 
8554         // Read the second operand.
8555         uint32_t val2 = ReadCoreReg(Rm, &success);
8556         if (!success)
8557             return false;
8558 
8559         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8560         if (!success)
8561             return false;
8562         uint32_t result = val1 | shifted;
8563 
8564         EmulateInstruction::Context context;
8565         context.type = EmulateInstruction::eContextImmediate;
8566         context.SetNoArgs ();
8567 
8568         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8569             return false;
8570     }
8571     return true;
8572 }
8573 
8574 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to
8575 // the destination register. It can optionally update the condition flags based on the result.
8576 bool
8577 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding)
8578 {
8579 #if 0
8580     // ARM pseudo code...
8581     if ConditionPassed() then
8582         EncodingSpecificOperations();
8583         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
8584         if d == 15 then         // Can only occur for ARM encoding
8585             ALUWritePC(result); // setflags is always FALSE here
8586         else
8587             R[d] = result;
8588             if setflags then
8589                 APSR.N = result<31>;
8590                 APSR.Z = IsZeroBit(result);
8591                 APSR.C = carry;
8592                 APSR.V = overflow;
8593 #endif
8594 
8595     bool success = false;
8596 
8597     uint32_t Rd; // the destination register
8598     uint32_t Rn; // the first operand
8599     bool setflags;
8600     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8601     switch (encoding) {
8602     case eEncodingT1:
8603         Rd = Bits32(opcode, 2, 0);
8604         Rn = Bits32(opcode, 5, 3);
8605         setflags = !InITBlock();
8606         imm32 = 0;
8607         break;
8608     case eEncodingT2:
8609         Rd = Bits32(opcode, 11, 8);
8610         Rn = Bits32(opcode, 19, 16);
8611         setflags = BitIsSet(opcode, 20);
8612         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8613         if (BadReg(Rd) || BadReg(Rn))
8614             return false;
8615         break;
8616     case eEncodingA1:
8617         Rd = Bits32(opcode, 15, 12);
8618         Rn = Bits32(opcode, 19, 16);
8619         setflags = BitIsSet(opcode, 20);
8620         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8621 
8622         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8623         if (Rd == 15 && setflags)
8624             return EmulateSUBSPcLrEtc (opcode, encoding);
8625         break;
8626     default:
8627         return false;
8628     }
8629     // Read the register value from the operand register Rn.
8630     uint32_t reg_val = ReadCoreReg(Rn, &success);
8631     if (!success)
8632         return false;
8633 
8634     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
8635 
8636     EmulateInstruction::Context context;
8637     context.type = EmulateInstruction::eContextImmediate;
8638     context.SetNoArgs ();
8639 
8640     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8641         return false;
8642 
8643     return true;
8644 }
8645 
8646 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the
8647 // result to the destination register. It can optionally update the condition flags based on the result.
8648 bool
8649 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding)
8650 {
8651 #if 0
8652     // ARM pseudo code...
8653     if ConditionPassed() then
8654         EncodingSpecificOperations();
8655         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8656         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
8657         if d == 15 then         // Can only occur for ARM encoding
8658             ALUWritePC(result); // setflags is always FALSE here
8659         else
8660             R[d] = result;
8661             if setflags then
8662                 APSR.N = result<31>;
8663                 APSR.Z = IsZeroBit(result);
8664                 APSR.C = carry;
8665                 APSR.V = overflow;
8666 #endif
8667 
8668     bool success = false;
8669 
8670     uint32_t Rd; // the destination register
8671     uint32_t Rn; // the first operand
8672     uint32_t Rm; // the second operand
8673     bool setflags;
8674     ARM_ShifterType shift_t;
8675     uint32_t shift_n; // the shift applied to the value read from Rm
8676     switch (encoding) {
8677     case eEncodingT1:
8678         Rd = Bits32(opcode, 11, 8);
8679         Rn = Bits32(opcode, 19, 16);
8680         Rm = Bits32(opcode, 3, 0);
8681         setflags = BitIsSet(opcode, 20);
8682         shift_n = DecodeImmShiftThumb(opcode, shift_t);
8683         // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
8684         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8685             return false;
8686         break;
8687     case eEncodingA1:
8688         Rd = Bits32(opcode, 15, 12);
8689         Rn = Bits32(opcode, 19, 16);
8690         Rm = Bits32(opcode, 3, 0);
8691         setflags = BitIsSet(opcode, 20);
8692         shift_n = DecodeImmShiftARM(opcode, shift_t);
8693 
8694         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8695         if (Rd == 15 && setflags)
8696             return EmulateSUBSPcLrEtc (opcode, encoding);
8697         break;
8698     default:
8699         return false;
8700     }
8701     // Read the register value from register Rn.
8702     uint32_t val1 = ReadCoreReg(Rn, &success);
8703     if (!success)
8704         return false;
8705 
8706     // Read the register value from register Rm.
8707     uint32_t val2 = ReadCoreReg(Rm, &success);
8708     if (!success)
8709         return false;
8710 
8711     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8712     if (!success)
8713         return false;
8714     AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
8715 
8716     EmulateInstruction::Context context;
8717     context.type = EmulateInstruction::eContextImmediate;
8718     context.SetNoArgs();
8719     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8720         return false;
8721 
8722     return true;
8723 }
8724 
8725 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from
8726 // an immediate value, and writes the result to the destination register. It can optionally update the condition
8727 // flags based on the result.
8728 bool
8729 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding)
8730 {
8731 #if 0
8732     // ARM pseudo code...
8733     if ConditionPassed() then
8734         EncodingSpecificOperations();
8735         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
8736         if d == 15 then
8737             ALUWritePC(result); // setflags is always FALSE here
8738         else
8739             R[d] = result;
8740             if setflags then
8741                 APSR.N = result<31>;
8742                 APSR.Z = IsZeroBit(result);
8743                 APSR.C = carry;
8744                 APSR.V = overflow;
8745 #endif
8746 
8747     bool success = false;
8748 
8749     uint32_t Rd; // the destination register
8750     uint32_t Rn; // the first operand
8751     bool setflags;
8752     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8753     switch (encoding) {
8754     case eEncodingA1:
8755         Rd = Bits32(opcode, 15, 12);
8756         Rn = Bits32(opcode, 19, 16);
8757         setflags = BitIsSet(opcode, 20);
8758         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8759 
8760         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8761         if (Rd == 15 && setflags)
8762             return EmulateSUBSPcLrEtc  (opcode, encoding);
8763         break;
8764     default:
8765         return false;
8766     }
8767     // Read the register value from the operand register Rn.
8768     uint32_t reg_val = ReadCoreReg(Rn, &success);
8769     if (!success)
8770         return false;
8771 
8772     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
8773 
8774     EmulateInstruction::Context context;
8775     context.type = EmulateInstruction::eContextImmediate;
8776     context.SetNoArgs ();
8777 
8778     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8779         return false;
8780 
8781     return true;
8782 }
8783 
8784 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an
8785 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the
8786 // condition flags based on the result.
8787 bool
8788 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding)
8789 {
8790 #if 0
8791     // ARM pseudo code...
8792     if ConditionPassed() then
8793         EncodingSpecificOperations();
8794         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8795         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
8796         if d == 15 then
8797             ALUWritePC(result); // setflags is always FALSE here
8798         else
8799             R[d] = result;
8800             if setflags then
8801                 APSR.N = result<31>;
8802                 APSR.Z = IsZeroBit(result);
8803                 APSR.C = carry;
8804                 APSR.V = overflow;
8805 #endif
8806 
8807     bool success = false;
8808 
8809     uint32_t Rd; // the destination register
8810     uint32_t Rn; // the first operand
8811     uint32_t Rm; // the second operand
8812     bool setflags;
8813     ARM_ShifterType shift_t;
8814     uint32_t shift_n; // the shift applied to the value read from Rm
8815     switch (encoding) {
8816     case eEncodingA1:
8817         Rd = Bits32(opcode, 15, 12);
8818         Rn = Bits32(opcode, 19, 16);
8819         Rm = Bits32(opcode, 3, 0);
8820         setflags = BitIsSet(opcode, 20);
8821         shift_n = DecodeImmShiftARM(opcode, shift_t);
8822 
8823         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8824         if (Rd == 15 && setflags)
8825             return EmulateSUBSPcLrEtc (opcode, encoding);
8826         break;
8827     default:
8828         return false;
8829     }
8830     // Read the register value from register Rn.
8831     uint32_t val1 = ReadCoreReg(Rn, &success);
8832     if (!success)
8833         return false;
8834 
8835     // Read the register value from register Rm.
8836     uint32_t val2 = ReadCoreReg(Rm, &success);
8837     if (!success)
8838         return false;
8839 
8840     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8841     if (!success)
8842         return false;
8843     AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
8844 
8845     EmulateInstruction::Context context;
8846     context.type = EmulateInstruction::eContextImmediate;
8847     context.SetNoArgs();
8848     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8849         return false;
8850 
8851     return true;
8852 }
8853 
8854 // Subtract with Carry (immediate) subtracts an immediate value and the value of
8855 // NOT (Carry flag) from a register value, and writes the result to the destination register.
8856 // It can optionally update the condition flags based on the result.
8857 bool
8858 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding)
8859 {
8860 #if 0
8861     // ARM pseudo code...
8862     if ConditionPassed() then
8863         EncodingSpecificOperations();
8864         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
8865         if d == 15 then         // Can only occur for ARM encoding
8866             ALUWritePC(result); // setflags is always FALSE here
8867         else
8868             R[d] = result;
8869             if setflags then
8870                 APSR.N = result<31>;
8871                 APSR.Z = IsZeroBit(result);
8872                 APSR.C = carry;
8873                 APSR.V = overflow;
8874 #endif
8875 
8876     bool success = false;
8877 
8878     uint32_t Rd; // the destination register
8879     uint32_t Rn; // the first operand
8880     bool setflags;
8881     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8882     switch (encoding) {
8883     case eEncodingT1:
8884         Rd = Bits32(opcode, 11, 8);
8885         Rn = Bits32(opcode, 19, 16);
8886         setflags = BitIsSet(opcode, 20);
8887         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8888         if (BadReg(Rd) || BadReg(Rn))
8889             return false;
8890         break;
8891     case eEncodingA1:
8892         Rd = Bits32(opcode, 15, 12);
8893         Rn = Bits32(opcode, 19, 16);
8894         setflags = BitIsSet(opcode, 20);
8895         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8896 
8897         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8898         if (Rd == 15 && setflags)
8899             return EmulateSUBSPcLrEtc (opcode, encoding);
8900         break;
8901     default:
8902         return false;
8903     }
8904     // Read the register value from the operand register Rn.
8905     uint32_t reg_val = ReadCoreReg(Rn, &success);
8906     if (!success)
8907         return false;
8908 
8909     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
8910 
8911     EmulateInstruction::Context context;
8912     context.type = EmulateInstruction::eContextImmediate;
8913     context.SetNoArgs ();
8914 
8915     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8916         return false;
8917 
8918     return true;
8919 }
8920 
8921 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of
8922 // NOT (Carry flag) from a register value, and writes the result to the destination register.
8923 // It can optionally update the condition flags based on the result.
8924 bool
8925 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding)
8926 {
8927 #if 0
8928     // ARM pseudo code...
8929     if ConditionPassed() then
8930         EncodingSpecificOperations();
8931         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8932         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
8933         if d == 15 then         // Can only occur for ARM encoding
8934             ALUWritePC(result); // setflags is always FALSE here
8935         else
8936             R[d] = result;
8937             if setflags then
8938                 APSR.N = result<31>;
8939                 APSR.Z = IsZeroBit(result);
8940                 APSR.C = carry;
8941                 APSR.V = overflow;
8942 #endif
8943 
8944     bool success = false;
8945 
8946     uint32_t Rd; // the destination register
8947     uint32_t Rn; // the first operand
8948     uint32_t Rm; // the second operand
8949     bool setflags;
8950     ARM_ShifterType shift_t;
8951     uint32_t shift_n; // the shift applied to the value read from Rm
8952     switch (encoding) {
8953     case eEncodingT1:
8954         Rd = Rn = Bits32(opcode, 2, 0);
8955         Rm = Bits32(opcode, 5, 3);
8956         setflags = !InITBlock();
8957         shift_t = SRType_LSL;
8958         shift_n = 0;
8959         break;
8960     case eEncodingT2:
8961         Rd = Bits32(opcode, 11, 8);
8962         Rn = Bits32(opcode, 19, 16);
8963         Rm = Bits32(opcode, 3, 0);
8964         setflags = BitIsSet(opcode, 20);
8965         shift_n = DecodeImmShiftThumb(opcode, shift_t);
8966         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8967             return false;
8968         break;
8969     case eEncodingA1:
8970         Rd = Bits32(opcode, 15, 12);
8971         Rn = Bits32(opcode, 19, 16);
8972         Rm = Bits32(opcode, 3, 0);
8973         setflags = BitIsSet(opcode, 20);
8974         shift_n = DecodeImmShiftARM(opcode, shift_t);
8975 
8976         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8977         if (Rd == 15 && setflags)
8978             return EmulateSUBSPcLrEtc (opcode, encoding);
8979         break;
8980     default:
8981         return false;
8982     }
8983     // Read the register value from register Rn.
8984     uint32_t val1 = ReadCoreReg(Rn, &success);
8985     if (!success)
8986         return false;
8987 
8988     // Read the register value from register Rm.
8989     uint32_t val2 = ReadCoreReg(Rm, &success);
8990     if (!success)
8991         return false;
8992 
8993     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8994     if (!success)
8995         return false;
8996     AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
8997 
8998     EmulateInstruction::Context context;
8999     context.type = EmulateInstruction::eContextImmediate;
9000     context.SetNoArgs();
9001     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9002         return false;
9003 
9004     return true;
9005 }
9006 
9007 // This instruction subtracts an immediate value from a register value, and writes the result
9008 // to the destination register.  It can optionally update the condition flags based on the result.
9009 bool
9010 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding)
9011 {
9012 #if 0
9013     // ARM pseudo code...
9014     if ConditionPassed() then
9015         EncodingSpecificOperations();
9016         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9017         R[d] = result;
9018         if setflags then
9019             APSR.N = result<31>;
9020             APSR.Z = IsZeroBit(result);
9021             APSR.C = carry;
9022             APSR.V = overflow;
9023 #endif
9024 
9025     bool success = false;
9026 
9027     uint32_t Rd; // the destination register
9028     uint32_t Rn; // the first operand
9029     bool setflags;
9030     uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9031     switch (encoding) {
9032     case eEncodingT1:
9033         Rd = Bits32(opcode, 2, 0);
9034         Rn = Bits32(opcode, 5, 3);
9035         setflags = !InITBlock();
9036         imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9037         break;
9038     case eEncodingT2:
9039         Rd = Rn = Bits32(opcode, 10, 8);
9040         setflags = !InITBlock();
9041         imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9042         break;
9043     case eEncodingT3:
9044         Rd = Bits32(opcode, 11, 8);
9045         Rn = Bits32(opcode, 19, 16);
9046         setflags = BitIsSet(opcode, 20);
9047         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9048 
9049         // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9050         if (Rd == 15 && setflags)
9051             return EmulateCMPImm (opcode, eEncodingT2);
9052 
9053         // if Rn == '1101' then SEE SUB (SP minus immediate);
9054         if (Rn == 13)
9055             return EmulateSUBSPImm (opcode, eEncodingT2);
9056 
9057         // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9058         if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9059             return false;
9060         break;
9061     case eEncodingT4:
9062         Rd = Bits32(opcode, 11, 8);
9063         Rn = Bits32(opcode, 19, 16);
9064         setflags = BitIsSet(opcode, 20);
9065         imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9066 
9067         // if Rn == '1111' then SEE ADR;
9068         if (Rn == 15)
9069             return EmulateADR (opcode, eEncodingT2);
9070 
9071         // if Rn == '1101' then SEE SUB (SP minus immediate);
9072         if (Rn == 13)
9073             return EmulateSUBSPImm (opcode, eEncodingT3);
9074 
9075         if (BadReg(Rd))
9076             return false;
9077         break;
9078     default:
9079         return false;
9080     }
9081     // Read the register value from the operand register Rn.
9082     uint32_t reg_val = ReadCoreReg(Rn, &success);
9083     if (!success)
9084         return false;
9085 
9086     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9087 
9088     EmulateInstruction::Context context;
9089     context.type = EmulateInstruction::eContextImmediate;
9090     context.SetNoArgs ();
9091 
9092     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9093         return false;
9094 
9095     return true;
9096 }
9097 
9098 // This instruction subtracts an immediate value from a register value, and writes the result
9099 // to the destination register.  It can optionally update the condition flags based on the result.
9100 bool
9101 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9102 {
9103 #if 0
9104     // ARM pseudo code...
9105     if ConditionPassed() then
9106         EncodingSpecificOperations();
9107         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9108         if d == 15 then
9109             ALUWritePC(result); // setflags is always FALSE here
9110         else
9111             R[d] = result;
9112             if setflags then
9113                 APSR.N = result<31>;
9114                 APSR.Z = IsZeroBit(result);
9115                 APSR.C = carry;
9116                 APSR.V = overflow;
9117 #endif
9118 
9119     bool success = false;
9120 
9121     uint32_t Rd; // the destination register
9122     uint32_t Rn; // the first operand
9123     bool setflags;
9124     uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9125     switch (encoding) {
9126     case eEncodingA1:
9127         Rd = Bits32(opcode, 15, 12);
9128         Rn = Bits32(opcode, 19, 16);
9129         setflags = BitIsSet(opcode, 20);
9130         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9131 
9132         // if Rn == '1111' && S == '0' then SEE ADR;
9133         if (Rn == 15 && !setflags)
9134             return EmulateADR (opcode, eEncodingA2);
9135 
9136         // if Rn == '1101' then SEE SUB (SP minus immediate);
9137         if (Rn == 13)
9138             return EmulateSUBSPImm (opcode, eEncodingA1);
9139 
9140         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9141         if (Rd == 15 && setflags)
9142             return EmulateSUBSPcLrEtc (opcode, encoding);
9143         break;
9144     default:
9145         return false;
9146     }
9147     // Read the register value from the operand register Rn.
9148     uint32_t reg_val = ReadCoreReg(Rn, &success);
9149     if (!success)
9150         return false;
9151 
9152     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9153 
9154     EmulateInstruction::Context context;
9155     context.type = EmulateInstruction::eContextImmediate;
9156     context.SetNoArgs ();
9157 
9158     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9159         return false;
9160 
9161     return true;
9162 }
9163 
9164 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an
9165 // immediate value.  It updates the condition flags based on the result, and discards the result.
9166 bool
9167 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding)
9168 {
9169 #if 0
9170     // ARM pseudo code...
9171     if ConditionPassed() then
9172         EncodingSpecificOperations();
9173         result = R[n] EOR imm32;
9174         APSR.N = result<31>;
9175         APSR.Z = IsZeroBit(result);
9176         APSR.C = carry;
9177         // APSR.V unchanged
9178 #endif
9179 
9180     bool success = false;
9181 
9182     if (ConditionPassed(opcode))
9183     {
9184         uint32_t Rn;
9185         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9186         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9187         switch (encoding)
9188         {
9189         case eEncodingT1:
9190             Rn = Bits32(opcode, 19, 16);
9191             imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9192             if (BadReg(Rn))
9193                 return false;
9194             break;
9195         case eEncodingA1:
9196             Rn = Bits32(opcode, 19, 16);
9197             imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9198             break;
9199         default:
9200             return false;
9201         }
9202 
9203         // Read the first operand.
9204         uint32_t val1 = ReadCoreReg(Rn, &success);
9205         if (!success)
9206             return false;
9207 
9208         uint32_t result = val1 ^ imm32;
9209 
9210         EmulateInstruction::Context context;
9211         context.type = EmulateInstruction::eContextImmediate;
9212         context.SetNoArgs ();
9213 
9214         if (!WriteFlags(context, result, carry))
9215             return false;
9216     }
9217     return true;
9218 }
9219 
9220 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an
9221 // optionally-shifted register value.  It updates the condition flags based on the result, and discards
9222 // the result.
9223 bool
9224 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding)
9225 {
9226 #if 0
9227     // ARM pseudo code...
9228     if ConditionPassed() then
9229         EncodingSpecificOperations();
9230         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9231         result = R[n] EOR shifted;
9232         APSR.N = result<31>;
9233         APSR.Z = IsZeroBit(result);
9234         APSR.C = carry;
9235         // APSR.V unchanged
9236 #endif
9237 
9238     bool success = false;
9239 
9240     if (ConditionPassed(opcode))
9241     {
9242         uint32_t Rn, Rm;
9243         ARM_ShifterType shift_t;
9244         uint32_t shift_n; // the shift applied to the value read from Rm
9245         uint32_t carry;
9246         switch (encoding)
9247         {
9248         case eEncodingT1:
9249             Rn = Bits32(opcode, 19, 16);
9250             Rm = Bits32(opcode, 3, 0);
9251             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9252             if (BadReg(Rn) || BadReg(Rm))
9253                 return false;
9254             break;
9255         case eEncodingA1:
9256             Rn = Bits32(opcode, 19, 16);
9257             Rm = Bits32(opcode, 3, 0);
9258             shift_n = DecodeImmShiftARM(opcode, shift_t);
9259             break;
9260         default:
9261             return false;
9262         }
9263 
9264         // Read the first operand.
9265         uint32_t val1 = ReadCoreReg(Rn, &success);
9266         if (!success)
9267             return false;
9268 
9269         // Read the second operand.
9270         uint32_t val2 = ReadCoreReg(Rm, &success);
9271         if (!success)
9272             return false;
9273 
9274         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9275         if (!success)
9276             return false;
9277         uint32_t result = val1 ^ shifted;
9278 
9279         EmulateInstruction::Context context;
9280         context.type = EmulateInstruction::eContextImmediate;
9281         context.SetNoArgs ();
9282 
9283         if (!WriteFlags(context, result, carry))
9284             return false;
9285     }
9286     return true;
9287 }
9288 
9289 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value.
9290 // It updates the condition flags based on the result, and discards the result.
9291 bool
9292 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding)
9293 {
9294 #if 0
9295     // ARM pseudo code...
9296     if ConditionPassed() then
9297         EncodingSpecificOperations();
9298         result = R[n] AND imm32;
9299         APSR.N = result<31>;
9300         APSR.Z = IsZeroBit(result);
9301         APSR.C = carry;
9302         // APSR.V unchanged
9303 #endif
9304 
9305     bool success = false;
9306 
9307     if (ConditionPassed(opcode))
9308     {
9309         uint32_t Rn;
9310         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9311         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9312         switch (encoding)
9313         {
9314         case eEncodingT1:
9315             Rn = Bits32(opcode, 19, 16);
9316             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9317             if (BadReg(Rn))
9318                 return false;
9319             break;
9320         case eEncodingA1:
9321             Rn = Bits32(opcode, 19, 16);
9322             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9323             break;
9324         default:
9325             return false;
9326         }
9327 
9328         // Read the first operand.
9329         uint32_t val1 = ReadCoreReg(Rn, &success);
9330         if (!success)
9331             return false;
9332 
9333         uint32_t result = val1 & imm32;
9334 
9335         EmulateInstruction::Context context;
9336         context.type = EmulateInstruction::eContextImmediate;
9337         context.SetNoArgs ();
9338 
9339         if (!WriteFlags(context, result, carry))
9340             return false;
9341     }
9342     return true;
9343 }
9344 
9345 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value.
9346 // It updates the condition flags based on the result, and discards the result.
9347 bool
9348 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding)
9349 {
9350 #if 0
9351     // ARM pseudo code...
9352     if ConditionPassed() then
9353         EncodingSpecificOperations();
9354         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9355         result = R[n] AND shifted;
9356         APSR.N = result<31>;
9357         APSR.Z = IsZeroBit(result);
9358         APSR.C = carry;
9359         // APSR.V unchanged
9360 #endif
9361 
9362     bool success = false;
9363 
9364     if (ConditionPassed(opcode))
9365     {
9366         uint32_t Rn, Rm;
9367         ARM_ShifterType shift_t;
9368         uint32_t shift_n; // the shift applied to the value read from Rm
9369         uint32_t carry;
9370         switch (encoding)
9371         {
9372         case eEncodingT1:
9373             Rn = Bits32(opcode, 2, 0);
9374             Rm = Bits32(opcode, 5, 3);
9375             shift_t = SRType_LSL;
9376             shift_n = 0;
9377             break;
9378         case eEncodingT2:
9379             Rn = Bits32(opcode, 19, 16);
9380             Rm = Bits32(opcode, 3, 0);
9381             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9382             if (BadReg(Rn) || BadReg(Rm))
9383                 return false;
9384             break;
9385         case eEncodingA1:
9386             Rn = Bits32(opcode, 19, 16);
9387             Rm = Bits32(opcode, 3, 0);
9388             shift_n = DecodeImmShiftARM(opcode, shift_t);
9389             break;
9390         default:
9391             return false;
9392         }
9393 
9394         // Read the first operand.
9395         uint32_t val1 = ReadCoreReg(Rn, &success);
9396         if (!success)
9397             return false;
9398 
9399         // Read the second operand.
9400         uint32_t val2 = ReadCoreReg(Rm, &success);
9401         if (!success)
9402             return false;
9403 
9404         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9405         if (!success)
9406             return false;
9407         uint32_t result = val1 & shifted;
9408 
9409         EmulateInstruction::Context context;
9410         context.type = EmulateInstruction::eContextImmediate;
9411         context.SetNoArgs ();
9412 
9413         if (!WriteFlags(context, result, carry))
9414             return false;
9415     }
9416     return true;
9417 }
9418 
9419 // A8.6.216 SUB (SP minus register)
9420 bool
9421 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding)
9422 {
9423 #if 0
9424     if ConditionPassed() then
9425         EncodingSpecificOperations();
9426         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9427         (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9428         if d == 15 then // Can only occur for ARM encoding
9429             ALUWritePC(result); // setflags is always FALSE here
9430         else
9431             R[d] = result;
9432             if setflags then
9433                 APSR.N = result<31>;
9434                 APSR.Z = IsZeroBit(result);
9435                 APSR.C = carry;
9436                 APSR.V = overflow;
9437 #endif
9438 
9439     bool success = false;
9440 
9441     if (ConditionPassed(opcode))
9442     {
9443         uint32_t d;
9444         uint32_t m;
9445         bool setflags;
9446         ARM_ShifterType shift_t;
9447         uint32_t shift_n;
9448 
9449         switch (encoding)
9450         {
9451             case eEncodingT1:
9452                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9453                 d = Bits32 (opcode, 11, 8);
9454                 m = Bits32 (opcode, 3, 0);
9455                 setflags = BitIsSet (opcode, 20);
9456 
9457                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9458                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9459 
9460                 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE;
9461                 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
9462                     return false;
9463 
9464                 // if d == 15 || BadReg(m) then UNPREDICTABLE;
9465                 if ((d == 15) || BadReg (m))
9466                     return false;
9467                 break;
9468 
9469             case eEncodingA1:
9470                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9471                 d = Bits32 (opcode, 15, 12);
9472                 m = Bits32 (opcode, 3, 0);
9473                 setflags = BitIsSet (opcode, 20);
9474 
9475                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9476                 if (d == 15 && setflags)
9477                     EmulateSUBSPcLrEtc (opcode, encoding);
9478 
9479                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9480                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9481                 break;
9482 
9483             default:
9484                 return false;
9485         }
9486 
9487         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9488         uint32_t Rm = ReadCoreReg (m, &success);
9489         if (!success)
9490             return false;
9491 
9492         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9493         if (!success)
9494             return false;
9495 
9496         // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9497         uint32_t sp_val = ReadCoreReg (SP_REG, &success);
9498         if (!success)
9499             return false;
9500 
9501         AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1);
9502 
9503         EmulateInstruction::Context context;
9504         context.type = eContextArithmetic;
9505         RegisterInfo sp_reg;
9506         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
9507         RegisterInfo dwarf_reg;
9508         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
9509         context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
9510 
9511         if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9512             return false;
9513     }
9514     return true;
9515 }
9516 
9517 
9518 // A8.6.7 ADD (register-shifted register)
9519 bool
9520 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding)
9521 {
9522 #if 0
9523     if ConditionPassed() then
9524         EncodingSpecificOperations();
9525         shift_n = UInt(R[s]<7:0>);
9526         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9527         (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9528         R[d] = result;
9529         if setflags then
9530             APSR.N = result<31>;
9531             APSR.Z = IsZeroBit(result);
9532             APSR.C = carry;
9533             APSR.V = overflow;
9534 #endif
9535 
9536     bool success = false;
9537 
9538     if (ConditionPassed(opcode))
9539     {
9540         uint32_t d;
9541         uint32_t n;
9542         uint32_t m;
9543         uint32_t s;
9544         bool setflags;
9545         ARM_ShifterType shift_t;
9546 
9547         switch (encoding)
9548         {
9549             case eEncodingA1:
9550                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
9551                 d = Bits32 (opcode, 15, 12);
9552                 n = Bits32 (opcode, 19, 16);
9553                 m = Bits32 (opcode, 3, 0);
9554                 s = Bits32 (opcode, 11, 8);
9555 
9556                 // setflags = (S == �1�); shift_t = DecodeRegShift(type);
9557                 setflags = BitIsSet (opcode, 20);
9558                 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5));
9559 
9560                 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
9561                 if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
9562                     return false;
9563                 break;
9564 
9565             default:
9566                 return false;
9567         }
9568 
9569         // shift_n = UInt(R[s]<7:0>);
9570         uint32_t Rs = ReadCoreReg (s, &success);
9571         if (!success)
9572             return false;
9573 
9574         uint32_t shift_n = Bits32 (Rs, 7, 0);
9575 
9576         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9577         uint32_t Rm = ReadCoreReg (m, &success);
9578         if (!success)
9579             return false;
9580 
9581         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9582         if (!success)
9583             return false;
9584 
9585         // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9586         uint32_t Rn = ReadCoreReg (n, &success);
9587         if (!success)
9588             return false;
9589 
9590         AddWithCarryResult res = AddWithCarry (Rn, shifted, 0);
9591 
9592         // R[d] = result;
9593         EmulateInstruction::Context context;
9594         context.type = eContextArithmetic;
9595         RegisterInfo reg_n;
9596         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9597         RegisterInfo reg_m;
9598         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9599 
9600         context.SetRegisterRegisterOperands (reg_n, reg_m);
9601 
9602         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result))
9603             return false;
9604 
9605         // if setflags then
9606             // APSR.N = result<31>;
9607             // APSR.Z = IsZeroBit(result);
9608             // APSR.C = carry;
9609             // APSR.V = overflow;
9610         if (setflags)
9611             return WriteFlags (context, res.result, res.carry_out, res.overflow);
9612     }
9613     return true;
9614 }
9615 
9616 // A8.6.213 SUB (register)
9617 bool
9618 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding)
9619 {
9620 #if 0
9621     if ConditionPassed() then
9622         EncodingSpecificOperations();
9623         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9624         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9625         if d == 15 then // Can only occur for ARM encoding
9626             ALUWritePC(result); // setflags is always FALSE here
9627         else
9628             R[d] = result;
9629             if setflags then
9630                 APSR.N = result<31>;
9631                 APSR.Z = IsZeroBit(result);
9632                 APSR.C = carry;
9633                 APSR.V = overflow;
9634 #endif
9635 
9636     bool success = false;
9637 
9638     if (ConditionPassed(opcode))
9639     {
9640         uint32_t d;
9641         uint32_t n;
9642         uint32_t m;
9643         bool setflags;
9644         ARM_ShifterType shift_t;
9645         uint32_t shift_n;
9646 
9647         switch (encoding)
9648         {
9649             case eEncodingT1:
9650                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
9651                 d = Bits32 (opcode, 2, 0);
9652                 n = Bits32 (opcode, 5, 3);
9653                 m = Bits32 (opcode, 8, 6);
9654                 setflags = !InITBlock();
9655 
9656                 // (shift_t, shift_n) = (SRType_LSL, 0);
9657                 shift_t = SRType_LSL;
9658                 shift_n = 0;
9659 
9660                 break;
9661 
9662             case eEncodingT2:
9663                 // if Rd == �1111� && S == �1� then SEE CMP (register);
9664                 // if Rn == �1101� then SEE SUB (SP minus register);
9665                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9666                 d = Bits32 (opcode, 11, 8);
9667                 n = Bits32 (opcode, 19, 16);
9668                 m = Bits32 (opcode, 3, 0);
9669                 setflags = BitIsSet (opcode, 20);
9670 
9671                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9672                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9673 
9674                 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE;
9675                 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m))
9676                     return false;
9677 
9678                 break;
9679 
9680             case eEncodingA1:
9681                 // if Rn == �1101� then SEE SUB (SP minus register);
9682                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9683                 d = Bits32 (opcode, 15, 12);
9684                 n = Bits32 (opcode, 19, 16);
9685                 m = Bits32 (opcode, 3, 0);
9686                 setflags = BitIsSet (opcode, 20);
9687 
9688                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9689                 if ((d == 15) && setflags)
9690                     EmulateSUBSPcLrEtc (opcode, encoding);
9691 
9692                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9693                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9694 
9695                 break;
9696 
9697             default:
9698                 return false;
9699         }
9700 
9701         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9702         uint32_t Rm = ReadCoreReg (m, &success);
9703         if (!success)
9704             return false;
9705 
9706         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9707         if (!success)
9708             return false;
9709 
9710         // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9711         uint32_t Rn = ReadCoreReg (n, &success);
9712         if (!success)
9713             return false;
9714 
9715         AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1);
9716 
9717         // if d == 15 then // Can only occur for ARM encoding
9718             // ALUWritePC(result); // setflags is always FALSE here
9719         // else
9720             // R[d] = result;
9721             // if setflags then
9722                 // APSR.N = result<31>;
9723                 // APSR.Z = IsZeroBit(result);
9724                 // APSR.C = carry;
9725                 // APSR.V = overflow;
9726 
9727         EmulateInstruction::Context context;
9728         context.type = eContextArithmetic;
9729         RegisterInfo reg_n;
9730         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9731         RegisterInfo reg_m;
9732         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9733         context.SetRegisterRegisterOperands (reg_n, reg_m);
9734 
9735         if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9736             return false;
9737     }
9738     return true;
9739 }
9740 
9741 // A8.6.202 STREX
9742 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a
9743 // word from a register to memory if the executing processor has exclusive access to the memory addressed.
9744 bool
9745 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding)
9746 {
9747 #if 0
9748     if ConditionPassed() then
9749         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9750         address = R[n] + imm32;
9751         if ExclusiveMonitorsPass(address,4) then
9752             MemA[address,4] = R[t];
9753             R[d] = 0;
9754         else
9755             R[d] = 1;
9756 #endif
9757 
9758     bool success = false;
9759 
9760     if (ConditionPassed(opcode))
9761     {
9762         uint32_t d;
9763         uint32_t t;
9764         uint32_t n;
9765         uint32_t imm32;
9766         const uint32_t addr_byte_size = GetAddressByteSize();
9767 
9768         switch (encoding)
9769         {
9770             case eEncodingT1:
9771                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
9772                 d = Bits32 (opcode, 11, 8);
9773                 t = Bits32 (opcode, 15, 12);
9774                 n = Bits32 (opcode, 19, 16);
9775                 imm32 = Bits32 (opcode, 7, 0) << 2;
9776 
9777                 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
9778                 if (BadReg (d) || BadReg (t) || (n == 15))
9779                   return false;
9780 
9781                 // if d == n || d == t then UNPREDICTABLE;
9782                 if ((d == n) || (d == t))
9783                   return false;
9784 
9785                 break;
9786 
9787             case eEncodingA1:
9788                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset
9789                 d = Bits32 (opcode, 15, 12);
9790                 t = Bits32 (opcode, 3, 0);
9791                 n = Bits32 (opcode, 19, 16);
9792                 imm32 = 0;
9793 
9794                 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
9795                 if ((d == 15) || (t == 15) || (n == 15))
9796                     return false;
9797 
9798                 // if d == n || d == t then UNPREDICTABLE;
9799                 if ((d == n) || (d == t))
9800                     return false;
9801 
9802                 break;
9803 
9804             default:
9805                 return false;
9806         }
9807 
9808         // address = R[n] + imm32;
9809         uint32_t Rn = ReadCoreReg (n, &success);
9810         if (!success)
9811             return false;
9812 
9813         addr_t address = Rn + imm32;
9814 
9815         RegisterInfo base_reg;
9816         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9817         RegisterInfo data_reg;
9818         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9819         EmulateInstruction::Context context;
9820         context.type = eContextRegisterStore;
9821         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32);
9822 
9823         // if ExclusiveMonitorsPass(address,4) then
9824         // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this
9825         //                                                         always return true.
9826         if (true)
9827         {
9828             // MemA[address,4] = R[t];
9829             uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
9830             if (!success)
9831                 return false;
9832 
9833             if (!MemAWrite (context, address, Rt, addr_byte_size))
9834                 return false;
9835 
9836             // R[d] = 0;
9837             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0))
9838                 return false;
9839         }
9840         else
9841         {
9842             // R[d] = 1;
9843             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
9844                 return false;
9845         }
9846     }
9847     return true;
9848 }
9849 
9850 // A8.6.197 STRB (immediate, ARM)
9851 bool
9852 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9853 {
9854 #if 0
9855     if ConditionPassed() then
9856         EncodingSpecificOperations();
9857         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9858         address = if index then offset_addr else R[n];
9859         MemU[address,1] = R[t]<7:0>;
9860         if wback then R[n] = offset_addr;
9861 #endif
9862 
9863     bool success = false;
9864 
9865     if (ConditionPassed(opcode))
9866     {
9867         uint32_t t;
9868         uint32_t n;
9869         uint32_t imm32;
9870         bool index;
9871         bool add;
9872         bool wback;
9873 
9874         switch (encoding)
9875         {
9876             case eEncodingA1:
9877                 // if P == �0� && W == �1� then SEE STRBT;
9878                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9879                 t = Bits32 (opcode, 15, 12);
9880                 n = Bits32 (opcode, 19, 16);
9881                 imm32 = Bits32 (opcode, 11, 0);
9882 
9883                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9884                 index = BitIsSet (opcode, 24);
9885                 add = BitIsSet (opcode, 23);
9886                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9887 
9888                 // if t == 15 then UNPREDICTABLE;
9889                 if (t == 15)
9890                     return false;
9891 
9892                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9893                 if (wback && ((n == 15) || (n == t)))
9894                     return false;
9895 
9896                 break;
9897 
9898             default:
9899                 return false;
9900         }
9901 
9902         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9903         uint32_t Rn = ReadCoreReg (n, &success);
9904         if (!success)
9905             return false;
9906 
9907         addr_t offset_addr;
9908         if (add)
9909             offset_addr = Rn + imm32;
9910         else
9911             offset_addr = Rn - imm32;
9912 
9913         // address = if index then offset_addr else R[n];
9914         addr_t address;
9915         if (index)
9916             address = offset_addr;
9917         else
9918             address = Rn;
9919 
9920         // MemU[address,1] = R[t]<7:0>;
9921         uint32_t Rt = ReadCoreReg (t, &success);
9922         if (!success)
9923             return false;
9924 
9925         RegisterInfo base_reg;
9926         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9927         RegisterInfo data_reg;
9928         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9929         EmulateInstruction::Context context;
9930         context.type = eContextRegisterStore;
9931         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
9932 
9933         if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1))
9934             return false;
9935 
9936         // if wback then R[n] = offset_addr;
9937         if (wback)
9938         {
9939             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
9940                 return false;
9941         }
9942     }
9943     return true;
9944 }
9945 
9946 // A8.6.194 STR (immediate, ARM)
9947 bool
9948 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding)
9949 {
9950 #if 0
9951     if ConditionPassed() then
9952         EncodingSpecificOperations();
9953         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9954         address = if index then offset_addr else R[n];
9955         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
9956         if wback then R[n] = offset_addr;
9957 #endif
9958 
9959     bool success = false;
9960 
9961     if (ConditionPassed(opcode))
9962     {
9963         uint32_t t;
9964         uint32_t n;
9965         uint32_t imm32;
9966         bool index;
9967         bool add;
9968         bool wback;
9969 
9970         const uint32_t addr_byte_size = GetAddressByteSize();
9971 
9972         switch (encoding)
9973         {
9974             case eEncodingA1:
9975                 // if P == �0� && W == �1� then SEE STRT;
9976                 // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH;
9977                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9978                 t = Bits32 (opcode, 15, 12);
9979                 n = Bits32 (opcode, 19, 16);
9980                 imm32 = Bits32 (opcode, 11, 0);
9981 
9982                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9983                 index = BitIsSet (opcode, 24);
9984                 add = BitIsSet (opcode, 23);
9985                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9986 
9987                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9988                 if (wback && ((n == 15) || (n == t)))
9989                     return false;
9990 
9991                 break;
9992 
9993             default:
9994                 return false;
9995         }
9996 
9997         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9998         uint32_t Rn = ReadCoreReg (n, &success);
9999         if (!success)
10000             return false;
10001 
10002         addr_t offset_addr;
10003         if (add)
10004             offset_addr = Rn + imm32;
10005         else
10006             offset_addr = Rn - imm32;
10007 
10008         // address = if index then offset_addr else R[n];
10009         addr_t address;
10010         if (index)
10011             address = offset_addr;
10012         else
10013             address = Rn;
10014 
10015         RegisterInfo base_reg;
10016         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10017         RegisterInfo data_reg;
10018         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10019         EmulateInstruction::Context context;
10020         context.type = eContextRegisterStore;
10021         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10022 
10023         // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10024         uint32_t Rt = ReadCoreReg (t, &success);
10025         if (!success)
10026             return false;
10027 
10028         if (t == 15)
10029         {
10030             uint32_t pc_value = ReadCoreReg (PC_REG, &success);
10031             if (!success)
10032                 return false;
10033 
10034             if (!MemUWrite (context, address, pc_value, addr_byte_size))
10035                 return false;
10036         }
10037         else
10038         {
10039             if (!MemUWrite (context, address, Rt, addr_byte_size))
10040                   return false;
10041         }
10042 
10043         // if wback then R[n] = offset_addr;
10044         if (wback)
10045         {
10046             context.type = eContextAdjustBaseRegister;
10047             context.SetImmediate (offset_addr);
10048 
10049             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10050                 return false;
10051         }
10052     }
10053     return true;
10054 }
10055 
10056 // A8.6.66 LDRD (immediate)
10057 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two
10058 // words from memory, and writes them to two registers.  It can use offset, post-indexed, or pre-indexed addressing.
10059 bool
10060 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding)
10061 {
10062 #if 0
10063     if ConditionPassed() then
10064         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10065         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10066         address = if index then offset_addr else R[n];
10067         R[t] = MemA[address,4];
10068         R[t2] = MemA[address+4,4];
10069         if wback then R[n] = offset_addr;
10070 #endif
10071 
10072     bool success = false;
10073 
10074     if (ConditionPassed(opcode))
10075     {
10076         uint32_t t;
10077         uint32_t t2;
10078         uint32_t n;
10079         uint32_t imm32;
10080         bool index;
10081         bool add;
10082         bool wback;
10083 
10084         switch (encoding)
10085         {
10086             case eEncodingT1:
10087                 //if P == �0� && W == �0� then SEE �Related encodings�;
10088                 //if Rn == �1111� then SEE LDRD (literal);
10089                 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10090                 t = Bits32 (opcode, 15, 12);
10091                 t2 = Bits32 (opcode, 11, 8);
10092                 n = Bits32 (opcode, 19, 16);
10093                 imm32 = Bits32 (opcode, 7, 0) << 2;
10094 
10095                 //index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10096                 index = BitIsSet (opcode, 24);
10097                 add = BitIsSet (opcode, 23);
10098                 wback = BitIsSet (opcode, 21);
10099 
10100                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10101                 if (wback && ((n == t) || (n == t2)))
10102                     return false;
10103 
10104                 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10105                 if (BadReg (t) || BadReg (t2) || (t == t2))
10106                     return false;
10107 
10108                 break;
10109 
10110             case eEncodingA1:
10111                 //if Rn == �1111� then SEE LDRD (literal);
10112                 //if Rt<0> == �1� then UNPREDICTABLE;
10113                 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10114                 t = Bits32 (opcode, 15, 12);
10115                 if (BitIsSet (t, 0))
10116                     return false;
10117                 t2 = t + 1;
10118                 n = Bits32 (opcode, 19, 16);
10119                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 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 P == �0� && W == �1� then UNPREDICTABLE;
10127                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10128                     return false;
10129 
10130                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10131                 if (wback && ((n == t) || (n == t2)))
10132                     return false;
10133 
10134                 //if t2 == 15 then UNPREDICTABLE;
10135                 if (t2 == 15)
10136                     return false;
10137 
10138                 break;
10139 
10140             default:
10141                 return false;
10142         }
10143 
10144         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10145         uint32_t Rn = ReadCoreReg (n, &success);
10146         if (!success)
10147             return false;
10148 
10149         addr_t offset_addr;
10150         if (add)
10151                   offset_addr = Rn + imm32;
10152         else
10153             offset_addr = Rn - imm32;
10154 
10155         //address = if index then offset_addr else R[n];
10156         addr_t address;
10157         if (index)
10158             address = offset_addr;
10159         else
10160             address = Rn;
10161 
10162         //R[t] = MemA[address,4];
10163         RegisterInfo base_reg;
10164         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10165 
10166         EmulateInstruction::Context context;
10167         context.type = eContextRegisterLoad;
10168         context.SetRegisterPlusOffset (base_reg, address - Rn);
10169 
10170         const uint32_t addr_byte_size = GetAddressByteSize();
10171         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10172         if (!success)
10173             return false;
10174 
10175         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10176             return false;
10177 
10178         //R[t2] = MemA[address+4,4];
10179 
10180         context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10181         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10182         if (!success)
10183             return false;
10184 
10185         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10186             return false;
10187 
10188         //if wback then R[n] = offset_addr;
10189         if (wback)
10190         {
10191             context.type = eContextAdjustBaseRegister;
10192             context.SetAddress (offset_addr);
10193 
10194             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10195                 return false;
10196         }
10197     }
10198     return true;
10199 }
10200 
10201 // A8.6.68 LDRD (register)
10202 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two
10203 // words from memory, and writes them to two registers.  It can use offset, post-indexed or pre-indexed addressing.
10204 bool
10205 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding)
10206 {
10207 #if 0
10208     if ConditionPassed() then
10209         EncodingSpecificOperations();
10210         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10211         address = if index then offset_addr else R[n];
10212         R[t] = MemA[address,4];
10213         R[t2] = MemA[address+4,4];
10214         if wback then R[n] = offset_addr;
10215 #endif
10216 
10217     bool success = false;
10218 
10219     if (ConditionPassed(opcode))
10220     {
10221         uint32_t t;
10222         uint32_t t2;
10223         uint32_t n;
10224         uint32_t m;
10225         bool index;
10226         bool add;
10227         bool wback;
10228 
10229         switch (encoding)
10230         {
10231             case eEncodingA1:
10232                 // if Rt<0> == �1� then UNPREDICTABLE;
10233                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10234                 t = Bits32 (opcode, 15, 12);
10235                 if (BitIsSet (t, 0))
10236                     return false;
10237                 t2 = t + 1;
10238                 n = Bits32 (opcode, 19, 16);
10239                 m = Bits32 (opcode, 3, 0);
10240 
10241                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10242                 index = BitIsSet (opcode, 24);
10243                 add = BitIsSet (opcode, 23);
10244                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10245 
10246                 // if P == �0� && W == �1� then UNPREDICTABLE;
10247                   if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10248                   return false;
10249 
10250                 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10251                   if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10252                   return false;
10253 
10254                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10255                   if (wback && ((n == 15) || (n == t) || (n == t2)))
10256                   return false;
10257 
10258                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10259                 if ((ArchVersion() < 6) && wback && (m == n))
10260                   return false;
10261                 break;
10262 
10263             default:
10264                 return false;
10265         }
10266 
10267         uint32_t Rn = ReadCoreReg (n, &success);
10268         if (!success)
10269             return false;
10270         RegisterInfo base_reg;
10271         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10272 
10273         uint32_t Rm = ReadCoreReg (m, &success);
10274         if (!success)
10275             return false;
10276         RegisterInfo offset_reg;
10277         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10278 
10279         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10280         addr_t offset_addr;
10281         if (add)
10282             offset_addr = Rn + Rm;
10283         else
10284             offset_addr = Rn - Rm;
10285 
10286         // address = if index then offset_addr else R[n];
10287         addr_t address;
10288         if (index)
10289             address = offset_addr;
10290         else
10291             address = Rn;
10292 
10293         EmulateInstruction::Context context;
10294         context.type = eContextRegisterLoad;
10295         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
10296 
10297         // R[t] = MemA[address,4];
10298         const uint32_t addr_byte_size = GetAddressByteSize();
10299         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10300         if (!success)
10301             return false;
10302 
10303         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10304             return false;
10305 
10306         // R[t2] = MemA[address+4,4];
10307 
10308         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10309         if (!success)
10310             return false;
10311 
10312         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10313             return false;
10314 
10315         // if wback then R[n] = offset_addr;
10316         if (wback)
10317         {
10318             context.type = eContextAdjustBaseRegister;
10319             context.SetAddress (offset_addr);
10320 
10321             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10322                 return false;
10323         }
10324     }
10325     return true;
10326 }
10327 
10328 // A8.6.200 STRD (immediate)
10329 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and
10330 // stores two words from two registers to memory.  It can use offset, post-indexed, or pre-indexed addressing.
10331 bool
10332 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding)
10333 {
10334 #if 0
10335     if ConditionPassed() then
10336         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10337         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10338         address = if index then offset_addr else R[n];
10339         MemA[address,4] = R[t];
10340         MemA[address+4,4] = R[t2];
10341         if wback then R[n] = offset_addr;
10342 #endif
10343 
10344     bool success = false;
10345 
10346     if (ConditionPassed(opcode))
10347     {
10348         uint32_t t;
10349         uint32_t t2;
10350         uint32_t n;
10351         uint32_t imm32;
10352         bool index;
10353         bool add;
10354         bool wback;
10355 
10356         switch (encoding)
10357         {
10358             case eEncodingT1:
10359                 // if P == �0� && W == �0� then SEE �Related encodings�;
10360                 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10361                 t = Bits32 (opcode, 15, 12);
10362                 t2 = Bits32 (opcode, 11, 8);
10363                 n = Bits32 (opcode, 19, 16);
10364                 imm32 = Bits32 (opcode, 7, 0) << 2;
10365 
10366                 // index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10367                 index = BitIsSet (opcode, 24);
10368                 add = BitIsSet (opcode, 23);
10369                 wback = BitIsSet (opcode, 21);
10370 
10371                 // if wback && (n == t || n == t2) then UNPREDICTABLE;
10372                 if (wback && ((n == t) || (n == t2)))
10373                     return false;
10374 
10375                 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10376                 if ((n == 15) || BadReg (t) || BadReg (t2))
10377                     return false;
10378 
10379                 break;
10380 
10381             case eEncodingA1:
10382                 // if Rt<0> == �1� then UNPREDICTABLE;
10383                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10384                 t = Bits32 (opcode, 15, 12);
10385                 if (BitIsSet (t, 0))
10386                     return false;
10387 
10388                 t2 = t + 1;
10389                 n = Bits32 (opcode, 19, 16);
10390                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10391 
10392                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10393                 index = BitIsSet (opcode, 24);
10394                 add = BitIsSet (opcode, 23);
10395                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10396 
10397                 // if P == �0� && W == �1� then UNPREDICTABLE;
10398                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10399                     return false;
10400 
10401                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10402                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10403                     return false;
10404 
10405                 // if t2 == 15 then UNPREDICTABLE;
10406                 if (t2 == 15)
10407                     return false;
10408 
10409                 break;
10410 
10411             default:
10412                 return false;
10413         }
10414 
10415         RegisterInfo base_reg;
10416         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10417 
10418         uint32_t Rn = ReadCoreReg (n, &success);
10419         if (!success)
10420             return false;
10421 
10422         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10423         addr_t offset_addr;
10424         if (add)
10425             offset_addr = Rn + imm32;
10426         else
10427             offset_addr = Rn - imm32;
10428 
10429         //address = if index then offset_addr else R[n];
10430         addr_t address;
10431         if (index)
10432             address = offset_addr;
10433         else
10434             address = Rn;
10435 
10436         //MemA[address,4] = R[t];
10437         RegisterInfo data_reg;
10438         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10439 
10440         uint32_t data = ReadCoreReg (t, &success);
10441         if (!success)
10442             return false;
10443 
10444         EmulateInstruction::Context context;
10445         context.type = eContextRegisterStore;
10446         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10447 
10448         const uint32_t addr_byte_size = GetAddressByteSize();
10449 
10450         if (!MemAWrite (context, address, data, addr_byte_size))
10451             return false;
10452 
10453         //MemA[address+4,4] = R[t2];
10454         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10455         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10456 
10457         data = ReadCoreReg (t2, &success);
10458         if (!success)
10459             return false;
10460 
10461         if (!MemAWrite (context, address + 4, data, addr_byte_size))
10462             return false;
10463 
10464         //if wback then R[n] = offset_addr;
10465         if (wback)
10466         {
10467             context.type = eContextAdjustBaseRegister;
10468             context.SetAddress (offset_addr);
10469 
10470             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10471                 return false;
10472         }
10473     }
10474     return true;
10475 }
10476 
10477 
10478 // A8.6.201 STRD (register)
10479 bool
10480 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding)
10481 {
10482 #if 0
10483     if ConditionPassed() then
10484         EncodingSpecificOperations();
10485         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10486         address = if index then offset_addr else R[n];
10487         MemA[address,4] = R[t];
10488         MemA[address+4,4] = R[t2];
10489         if wback then R[n] = offset_addr;
10490 #endif
10491 
10492     bool success = false;
10493 
10494     if (ConditionPassed(opcode))
10495     {
10496         uint32_t t;
10497         uint32_t t2;
10498         uint32_t n;
10499         uint32_t m;
10500         bool index;
10501         bool add;
10502         bool wback;
10503 
10504         switch (encoding)
10505         {
10506             case eEncodingA1:
10507                 // if Rt<0> == �1� then UNPREDICTABLE;
10508                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10509                 t = Bits32 (opcode, 15, 12);
10510                 if (BitIsSet (t, 0))
10511                    return false;
10512 
10513                 t2 = t+1;
10514                 n = Bits32 (opcode, 19, 16);
10515                 m = Bits32 (opcode, 3, 0);
10516 
10517                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10518                 index = BitIsSet (opcode, 24);
10519                 add = BitIsSet (opcode, 23);
10520                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10521 
10522                 // if P == �0� && W == �1� then UNPREDICTABLE;
10523                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10524                    return false;
10525 
10526                 // if t2 == 15 || m == 15 then UNPREDICTABLE;
10527                 if ((t2 == 15) || (m == 15))
10528                    return false;
10529 
10530                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10531                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10532                    return false;
10533 
10534                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10535                 if ((ArchVersion() < 6) && wback && (m == n))
10536                    return false;
10537 
10538                 break;
10539 
10540             default:
10541                 return false;
10542         }
10543 
10544         RegisterInfo base_reg;
10545         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10546         RegisterInfo offset_reg;
10547         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10548         RegisterInfo data_reg;
10549 
10550         uint32_t Rn = ReadCoreReg (n, &success);
10551         if (!success)
10552             return false;
10553 
10554         uint32_t Rm = ReadCoreReg (m, &success);
10555         if (!success)
10556             return false;
10557 
10558         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10559         addr_t offset_addr;
10560         if (add)
10561             offset_addr = Rn + Rm;
10562         else
10563             offset_addr = Rn - Rm;
10564 
10565         // address = if index then offset_addr else R[n];
10566         addr_t address;
10567         if (index)
10568             address = offset_addr;
10569         else
10570             address = Rn;
10571                           // MemA[address,4] = R[t];
10572         uint32_t Rt = ReadCoreReg (t, &success);
10573         if (!success)
10574             return false;
10575 
10576         EmulateInstruction::Context context;
10577         context.type = eContextRegisterStore;
10578         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10579         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10580 
10581         const uint32_t addr_byte_size = GetAddressByteSize();
10582 
10583         if (!MemAWrite (context, address, Rt, addr_byte_size))
10584             return false;
10585 
10586         // MemA[address+4,4] = R[t2];
10587         uint32_t Rt2 = ReadCoreReg (t2, &success);
10588         if (!success)
10589             return false;
10590 
10591         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10592 
10593         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10594 
10595         if (!MemAWrite (context, address + 4, Rt2, addr_byte_size))
10596             return false;
10597 
10598         // if wback then R[n] = offset_addr;
10599         if (wback)
10600         {
10601             context.type = eContextAdjustBaseRegister;
10602             context.SetAddress (offset_addr);
10603 
10604             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10605                 return false;
10606 
10607         }
10608     }
10609     return true;
10610 }
10611 
10612 // A8.6.319 VLDM
10613 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from
10614 // an ARM core register.
10615 bool
10616 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding)
10617 {
10618 #if 0
10619     if ConditionPassed() then
10620         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10621         address = if add then R[n] else R[n]-imm32;
10622         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10623         for r = 0 to regs-1
10624             if single_regs then
10625                 S[d+r] = MemA[address,4]; address = address+4;
10626             else
10627                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10628                 // Combine the word-aligned words in the correct order for current endianness.
10629                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10630 #endif
10631 
10632     bool success = false;
10633 
10634     if (ConditionPassed(opcode))
10635     {
10636         bool single_regs;
10637         bool add;
10638         bool wback;
10639         uint32_t d;
10640         uint32_t n;
10641         uint32_t imm32;
10642         uint32_t regs;
10643 
10644         switch (encoding)
10645         {
10646             case eEncodingT1:
10647             case eEncodingA1:
10648                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10649                 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10650                 // if P == �1� && W == �0� then SEE VLDR;
10651                 // if P == U && W == �1� then UNDEFINED;
10652                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10653                     return false;
10654 
10655                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10656                 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10657                 single_regs = false;
10658                 add = BitIsSet (opcode, 23);
10659                 wback = BitIsSet (opcode, 21);
10660 
10661                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10662                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10663                 n = Bits32 (opcode, 19, 16);
10664                 imm32 = Bits32 (opcode, 7, 0) << 2;
10665 
10666                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�.
10667                 regs = Bits32 (opcode, 7, 0) / 2;
10668 
10669                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10670                 if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
10671                     return false;
10672 
10673                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10674                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10675                     return false;
10676 
10677                 break;
10678 
10679             case eEncodingT2:
10680             case eEncodingA2:
10681                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10682                 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10683                 // if P == �1� && W == �0� then SEE VLDR;
10684                 // if P == U && W == �1� then UNDEFINED;
10685                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10686                     return false;
10687 
10688                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10689                 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10690                 single_regs = true;
10691                 add = BitIsSet (opcode, 23);
10692                 wback = BitIsSet (opcode, 21);
10693                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10694                 n = Bits32 (opcode, 19, 16);
10695 
10696                 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10697                 imm32 = Bits32 (opcode, 7, 0) << 2;
10698                 regs = Bits32 (opcode, 7, 0);
10699 
10700                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10701                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10702                     return false;
10703 
10704                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10705                 if ((regs == 0) || ((d + regs) > 32))
10706                     return false;
10707                 break;
10708 
10709             default:
10710                 return false;
10711         }
10712 
10713         RegisterInfo base_reg;
10714         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10715 
10716         uint32_t Rn = ReadCoreReg (n, &success);
10717         if (!success)
10718             return false;
10719 
10720         // address = if add then R[n] else R[n]-imm32;
10721         addr_t address;
10722         if (add)
10723             address = Rn;
10724         else
10725             address = Rn - imm32;
10726 
10727         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10728         EmulateInstruction::Context context;
10729 
10730         if (wback)
10731         {
10732             uint32_t value;
10733             if (add)
10734                 value = Rn + imm32;
10735             else
10736                 value = Rn - imm32;
10737 
10738             context.type = eContextAdjustBaseRegister;
10739             context.SetImmediateSigned (value - Rn);
10740             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10741                 return false;
10742 
10743         }
10744 
10745         const uint32_t addr_byte_size = GetAddressByteSize();
10746         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10747 
10748         context.type = eContextRegisterLoad;
10749 
10750         // for r = 0 to regs-1
10751         for (uint32_t r = 0; r < regs; ++r)
10752         {
10753             if (single_regs)
10754             {
10755                 // S[d+r] = MemA[address,4]; address = address+4;
10756                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10757 
10758                 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10759                 if (!success)
10760                     return false;
10761 
10762                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10763                     return false;
10764 
10765                 address = address + 4;
10766             }
10767             else
10768             {
10769                 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10770                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10771                 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10772                 if (!success)
10773                     return false;
10774 
10775                 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10776                 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10777                 if (!success)
10778                     return false;
10779 
10780                 address = address + 8;
10781                 // // Combine the word-aligned words in the correct order for current endianness.
10782                 // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10783                 uint64_t data;
10784                 if (GetByteOrder() == eByteOrderBig)
10785                 {
10786                     data = word1;
10787                     data = (data << 32) | word2;
10788                 }
10789                 else
10790                 {
10791                     data = word2;
10792                     data = (data << 32) | word1;
10793                 }
10794 
10795                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10796                     return false;
10797             }
10798         }
10799     }
10800     return true;
10801 }
10802 
10803 // A8.6.399 VSTM
10804 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an
10805 // ARM core register.
10806 bool
10807 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding)
10808 {
10809 #if 0
10810     if ConditionPassed() then
10811         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10812         address = if add then R[n] else R[n]-imm32;
10813         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10814         for r = 0 to regs-1
10815             if single_regs then
10816                 MemA[address,4] = S[d+r]; address = address+4;
10817             else
10818                 // Store as two word-aligned words in the correct order for current endianness.
10819                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10820                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10821                 address = address+8;
10822 #endif
10823 
10824     bool success = false;
10825 
10826     if (ConditionPassed (opcode))
10827     {
10828         bool single_regs;
10829         bool add;
10830         bool wback;
10831         uint32_t d;
10832         uint32_t n;
10833         uint32_t imm32;
10834         uint32_t regs;
10835 
10836         switch (encoding)
10837         {
10838             case eEncodingT1:
10839             case eEncodingA1:
10840                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10841                 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10842                 // if P == �1� && W == �0� then SEE VSTR;
10843                 // if P == U && W == �1� then UNDEFINED;
10844                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10845                     return false;
10846 
10847                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10848                 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10849                 single_regs = false;
10850                 add = BitIsSet (opcode, 23);
10851                 wback = BitIsSet (opcode, 21);
10852 
10853                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10854                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10855                 n = Bits32 (opcode, 19, 16);
10856                 imm32 = Bits32 (opcode, 7, 0) << 2;
10857 
10858                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�.
10859                 regs = Bits32 (opcode, 7, 0) / 2;
10860 
10861                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10862                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10863                     return false;
10864 
10865                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10866                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10867                     return false;
10868 
10869                 break;
10870 
10871             case eEncodingT2:
10872             case eEncodingA2:
10873                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10874                 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10875                 // if P == �1� && W == �0� then SEE VSTR;
10876                 // if P == U && W == �1� then UNDEFINED;
10877                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10878                     return false;
10879 
10880                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10881                 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10882                 single_regs = true;
10883                 add = BitIsSet (opcode, 23);
10884                 wback = BitIsSet (opcode, 21);
10885                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10886                 n = Bits32 (opcode, 19, 16);
10887 
10888                 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10889                 imm32 = Bits32 (opcode, 7, 0) << 2;
10890                 regs = Bits32 (opcode, 7, 0);
10891 
10892                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10893                 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM)))
10894                     return false;
10895 
10896                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10897                 if ((regs == 0) || ((d + regs) > 32))
10898                     return false;
10899 
10900                 break;
10901 
10902             default:
10903                 return false;
10904         }
10905 
10906         RegisterInfo base_reg;
10907         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10908 
10909         uint32_t Rn = ReadCoreReg (n, &success);
10910         if (!success)
10911             return false;
10912 
10913         // address = if add then R[n] else R[n]-imm32;
10914         addr_t address;
10915         if (add)
10916             address = Rn;
10917         else
10918             address = Rn - imm32;
10919 
10920         EmulateInstruction::Context context;
10921         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10922         if (wback)
10923         {
10924             uint32_t value;
10925             if (add)
10926                 value = Rn + imm32;
10927             else
10928                 value = Rn - imm32;
10929 
10930             context.type = eContextAdjustBaseRegister;
10931             context.SetRegisterPlusOffset (base_reg, value - Rn);
10932 
10933             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10934                 return false;
10935         }
10936 
10937         const uint32_t addr_byte_size = GetAddressByteSize();
10938         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10939 
10940         context.type = eContextRegisterStore;
10941         // for r = 0 to regs-1
10942         for (int r = 0; r < regs; ++r)
10943         {
10944 
10945             if (single_regs)
10946             {
10947                 // MemA[address,4] = S[d+r]; address = address+4;
10948                 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10949                 if (!success)
10950                     return false;
10951 
10952                 RegisterInfo data_reg;
10953                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
10954                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10955                 if (!MemAWrite (context, address, data, addr_byte_size))
10956                     return false;
10957 
10958                 address = address + 4;
10959             }
10960             else
10961             {
10962                 // // Store as two word-aligned words in the correct order for current endianness.
10963                 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10964                 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10965                 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10966                 if (!success)
10967                     return false;
10968 
10969                 RegisterInfo data_reg;
10970                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
10971 
10972                 if (GetByteOrder() == eByteOrderBig)
10973                 {
10974                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10975                     if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
10976                         return false;
10977 
10978                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10979                     if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size))
10980                         return false;
10981                 }
10982                 else
10983                 {
10984                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10985                     if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
10986                         return false;
10987 
10988                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10989                     if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
10990                         return false;
10991                 }
10992                 // address = address+8;
10993                 address = address + 8;
10994             }
10995         }
10996     }
10997     return true;
10998 }
10999 
11000 // A8.6.320
11001 // This instruciton loads a single extension register fronm memory, using an address from an ARM core register, with
11002 // an optional offset.
11003 bool
11004 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
11005 {
11006 #if 0
11007     if ConditionPassed() then
11008         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11009         base = if n == 15 then Align(PC,4) else R[n];
11010         address = if add then (base + imm32) else (base - imm32);
11011         if single_reg then
11012             S[d] = MemA[address,4];
11013         else
11014             word1 = MemA[address,4]; word2 = MemA[address+4,4];
11015             // Combine the word-aligned words in the correct order for current endianness.
11016             D[d] = if BigEndian() then word1:word2 else word2:word1;
11017 #endif
11018 
11019     bool success = false;
11020 
11021     if (ConditionPassed (opcode))
11022     {
11023         bool single_reg;
11024         bool add;
11025         uint32_t imm32;
11026         uint32_t d;
11027         uint32_t n;
11028 
11029         switch (encoding)
11030         {
11031             case eEncodingT1:
11032             case eEncodingA1:
11033                 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11034                 single_reg = false;
11035                 add = BitIsSet (opcode, 23);
11036                 imm32 = Bits32 (opcode, 7, 0) << 2;
11037 
11038                 // d = UInt(D:Vd); n = UInt(Rn);
11039                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11040                 n = Bits32 (opcode, 19, 16);
11041 
11042                 break;
11043 
11044             case eEncodingT2:
11045             case eEncodingA2:
11046                 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11047                 single_reg = true;
11048                 add = BitIsSet (opcode, 23);
11049                 imm32 = Bits32 (opcode, 7, 0) << 2;
11050 
11051                 // d = UInt(Vd:D); n = UInt(Rn);
11052                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11053                 n = Bits32 (opcode, 19, 16);
11054 
11055                 break;
11056 
11057             default:
11058                 return false;
11059         }
11060         RegisterInfo base_reg;
11061         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11062 
11063         uint32_t Rn = ReadCoreReg (n, &success);
11064         if (!success)
11065             return false;
11066 
11067         // base = if n == 15 then Align(PC,4) else R[n];
11068         uint32_t base;
11069         if (n == 15)
11070             base = AlignPC (Rn);
11071         else
11072             base = Rn;
11073 
11074         // address = if add then (base + imm32) else (base - imm32);
11075         addr_t address;
11076         if (add)
11077             address = base + imm32;
11078         else
11079             address = base - imm32;
11080 
11081         const uint32_t addr_byte_size = GetAddressByteSize();
11082         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11083 
11084         EmulateInstruction::Context context;
11085         context.type = eContextRegisterLoad;
11086         context.SetRegisterPlusOffset (base_reg, address - base);
11087 
11088         if (single_reg)
11089         {
11090             // S[d] = MemA[address,4];
11091             uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
11092             if (!success)
11093                 return false;
11094 
11095             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data))
11096                 return false;
11097         }
11098         else
11099         {
11100             // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11101             uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
11102             if (!success)
11103                 return false;
11104 
11105             context.SetRegisterPlusOffset (base_reg, (address + 4) - base);
11106             uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
11107             if (!success)
11108                 return false;
11109             // // Combine the word-aligned words in the correct order for current endianness.
11110             // D[d] = if BigEndian() then word1:word2 else word2:word1;
11111             uint64_t data64;
11112             if (GetByteOrder() == eByteOrderBig)
11113             {
11114                 data64 = word1;
11115                 data64 = (data64 << 32) | word2;
11116             }
11117             else
11118             {
11119                 data64 = word2;
11120                 data64 = (data64 << 32) | word1;
11121             }
11122 
11123             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64))
11124                 return false;
11125         }
11126     }
11127     return true;
11128 }
11129 
11130 // A8.6.400 VSTR
11131 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an
11132 // optional offset.
11133 bool
11134 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
11135 {
11136 #if 0
11137     if ConditionPassed() then
11138         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11139         address = if add then (R[n] + imm32) else (R[n] - imm32);
11140         if single_reg then
11141             MemA[address,4] = S[d];
11142         else
11143             // Store as two word-aligned words in the correct order for current endianness.
11144             MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11145             MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11146 #endif
11147 
11148     bool success = false;
11149 
11150     if (ConditionPassed (opcode))
11151     {
11152         bool single_reg;
11153         bool add;
11154         uint32_t imm32;
11155         uint32_t d;
11156         uint32_t n;
11157 
11158         switch (encoding)
11159         {
11160             case eEncodingT1:
11161             case eEncodingA1:
11162                 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11163                 single_reg = false;
11164                 add = BitIsSet (opcode, 23);
11165                 imm32 = Bits32 (opcode, 7, 0) << 2;
11166 
11167                 // d = UInt(D:Vd); n = UInt(Rn);
11168                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11169                 n = Bits32 (opcode, 19, 16);
11170 
11171                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11172                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11173                     return false;
11174 
11175                 break;
11176 
11177             case eEncodingT2:
11178             case eEncodingA2:
11179                 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11180                 single_reg = true;
11181                 add = BitIsSet (opcode, 23);
11182                 imm32 = Bits32 (opcode, 7, 0) << 2;
11183 
11184                 // d = UInt(Vd:D); n = UInt(Rn);
11185                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11186                 n = Bits32 (opcode, 19, 16);
11187 
11188                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11189                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11190                     return false;
11191 
11192                 break;
11193 
11194             default:
11195                 return false;
11196         }
11197 
11198         RegisterInfo base_reg;
11199         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11200 
11201         uint32_t Rn = ReadCoreReg (n, &success);
11202         if (!success)
11203             return false;
11204 
11205         // address = if add then (R[n] + imm32) else (R[n] - imm32);
11206         addr_t address;
11207         if (add)
11208             address = Rn + imm32;
11209         else
11210             address = Rn - imm32;
11211 
11212         const uint32_t addr_byte_size = GetAddressByteSize();
11213         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11214 
11215         RegisterInfo data_reg;
11216         GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg);
11217         EmulateInstruction::Context context;
11218         context.type = eContextRegisterStore;
11219         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11220 
11221         if (single_reg)
11222         {
11223             // MemA[address,4] = S[d];
11224             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11225             if (!success)
11226                 return false;
11227 
11228             if (!MemAWrite (context, address, data, addr_byte_size))
11229                 return false;
11230         }
11231         else
11232         {
11233             // // Store as two word-aligned words in the correct order for current endianness.
11234             // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11235             // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11236             uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11237             if (!success)
11238                 return false;
11239 
11240             if (GetByteOrder() == eByteOrderBig)
11241             {
11242                 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11243                     return false;
11244 
11245                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11246                 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size))
11247                     return false;
11248             }
11249             else
11250             {
11251                 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11252                     return false;
11253 
11254                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11255                 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11256                     return false;
11257             }
11258         }
11259     }
11260     return true;
11261 }
11262 
11263 // A8.6.307 VLDI1 (multiple single elements)
11264 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving.  Every
11265 // element of each register is loaded.
11266 bool
11267 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding)
11268 {
11269 #if 0
11270     if ConditionPassed() then
11271         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11272         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11273         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11274         for r = 0 to regs-1
11275             for e = 0 to elements-1
11276                 Elem[D[d+r],e,esize] = MemU[address,ebytes];
11277                 address = address + ebytes;
11278 #endif
11279 
11280     bool success = false;
11281 
11282     if (ConditionPassed (opcode))
11283     {
11284         uint32_t regs;
11285         uint32_t alignment;
11286         uint32_t ebytes;
11287         uint32_t esize;
11288         uint32_t elements;
11289         uint32_t d;
11290         uint32_t n;
11291         uint32_t m;
11292         bool wback;
11293         bool register_index;
11294 
11295         switch (encoding)
11296         {
11297             case eEncodingT1:
11298             case eEncodingA1:
11299             {
11300                 // case type of
11301                     // when �0111�
11302                         // regs = 1; if align<1> == �1� then UNDEFINED;
11303                     // when �1010�
11304                         // regs = 2; if align == �11� then UNDEFINED;
11305                     // when �0110�
11306                         // regs = 3; if align<1> == �1� then UNDEFINED;
11307                     // when �0010�
11308                         // regs = 4;
11309                     // otherwise
11310                         // SEE �Related encodings�;
11311                 uint32_t type = Bits32 (opcode, 11, 8);
11312                 uint32_t align = Bits32 (opcode, 5, 4);
11313                 if (type == 7) // '0111'
11314                 {
11315                     regs = 1;
11316                     if (BitIsSet (align, 1))
11317                         return false;
11318                 }
11319                 else if (type == 10) // '1010'
11320                 {
11321                     regs = 2;
11322                     if (align == 3)
11323                         return false;
11324 
11325                 }
11326                 else if (type == 6) // '0110'
11327                 {
11328                     regs = 3;
11329                     if (BitIsSet (align, 1))
11330                         return false;
11331                 }
11332                 else if (type == 2) // '0010'
11333                 {
11334                     regs = 4;
11335                 }
11336                 else
11337                     return false;
11338 
11339                 // alignment = if align == �00� then 1 else 4 << UInt(align);
11340                 if (align == 0)
11341                     alignment = 1;
11342                 else
11343                     alignment = 4 << align;
11344 
11345                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11346                 ebytes = 1 << Bits32 (opcode, 7, 6);
11347                 esize = 8 * ebytes;
11348                 elements = 8 / ebytes;
11349 
11350                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11351                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11352                 n = Bits32 (opcode, 19, 15);
11353                 m = Bits32 (opcode, 3, 0);
11354 
11355                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11356                 wback = (m != 15);
11357                 register_index = ((m != 15) && (m != 13));
11358 
11359                 // if d+regs > 32 then UNPREDICTABLE;
11360                 if ((d + regs) > 32)
11361                     return false;
11362             }
11363                 break;
11364 
11365             default:
11366                 return false;
11367         }
11368 
11369         RegisterInfo base_reg;
11370         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11371 
11372         uint32_t Rn = ReadCoreReg (n, &success);
11373         if (!success)
11374             return false;
11375 
11376         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11377         addr_t address = Rn;
11378         if ((address % alignment) != 0)
11379             return false;
11380 
11381         EmulateInstruction::Context context;
11382         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11383         if (wback)
11384         {
11385             uint32_t Rm = ReadCoreReg (m, &success);
11386             if (!success)
11387                 return false;
11388 
11389             uint32_t offset;
11390             if (register_index)
11391                 offset = Rm;
11392             else
11393                 offset = 8 * regs;
11394 
11395             uint32_t value = Rn + offset;
11396             context.type = eContextAdjustBaseRegister;
11397             context.SetRegisterPlusOffset (base_reg, offset);
11398 
11399             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11400                 return false;
11401 
11402         }
11403 
11404         // for r = 0 to regs-1
11405         for (int r = 0; r < regs; ++r)
11406         {
11407             // for e = 0 to elements-1
11408             uint64_t assembled_data = 0;
11409             for (int e = 0; e < elements; ++e)
11410             {
11411                 // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11412                 context.type = eContextRegisterLoad;
11413                 context.SetRegisterPlusOffset (base_reg, address - Rn);
11414                 uint64_t data = MemURead (context, address, ebytes, 0, &success);
11415                 if (!success)
11416                     return false;
11417 
11418                 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data
11419 
11420                 // address = address + ebytes;
11421                 address = address + ebytes;
11422             }
11423             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data))
11424                 return false;
11425         }
11426     }
11427     return true;
11428 }
11429 
11430 // A8.6.308 VLD1 (single element to one lane)
11431 //
11432 bool
11433 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding)
11434 {
11435 #if 0
11436     if ConditionPassed() then
11437         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11438         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11439         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11440         Elem[D[d],index,esize] = MemU[address,ebytes];
11441 #endif
11442 
11443     bool success = false;
11444 
11445     if (ConditionPassed (opcode))
11446     {
11447         uint32_t ebytes;
11448         uint32_t esize;
11449         uint32_t index;
11450         uint32_t alignment;
11451         uint32_t d;
11452         uint32_t n;
11453         uint32_t m;
11454         bool wback;
11455         bool register_index;
11456 
11457         switch (encoding)
11458         {
11459             case eEncodingT1:
11460             case eEncodingA1:
11461             {
11462                 uint32_t size = Bits32 (opcode, 11, 10);
11463                 uint32_t index_align = Bits32 (opcode, 7, 4);
11464                 // if size == �11� then SEE VLD1 (single element to all lanes);
11465                 if (size == 3)
11466                    return EmulateVLD1SingleAll (opcode, encoding);
11467                 // case size of
11468                 if (size == 0) // when '00'
11469                 {
11470                     // if index_align<0> != �0� then UNDEFINED;
11471                     if (BitIsClear (index_align, 0))
11472                         return false;
11473 
11474                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11475                     ebytes = 1;
11476                     esize = 8;
11477                     index = Bits32 (index_align, 3, 1);
11478                     alignment = 1;
11479                 }
11480                 else if (size == 1) // when �01�
11481                 {
11482                     // if index_align<1> != �0� then UNDEFINED;
11483                     if (BitIsClear (index_align, 1))
11484                         return false;
11485 
11486                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11487                     ebytes = 2;
11488                     esize = 16;
11489                     index = Bits32 (index_align, 3, 2);
11490 
11491                     // alignment = if index_align<0> == �0� then 1 else 2;
11492                     if (BitIsClear (index_align, 0))
11493                         alignment = 1;
11494                     else
11495                         alignment = 2;
11496                 }
11497                 else if (size == 2) // when �10�
11498                 {
11499                     // if index_align<2> != �0� then UNDEFINED;
11500                     if (BitIsClear (index_align, 2))
11501                         return false;
11502 
11503                     // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11504                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11505                         return false;
11506 
11507                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11508                     ebytes = 4;
11509                     esize = 32;
11510                     index = Bit32 (index_align, 3);
11511 
11512                     // alignment = if index_align<1:0> == �00� then 1 else 4;
11513                     if (Bits32 (index_align, 1, 0) == 0)
11514                         alignment = 1;
11515                     else
11516                         alignment = 4;
11517                 }
11518                 else
11519                 {
11520                     return false;
11521                 }
11522                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11523                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11524                 n = Bits32 (opcode, 19, 16);
11525                 m = Bits32 (opcode, 3, 0);
11526 
11527                 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
11528                 wback = (m != 15);
11529                 register_index = ((m != 15) && (m != 13));
11530 
11531                 if (n == 15)
11532                     return false;
11533 
11534             }
11535                 break;
11536 
11537             default:
11538                 return false;
11539         }
11540 
11541         RegisterInfo base_reg;
11542         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11543 
11544         uint32_t Rn = ReadCoreReg (n, &success);
11545         if (!success)
11546             return false;
11547 
11548         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11549         addr_t address = Rn;
11550         if ((address % alignment) != 0)
11551             return false;
11552 
11553         EmulateInstruction::Context context;
11554         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11555         if (wback)
11556         {
11557             uint32_t Rm = ReadCoreReg (m, &success);
11558             if (!success)
11559                 return false;
11560 
11561             uint32_t offset;
11562             if (register_index)
11563                 offset = Rm;
11564             else
11565                 offset = ebytes;
11566 
11567             uint32_t value = Rn + offset;
11568 
11569             context.type = eContextAdjustBaseRegister;
11570             context.SetRegisterPlusOffset (base_reg, offset);
11571 
11572             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11573                 return false;
11574         }
11575 
11576         // Elem[D[d],index,esize] = MemU[address,ebytes];
11577         uint32_t element = MemURead (context, address, esize, 0, &success);
11578         if (!success)
11579             return false;
11580 
11581         element = element << (index * esize);
11582 
11583         uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11584         if (!success)
11585             return false;
11586 
11587         uint64_t all_ones = -1;
11588         uint64_t mask = all_ones << ((index+1) * esize);  // mask is all 1's to left of where 'element' goes, & all 0's
11589                                                           // at element & to the right of element.
11590         if (index > 0)
11591             mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes.
11592                                                                      // now mask should be 0's where element goes & 1's
11593                                                                      // everywhere else.
11594 
11595         uint64_t masked_reg = reg_data & mask;  // Take original reg value & zero out 'element' bits
11596         reg_data = masked_reg & element;        // Put 'element' into those bits in reg_data.
11597 
11598         context.type = eContextRegisterLoad;
11599         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data))
11600             return false;
11601     }
11602     return true;
11603 }
11604 
11605 // A8.6.391 VST1 (multiple single elements)
11606 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four regsiters, without
11607 // interleaving.  Every element of each register is stored.
11608 bool
11609 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding)
11610 {
11611 #if 0
11612     if ConditionPassed() then
11613         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11614         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11615         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11616         for r = 0 to regs-1
11617             for e = 0 to elements-1
11618                 MemU[address,ebytes] = Elem[D[d+r],e,esize];
11619                 address = address + ebytes;
11620 #endif
11621 
11622     bool success = false;
11623 
11624     if (ConditionPassed (opcode))
11625     {
11626         uint32_t regs;
11627         uint32_t alignment;
11628         uint32_t ebytes;
11629         uint32_t esize;
11630         uint32_t elements;
11631         uint32_t d;
11632         uint32_t n;
11633         uint32_t m;
11634         bool wback;
11635         bool register_index;
11636 
11637         switch (encoding)
11638         {
11639             case eEncodingT1:
11640             case eEncodingA1:
11641             {
11642                 uint32_t type = Bits32 (opcode, 11, 8);
11643                 uint32_t align = Bits32 (opcode, 5, 4);
11644 
11645                 // case type of
11646                 if (type == 7)    // when �0111�
11647                 {
11648                     // regs = 1; if align<1> == �1� then UNDEFINED;
11649                     regs = 1;
11650                     if (BitIsSet (align, 1))
11651                         return false;
11652                 }
11653                 else if (type == 10) // when �1010�
11654                 {
11655                     // regs = 2; if align == �11� then UNDEFINED;
11656                     regs = 2;
11657                     if (align == 3)
11658                         return false;
11659                 }
11660                 else if (type == 6) // when �0110�
11661                 {
11662                     // regs = 3; if align<1> == �1� then UNDEFINED;
11663                     regs = 3;
11664                     if (BitIsSet (align, 1))
11665                         return false;
11666                 }
11667                 else if (type == 2) // when �0010�
11668                     // regs = 4;
11669                     regs = 4;
11670                 else // otherwise
11671                     // SEE �Related encodings�;
11672                     return false;
11673 
11674                 // alignment = if align == �00� then 1 else 4 << UInt(align);
11675                 if (align == 0)
11676                     alignment = 1;
11677                 else
11678                     alignment = 4 << align;
11679 
11680                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11681                 ebytes = 1 << Bits32 (opcode,7, 6);
11682                 esize = 8 * ebytes;
11683                 elements = 8 / ebytes;
11684 
11685                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11686                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11687                 n = Bits32 (opcode, 19, 16);
11688                 m = Bits32 (opcode, 3, 0);
11689 
11690                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11691                 wback = (m != 15);
11692                 register_index = ((m != 15) && (m != 13));
11693 
11694                 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11695                 if ((d + regs) > 32)
11696                     return false;
11697 
11698                 if (n == 15)
11699                     return false;
11700 
11701             }
11702                 break;
11703 
11704             default:
11705                 return false;
11706         }
11707 
11708         RegisterInfo base_reg;
11709         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11710 
11711         uint32_t Rn = ReadCoreReg (n, &success);
11712         if (!success)
11713             return false;
11714 
11715         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11716         addr_t address = Rn;
11717         if ((address % alignment) != 0)
11718             return false;
11719 
11720         EmulateInstruction::Context context;
11721         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11722         if (wback)
11723         {
11724             uint32_t Rm = ReadCoreReg (m, &success);
11725             if (!success)
11726                 return false;
11727 
11728             uint32_t offset;
11729             if (register_index)
11730                 offset = Rm;
11731             else
11732                 offset = 8 * regs;
11733 
11734             context.type = eContextAdjustBaseRegister;
11735             context.SetRegisterPlusOffset (base_reg, offset);
11736 
11737             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11738                 return false;
11739         }
11740 
11741         RegisterInfo data_reg;
11742         context.type = eContextRegisterStore;
11743         // for r = 0 to regs-1
11744         for (int r = 0; r < regs; ++r)
11745         {
11746             GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
11747             uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
11748             if (!success)
11749                 return false;
11750 
11751              // for e = 0 to elements-1
11752             for (int e = 0; e < elements; ++e)
11753             {
11754                 // MemU[address,ebytes] = Elem[D[d+r],e,esize];
11755                 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize);
11756 
11757                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11758                 if (!MemUWrite (context, address, word, ebytes))
11759                     return false;
11760 
11761                 // address = address + ebytes;
11762                 address = address + ebytes;
11763             }
11764         }
11765     }
11766     return true;
11767 }
11768 
11769 // A8.6.392 VST1 (single element from one lane)
11770 // This instruction stores one element to memory from one element of a register.
11771 bool
11772 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding)
11773 {
11774 #if 0
11775     if ConditionPassed() then
11776         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11777         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11778         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11779         MemU[address,ebytes] = Elem[D[d],index,esize];
11780 #endif
11781 
11782     bool success = false;
11783 
11784     if (ConditionPassed (opcode))
11785     {
11786         uint32_t ebytes;
11787         uint32_t esize;
11788         uint32_t index;
11789         uint32_t alignment;
11790         uint32_t d;
11791         uint32_t n;
11792         uint32_t m;
11793         bool wback;
11794         bool register_index;
11795 
11796         switch (encoding)
11797         {
11798             case eEncodingT1:
11799             case eEncodingA1:
11800             {
11801                 uint32_t size = Bits32 (opcode, 11, 10);
11802                 uint32_t index_align = Bits32 (opcode, 7, 4);
11803 
11804                 // if size == �11� then UNDEFINED;
11805                 if (size == 3)
11806                     return false;
11807 
11808                 // case size of
11809                 if (size == 0) // when �00�
11810                 {
11811                     // if index_align<0> != �0� then UNDEFINED;
11812                     if (BitIsClear (index_align, 0))
11813                         return false;
11814                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11815                     ebytes = 1;
11816                     esize = 8;
11817                     index = Bits32 (index_align, 3, 1);
11818                     alignment = 1;
11819                 }
11820                 else if (size == 1) // when �01�
11821                 {
11822                     // if index_align<1> != �0� then UNDEFINED;
11823                     if (BitIsClear (index_align, 1))
11824                         return false;
11825 
11826                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11827                     ebytes = 2;
11828                     esize = 16;
11829                     index = Bits32 (index_align, 3, 2);
11830 
11831                     // alignment = if index_align<0> == �0� then 1 else 2;
11832                     if (BitIsClear (index_align, 0))
11833                         alignment = 1;
11834                     else
11835                         alignment = 2;
11836                 }
11837                 else if (size == 2) // when �10�
11838                 {
11839                     // if index_align<2> != �0� then UNDEFINED;
11840                     if (BitIsClear (index_align, 2))
11841                         return false;
11842 
11843                     // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11844                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11845                         return false;
11846 
11847                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11848                     ebytes = 4;
11849                     esize = 32;
11850                     index = Bit32 (index_align, 3);
11851 
11852                     // alignment = if index_align<1:0> == �00� then 1 else 4;
11853                     if (Bits32 (index_align, 1, 0) == 0)
11854                         alignment = 1;
11855                     else
11856                         alignment = 4;
11857                 }
11858                 else
11859                 {
11860                     return false;
11861                 }
11862                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11863                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11864                 n = Bits32 (opcode, 19, 16);
11865                 m = Bits32 (opcode, 3, 0);
11866 
11867                 // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15 then UNPREDICTABLE;
11868                 wback = (m != 15);
11869                 register_index = ((m != 15) && (m != 13));
11870 
11871                 if (n == 15)
11872                     return false;
11873             }
11874                 break;
11875 
11876             default:
11877                 return false;
11878         }
11879 
11880         RegisterInfo base_reg;
11881         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11882 
11883         uint32_t Rn = ReadCoreReg (n, &success);
11884         if (!success)
11885             return false;
11886 
11887         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11888         addr_t address = Rn;
11889         if ((address % alignment) != 0)
11890             return false;
11891 
11892         EmulateInstruction::Context context;
11893         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11894         if (wback)
11895         {
11896             uint32_t Rm = ReadCoreReg (m, &success);
11897             if (!success)
11898                 return false;
11899 
11900             uint32_t offset;
11901             if (register_index)
11902                 offset = Rm;
11903             else
11904                 offset = ebytes;
11905 
11906             context.type = eContextAdjustBaseRegister;
11907             context.SetRegisterPlusOffset (base_reg, offset);
11908 
11909             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11910                 return false;
11911         }
11912 
11913         // MemU[address,ebytes] = Elem[D[d],index,esize];
11914         uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11915         if (!success)
11916             return false;
11917 
11918         uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1,  index * esize);
11919 
11920         RegisterInfo data_reg;
11921         GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg);
11922         context.type = eContextRegisterStore;
11923         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11924 
11925         if (!MemUWrite (context, address, word, ebytes))
11926             return false;
11927     }
11928     return true;
11929 }
11930 
11931 // A8.6.309 VLD1 (single element to all lanes)
11932 // This instruction loads one element from memory into every element of one or two vectors.
11933 bool
11934 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding)
11935 {
11936 #if 0
11937     if ConditionPassed() then
11938         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11939         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11940         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11941         replicated_element = Replicate(MemU[address,ebytes], elements);
11942         for r = 0 to regs-1
11943             D[d+r] = replicated_element;
11944 #endif
11945 
11946     bool success = false;
11947 
11948     if (ConditionPassed (opcode))
11949     {
11950         uint32_t ebytes;
11951         uint32_t elements;
11952         uint32_t regs;
11953         uint32_t alignment;
11954         uint32_t d;
11955         uint32_t n;
11956         uint32_t m;
11957         bool wback;
11958         bool register_index;
11959 
11960         switch (encoding)
11961         {
11962             case eEncodingT1:
11963             case eEncodingA1:
11964             {
11965                 //if size == �11� || (size == �00� && a == �1�) then UNDEFINED;
11966                 uint32_t size = Bits32 (opcode, 7, 6);
11967                 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4)))
11968                     return false;
11969 
11970                 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2;
11971                 ebytes = 1 << size;
11972                 elements = 8 / ebytes;
11973                 if (BitIsClear (opcode, 5))
11974                     regs = 1;
11975                 else
11976                     regs = 2;
11977 
11978                 //alignment = if a == �0� then 1 else ebytes;
11979                 if (BitIsClear (opcode, 4))
11980                     alignment = 1;
11981                 else
11982                     alignment = ebytes;
11983 
11984                 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11985                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11986                 n = Bits32 (opcode, 19, 16);
11987                 m = Bits32 (opcode, 3, 0);
11988 
11989                 //wback = (m != 15); register_index = (m != 15 && m != 13);
11990                 wback = (m != 15);
11991                 register_index = ((m != 15) && (m != 13));
11992 
11993                 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11994                 if ((d + regs) > 32)
11995                     return false;
11996 
11997                 if (n == 15)
11998                     return false;
11999             }
12000             break;
12001 
12002             default:
12003                 return false;
12004         }
12005 
12006         RegisterInfo base_reg;
12007         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12008 
12009         uint32_t Rn = ReadCoreReg (n, &success);
12010         if (!success)
12011             return false;
12012 
12013         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12014         addr_t address = Rn;
12015         if ((address % alignment) != 0)
12016             return false;
12017 
12018         EmulateInstruction::Context context;
12019         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12020         if (wback)
12021         {
12022             uint32_t Rm = ReadCoreReg (m, &success);
12023             if (!success)
12024                 return false;
12025 
12026             uint32_t offset;
12027             if (register_index)
12028                 offset = Rm;
12029             else
12030                 offset = ebytes;
12031 
12032             context.type = eContextAdjustBaseRegister;
12033             context.SetRegisterPlusOffset (base_reg, offset);
12034 
12035             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
12036                 return false;
12037         }
12038 
12039         // replicated_element = Replicate(MemU[address,ebytes], elements);
12040 
12041         context.type = eContextRegisterLoad;
12042         uint64_t word = MemURead (context, address, ebytes, 0, &success);
12043         if (!success)
12044             return false;
12045 
12046         uint64_t replicated_element = 0;
12047         uint32_t esize = ebytes * 8;
12048         for (int e = 0; e < elements; ++e)
12049             replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0);
12050 
12051         // for r = 0 to regs-1
12052         for (int r = 0; r < regs; ++r)
12053         {
12054             // D[d+r] = replicated_element;
12055             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element))
12056                 return false;
12057         }
12058     }
12059     return true;
12060 }
12061 
12062 // B6.2.13 SUBS PC, LR and related instructions
12063 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack.  It subtracts the
12064 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR.
12065 bool
12066 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding)
12067 {
12068 #if 0
12069     if ConditionPassed() then
12070         EncodingSpecificOperations();
12071         if CurrentInstrSet() == InstrSet_ThumbEE then
12072             UNPREDICTABLE;
12073         operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12074         case opcode of
12075             when0000result = R[n] AND operand2; // AND
12076             when0001result = R[n] EOR operand2; // EOR
12077             when0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12078             when0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12079             when0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12080             when0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12081             when0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12082             when0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12083             when1100result = R[n] OR operand2; // ORR
12084             when1101result = operand2; // MOV
12085             when1110result = R[n] AND NOT(operand2); // BIC
12086             when1111result = NOT(operand2); // MVN
12087         CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12088         BranchWritePC(result);
12089 #endif
12090 
12091     bool success = false;
12092 
12093     if (ConditionPassed (opcode))
12094     {
12095         uint32_t n;
12096         uint32_t m;
12097         uint32_t imm32;
12098         bool register_form;
12099         ARM_ShifterType shift_t;
12100         uint32_t shift_n;
12101         uint32_t code;
12102 
12103         switch (encoding)
12104         {
12105             case eEncodingT1:
12106                 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
12107                 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB
12108                 n = 14;
12109                 imm32 = Bits32 (opcode, 7, 0);
12110                 register_form = false;
12111                 code = 2;
12112 
12113                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12114                 if (InITBlock() && !LastInITBlock())
12115                     return false;
12116 
12117                 break;
12118 
12119             case eEncodingA1:
12120                 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12121                 n = Bits32 (opcode, 19, 16);
12122                 imm32 = ARMExpandImm (opcode);
12123                 register_form = false;
12124                 code = Bits32 (opcode, 24, 21);
12125 
12126                 break;
12127 
12128             case eEncodingA2:
12129                 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12130                 n = Bits32 (opcode, 19, 16);
12131                 m = Bits32 (opcode, 3, 0);
12132                 register_form = true;
12133 
12134                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12135                 shift_n = DecodeImmShiftARM (opcode, shift_t);
12136 
12137                 break;
12138 
12139             default:
12140                 return false;
12141         }
12142 
12143         // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12144         uint32_t operand2;
12145         if (register_form)
12146         {
12147             uint32_t Rm = ReadCoreReg (m, &success);
12148             if (!success)
12149                 return false;
12150 
12151             operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success);
12152             if (!success)
12153                 return false;
12154         }
12155         else
12156         {
12157             operand2 = imm32;
12158         }
12159 
12160         uint32_t Rn = ReadCoreReg (n, &success);
12161         if (!success)
12162             return false;
12163 
12164         AddWithCarryResult result;
12165 
12166         // case opcode of
12167         switch (code)
12168         {
12169             case 0: // when �0000�
12170                 // result = R[n] AND operand2; // AND
12171                 result.result = Rn & operand2;
12172                 break;
12173 
12174             case 1: // when �0001�
12175                 // result = R[n] EOR operand2; // EOR
12176                 result.result = Rn ^ operand2;
12177                 break;
12178 
12179             case 2: // when �0010�
12180                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12181                 result = AddWithCarry (Rn, ~(operand2), 1);
12182                 break;
12183 
12184             case 3: // when �0011�
12185                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12186                 result = AddWithCarry (~(Rn), operand2, 1);
12187                 break;
12188 
12189             case 4: // when �0100�
12190                 // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12191                 result = AddWithCarry (Rn, operand2, 0);
12192                 break;
12193 
12194             case 5: // when �0101�
12195                 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12196                 result = AddWithCarry (Rn, operand2, APSR_C);
12197                 break;
12198 
12199             case 6: // when �0110�
12200                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12201                 result = AddWithCarry (Rn, ~(operand2), APSR_C);
12202                 break;
12203 
12204             case 7: // when �0111�
12205                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12206                 result = AddWithCarry (~(Rn), operand2, APSR_C);
12207                 break;
12208 
12209             case 10: // when �1100�
12210                 // result = R[n] OR operand2; // ORR
12211                 result.result = Rn | operand2;
12212                 break;
12213 
12214             case 11: // when �1101�
12215                 // result = operand2; // MOV
12216                 result.result = operand2;
12217                 break;
12218 
12219             case 12: // when �1110�
12220                 // result = R[n] AND NOT(operand2); // BIC
12221                 result.result = Rn & ~(operand2);
12222                 break;
12223 
12224             case 15: // when �1111�
12225                 // result = NOT(operand2); // MVN
12226                 result.result = ~(operand2);
12227                 break;
12228 
12229             default:
12230                 return false;
12231         }
12232         // CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12233 
12234         // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for
12235         // the best.
12236         uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12237         if (!success)
12238             return false;
12239 
12240         CPSRWriteByInstr (spsr, 15, true);
12241 
12242         // BranchWritePC(result);
12243         EmulateInstruction::Context context;
12244         context.type = eContextAdjustPC;
12245         context.SetImmediate (result.result);
12246 
12247         BranchWritePC (context, result.result);
12248     }
12249     return true;
12250 }
12251 
12252 EmulateInstructionARM::ARMOpcode*
12253 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12254 {
12255     static ARMOpcode
12256     g_arm_opcodes[] =
12257     {
12258         //----------------------------------------------------------------------
12259         // Prologue instructions
12260         //----------------------------------------------------------------------
12261 
12262         // push register(s)
12263         { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12264         { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
12265 
12266         // set r7 to point to a stack offset
12267         { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
12268         { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12269         // copy the stack pointer to ip
12270         { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
12271         { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
12272         { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12273 
12274         // adjust the stack pointer
12275         { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12276         { 0x0fef0010, 0x004d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12277 
12278         // push one register
12279         // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12280         { 0x0e5f0000, 0x040d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
12281 
12282         // vector push consecutive extension register(s)
12283         { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12284         { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12285 
12286         //----------------------------------------------------------------------
12287         // Epilogue instructions
12288         //----------------------------------------------------------------------
12289 
12290         { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12291         { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12292         { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12293         { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12294 
12295         //----------------------------------------------------------------------
12296         // Supervisor Call (previously Software Interrupt)
12297         //----------------------------------------------------------------------
12298         { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12299 
12300         //----------------------------------------------------------------------
12301         // Branch instructions
12302         //----------------------------------------------------------------------
12303         { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
12304         // To resolve ambiguity, "blx <label>" should come before "bl <label>".
12305         { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12306         { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12307         { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12308         // for example, "bx lr"
12309         { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12310         // bxj
12311         { 0x0ffffff0, 0x012fff20, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12312 
12313         //----------------------------------------------------------------------
12314         // Data-processing instructions
12315         //----------------------------------------------------------------------
12316         // adc (immediate)
12317         { 0x0fe00000, 0x02a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12318         // adc (register)
12319         { 0x0fe00010, 0x00a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12320         // add (immediate)
12321         { 0x0fe00000, 0x02800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
12322         // add (register)
12323         { 0x0fe00010, 0x00800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12324         // add (register-shifted register)
12325         { 0x0fe00090, 0x00800010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12326         // adr
12327         { 0x0fff0000, 0x028f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12328         { 0x0fff0000, 0x024f0000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12329         // and (immediate)
12330         { 0x0fe00000, 0x02000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12331         // and (register)
12332         { 0x0fe00010, 0x00000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12333         // bic (immediate)
12334         { 0x0fe00000, 0x03c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12335         // bic (register)
12336         { 0x0fe00010, 0x01c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12337         // eor (immediate)
12338         { 0x0fe00000, 0x02200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12339         // eor (register)
12340         { 0x0fe00010, 0x00200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12341         // orr (immediate)
12342         { 0x0fe00000, 0x03800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12343         // orr (register)
12344         { 0x0fe00010, 0x01800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12345         // rsb (immediate)
12346         { 0x0fe00000, 0x02600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12347         // rsb (register)
12348         { 0x0fe00010, 0x00600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12349         // rsc (immediate)
12350         { 0x0fe00000, 0x02e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12351         // rsc (register)
12352         { 0x0fe00010, 0x00e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12353         // sbc (immediate)
12354         { 0x0fe00000, 0x02c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12355         // sbc (register)
12356         { 0x0fe00010, 0x00c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12357         // sub (immediate, ARM)
12358         { 0x0fe00000, 0x02400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
12359         // sub (sp minus immediate)
12360         { 0x0fef0000, 0x024d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12361         // sub (register)
12362         { 0x0fe00010, 0x00400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12363         // teq (immediate)
12364         { 0x0ff0f000, 0x03300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12365         // teq (register)
12366         { 0x0ff0f010, 0x01300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12367         // tst (immediate)
12368         { 0x0ff0f000, 0x03100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12369         // tst (register)
12370         { 0x0ff0f010, 0x01100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12371 
12372         // mov (immediate)
12373         { 0x0fef0000, 0x03a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12374         { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
12375         // mov (register)
12376         { 0x0fef0ff0, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12377         // mvn (immediate)
12378         { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12379         // mvn (register)
12380         { 0x0fef0010, 0x01e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12381         // cmn (immediate)
12382         { 0x0ff0f000, 0x03700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12383         // cmn (register)
12384         { 0x0ff0f010, 0x01700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12385         // cmp (immediate)
12386         { 0x0ff0f000, 0x03500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
12387         // cmp (register)
12388         { 0x0ff0f010, 0x01500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
12389         // asr (immediate)
12390         { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
12391         // asr (register)
12392         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
12393         // lsl (immediate)
12394         { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
12395         // lsl (register)
12396         { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
12397         // lsr (immediate)
12398         { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
12399         // lsr (register)
12400         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
12401         // rrx is a special case encoding of ror (immediate)
12402         { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
12403         // ror (immediate)
12404         { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
12405         // ror (register)
12406         { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
12407         // mul
12408         { 0x0fe000f0, 0x00000090, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
12409 
12410         // subs pc, lr and related instructions
12411         { 0x0e10f000, 0x0210f000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" },
12412         { 0x0e10f010, 0x0010f000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" },
12413 
12414         //----------------------------------------------------------------------
12415         // Load instructions
12416         //----------------------------------------------------------------------
12417         { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12418         { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
12419         { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12420         { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
12421         { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
12422         { 0x0e500010, 0x06100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
12423         { 0x0e5f0000, 0x045f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
12424         { 0xfe500010, 0x06500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
12425         { 0x0e5f00f0, 0x005f00b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12426         { 0x0e5000f0, 0x001000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"  },
12427         { 0x0e5000f0, 0x005000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
12428         { 0x0e5f00f0, 0x005f00d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
12429         { 0x0e5000f0, 0x001000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12430         { 0x0e5000f0, 0x005000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
12431         { 0x0e5f00f0, 0x005f00f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12432         { 0x0e5000f0, 0x001000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12433         { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
12434         { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12435         { 0x0e100f00, 0x0c100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12436         { 0x0e100f00, 0x0c100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12437         { 0x0f300f00, 0x0d100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12438         { 0x0f300f00, 0x0d100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12439         { 0xffb00000, 0xf4200000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12440         { 0xffb00300, 0xf4a00000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12441         { 0xffb00f00, 0xf4a00c00, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12442 
12443         //----------------------------------------------------------------------
12444         // Store instructions
12445         //----------------------------------------------------------------------
12446         { 0x0fd00000, 0x08800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12447         { 0x0fd00000, 0x08000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
12448         { 0x0fd00000, 0x09000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12449         { 0x0fd00000, 0x09800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
12450         { 0x0e500010, 0x06000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
12451         { 0x0e5000f0, 0x000000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
12452         { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
12453         { 0x0e500000, 0x04400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12454         { 0x0e500000, 0x04000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12455         { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
12456         { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12457         { 0x0e100f00, 0x0c000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12458         { 0x0e100f00, 0x0c000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12459         { 0x0f300f00, 0x0d000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
12460         { 0x0f300f00, 0x0d000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
12461         { 0xffb00000, 0xf4000000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12462         { 0xffb00300, 0xf4800000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12463 
12464         //----------------------------------------------------------------------
12465         // Other instructions
12466         //----------------------------------------------------------------------
12467         { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
12468         { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
12469         { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
12470         { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
12471         { 0xfe500000, 0xf8100000, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
12472 
12473     };
12474     static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode);
12475 
12476     for (size_t i=0; i<k_num_arm_opcodes; ++i)
12477     {
12478         if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
12479             (g_arm_opcodes[i].variants & arm_isa) != 0)
12480             return &g_arm_opcodes[i];
12481     }
12482     return NULL;
12483 }
12484 
12485 
12486 EmulateInstructionARM::ARMOpcode*
12487 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12488 {
12489 
12490     static ARMOpcode
12491     g_thumb_opcodes[] =
12492     {
12493         //----------------------------------------------------------------------
12494         // Prologue instructions
12495         //----------------------------------------------------------------------
12496 
12497         // push register(s)
12498         { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12499         { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
12500         { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
12501 
12502         // set r7 to point to a stack offset
12503         { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
12504         // copy the stack pointer to r7
12505         { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
12506         // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
12507         { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
12508 
12509         // PC-relative load into register (see also EmulateADDSPRm)
12510         { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
12511 
12512         // adjust the stack pointer
12513         { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
12514         { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
12515         { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
12516         { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
12517         { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12518 
12519         // vector push consecutive extension register(s)
12520         { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12521         { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12522 
12523         //----------------------------------------------------------------------
12524         // Epilogue instructions
12525         //----------------------------------------------------------------------
12526 
12527         { 0xfffff800, 0x0000a800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
12528         { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
12529         { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12530         { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
12531         { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
12532         { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12533         { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12534 
12535         //----------------------------------------------------------------------
12536         // Supervisor Call (previously Software Interrupt)
12537         //----------------------------------------------------------------------
12538         { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
12539 
12540         //----------------------------------------------------------------------
12541         // If Then makes up to four following instructions conditional.
12542         //----------------------------------------------------------------------
12543         // The next 5 opcode _must_ come before the if then instruction
12544         { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"},
12545         { 0xffffffff, 0x0000bf10, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
12546         { 0xffffffff, 0x0000bf20, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
12547         { 0xffffffff, 0x0000bf30, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
12548         { 0xffffffff, 0x0000bf40, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
12549         { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
12550 
12551         //----------------------------------------------------------------------
12552         // Branch instructions
12553         //----------------------------------------------------------------------
12554         // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
12555         { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
12556         { 0xfffff800, 0x0000e000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
12557         { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
12558         { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
12559         // J1 == J2 == 1
12560         { 0xf800d000, 0xf000d000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12561         // J1 == J2 == 1
12562         { 0xf800d001, 0xf000c000, ARMV5_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12563         { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12564         // for example, "bx lr"
12565         { 0xffffff87, 0x00004700, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12566         // bxj
12567         { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12568         // compare and branch
12569         { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
12570         // table branch byte
12571         { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
12572         // table branch halfword
12573         { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
12574 
12575         //----------------------------------------------------------------------
12576         // Data-processing instructions
12577         //----------------------------------------------------------------------
12578         // adc (immediate)
12579         { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
12580         // adc (register)
12581         { 0xffffffc0, 0x00004140, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
12582         { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12583         // add (register)
12584         { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
12585         // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
12586         { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
12587         // adr
12588         { 0xfffff800, 0x0000a000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12589         { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12590         { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12591         // and (immediate)
12592         { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
12593         // and (register)
12594         { 0xffffffc0, 0x00004000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
12595         { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12596         // bic (immediate)
12597         { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
12598         // bic (register)
12599         { 0xffffffc0, 0x00004380, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
12600         { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12601         // eor (immediate)
12602         { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
12603         // eor (register)
12604         { 0xffffffc0, 0x00004040, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
12605         { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12606         // orr (immediate)
12607         { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
12608         // orr (register)
12609         { 0xffffffc0, 0x00004300, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
12610         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12611         // rsb (immediate)
12612         { 0xffffffc0, 0x00004240, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
12613         { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
12614         // rsb (register)
12615         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12616         // sbc (immediate)
12617         { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12618         // sbc (register)
12619         { 0xffffffc0, 0x00004180, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
12620         { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12621         // add (immediate, Thumb)
12622         { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
12623         { 0xfffff800, 0x00003000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
12624         { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
12625         { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
12626         // sub (immediate, Thumb)
12627         { 0xfffffe00, 0x00001e00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
12628         { 0xfffff800, 0x00003800, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
12629         { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
12630         { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
12631         // sub (sp minus immediate)
12632         { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
12633         { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
12634         // sub (register)
12635         { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
12636         { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
12637         // teq (immediate)
12638         { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
12639         // teq (register)
12640         { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12641         // tst (immediate)
12642         { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
12643         // tst (register)
12644         { 0xffffffc0, 0x00004200, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
12645         { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
12646 
12647 
12648         // move from high register to high register
12649         { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
12650         // move from low register to low register
12651         { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
12652         // mov{s}<c>.w <Rd>, <Rm>
12653         { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
12654         // move immediate
12655         { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
12656         { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
12657         { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
12658         // mvn (immediate)
12659         { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
12660         // mvn (register)
12661         { 0xffffffc0, 0x000043c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
12662         { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
12663         // cmn (immediate)
12664         { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12665         // cmn (register)
12666         { 0xffffffc0, 0x000042c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
12667         { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12668         // cmp (immediate)
12669         { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
12670         { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
12671         // cmp (register) (Rn and Rm both from r0-r7)
12672         { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12673         // cmp (register) (Rn and Rm not both from r0-r7)
12674         { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12675         // asr (immediate)
12676         { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
12677         { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
12678         // asr (register)
12679         { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
12680         { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12681         // lsl (immediate)
12682         { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
12683         { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
12684         // lsl (register)
12685         { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
12686         { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
12687         // lsr (immediate)
12688         { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
12689         { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
12690         // lsr (register)
12691         { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
12692         { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12693         // rrx is a special case encoding of ror (immediate)
12694         { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
12695         // ror (immediate)
12696         { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
12697         // ror (register)
12698         { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
12699         { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
12700         // mul
12701         { 0xffffffc0, 0x00004340, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
12702         // mul
12703         { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
12704 
12705         // subs pc, lr and related instructions
12706         { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" },
12707 
12708         //----------------------------------------------------------------------
12709         // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table;
12710         // otherwise the wrong instructions will be selected.
12711         //----------------------------------------------------------------------
12712 
12713         { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
12714         { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
12715 
12716         //----------------------------------------------------------------------
12717         // Load instructions
12718         //----------------------------------------------------------------------
12719         { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12720         { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
12721         { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12722         { 0xfffff800, 0x00006800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
12723         { 0xfffff800, 0x00009800, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
12724         { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
12725         { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
12726                   // Thumb2 PC-relative load into register
12727         { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
12728         { 0xfffffe00, 0x00005800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
12729         { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
12730         { 0xfffff800, 0x00007800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
12731         { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12732         { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" },
12733         { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
12734         { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
12735         { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
12736         { 0xfffff800, 0x00008800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"  },
12737         { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12738         { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"  },
12739         { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12740         { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
12741         { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12742         { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
12743         { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12744         { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
12745         { 0xfffffe00, 0x00005600, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
12746         { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"  },
12747         { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
12748         { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12749         { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12750         { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
12751         { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12752         { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
12753         { 0xfe100f00, 0xec100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12754         { 0xfe100f00, 0xec100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
12755         { 0xffe00f00, 0xed100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12756         { 0xff300f00, 0xed100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
12757         { 0xffb00000, 0xf9200000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12758         { 0xffb00300, 0xf9a00000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12759         { 0xffb00f00, 0xf9a00c00, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12760 
12761         //----------------------------------------------------------------------
12762         // Store instructions
12763         //----------------------------------------------------------------------
12764         { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12765         { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
12766         { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12767         { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
12768         { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
12769         { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
12770         { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
12771         { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
12772         { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
12773         { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
12774         { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
12775         { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
12776         { 0xfffffe00, 0x00005200, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
12777         { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12778         { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
12779         { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
12780         { 0xfe100f00, 0xec000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12781         { 0xfea00f00, 0xec000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12782         { 0xff300f00, 0xed000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12783         { 0xff300f00, 0xed000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12784         { 0xffb00000, 0xf9000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12785         { 0xffb00300, 0xf9800000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12786 
12787         //----------------------------------------------------------------------
12788         // Other instructions
12789         //----------------------------------------------------------------------
12790         { 0xffffffc0, 0x0000b240, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
12791         { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12792         { 0xffffffc0, 0x0000b200, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
12793         { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12794         { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
12795         { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12796         { 0xffffffc0, 0x0000b280, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
12797         { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12798     };
12799 
12800     const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode);
12801     for (size_t i=0; i<k_num_thumb_opcodes; ++i)
12802     {
12803         if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
12804             (g_thumb_opcodes[i].variants & arm_isa) != 0)
12805             return &g_thumb_opcodes[i];
12806     }
12807     return NULL;
12808 }
12809 
12810 bool
12811 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
12812 {
12813     m_arch = arch;
12814     m_arm_isa = 0;
12815     const char *arch_cstr = arch.GetArchitectureName ();
12816     if (arch_cstr)
12817     {
12818         if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
12819         else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
12820         else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
12821         else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
12822         else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
12823         else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
12824         else if (0 == ::strcasecmp(arch_cstr, "armv7s"))    m_arm_isa = ARMv7S;
12825         else if (0 == ::strcasecmp(arch_cstr, "arm"))       m_arm_isa = ARMvAll;
12826         else if (0 == ::strcasecmp(arch_cstr, "thumb"))     m_arm_isa = ARMvAll;
12827         else if (0 == ::strncasecmp(arch_cstr,"armv4", 5))  m_arm_isa = ARMv4;
12828         else if (0 == ::strncasecmp(arch_cstr,"armv6", 5))  m_arm_isa = ARMv6;
12829         else if (0 == ::strncasecmp(arch_cstr,"armv7", 5))  m_arm_isa = ARMv7;
12830         else if (0 == ::strncasecmp(arch_cstr,"armv8", 5))  m_arm_isa = ARMv8;
12831     }
12832     return m_arm_isa != 0;
12833 }
12834 
12835 bool
12836 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
12837 {
12838     if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
12839     {
12840         if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
12841             m_opcode_mode = eModeThumb;
12842         else
12843         {
12844             AddressClass addr_class = inst_addr.GetAddressClass();
12845 
12846             if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
12847                 m_opcode_mode = eModeARM;
12848             else if (addr_class == eAddressClassCodeAlternateISA)
12849                 m_opcode_mode = eModeThumb;
12850             else
12851                 return false;
12852         }
12853         if (m_opcode_mode == eModeThumb)
12854             m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
12855         else
12856             m_opcode_cpsr = CPSR_MODE_USR;
12857         return true;
12858     }
12859     return false;
12860 }
12861 
12862 bool
12863 EmulateInstructionARM::ReadInstruction ()
12864 {
12865     bool success = false;
12866     m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
12867     if (success)
12868     {
12869         addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
12870         if (success)
12871         {
12872             Context read_inst_context;
12873             read_inst_context.type = eContextReadOpcode;
12874             read_inst_context.SetNoArgs ();
12875 
12876             if (m_opcode_cpsr & MASK_CPSR_T)
12877             {
12878                 m_opcode_mode = eModeThumb;
12879                 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
12880 
12881                 if (success)
12882                 {
12883                     if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
12884                     {
12885                         m_opcode.SetOpcode16 (thumb_opcode);
12886                     }
12887                     else
12888                     {
12889                         m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success));
12890                     }
12891                 }
12892             }
12893             else
12894             {
12895                 m_opcode_mode = eModeARM;
12896                 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success));
12897             }
12898         }
12899     }
12900     if (!success)
12901     {
12902         m_opcode_mode = eModeInvalid;
12903         m_addr = LLDB_INVALID_ADDRESS;
12904     }
12905     return success;
12906 }
12907 
12908 uint32_t
12909 EmulateInstructionARM::ArchVersion ()
12910 {
12911     return m_arm_isa;
12912 }
12913 
12914 bool
12915 EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional)
12916 {
12917    // If we are ignoring conditions, then always return true.
12918    // this allows us to iterate over disassembly code and still
12919    // emulate an instruction even if we don't have all the right
12920    // bits set in the CPSR register...
12921     if (m_ignore_conditions)
12922         return true;
12923 
12924     if (is_conditional)
12925         *is_conditional = true;
12926 
12927     const uint32_t cond = CurrentCond (opcode);
12928 
12929     if (cond == UINT32_MAX)
12930         return false;
12931 
12932     bool result = false;
12933     switch (UnsignedBits(cond, 3, 1))
12934     {
12935     case 0:
12936 		if (m_opcode_cpsr == 0)
12937 			result = true;
12938         else
12939             result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
12940 		break;
12941     case 1:
12942         if (m_opcode_cpsr == 0)
12943             result = true;
12944         else
12945             result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
12946 		break;
12947     case 2:
12948         if (m_opcode_cpsr == 0)
12949             result = true;
12950         else
12951             result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
12952 		break;
12953     case 3:
12954         if (m_opcode_cpsr == 0)
12955             result = true;
12956         else
12957             result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
12958 		break;
12959     case 4:
12960         if (m_opcode_cpsr == 0)
12961             result = true;
12962         else
12963             result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12964 		break;
12965     case 5:
12966         if (m_opcode_cpsr == 0)
12967             result = true;
12968         else
12969 		{
12970             bool n = (m_opcode_cpsr & MASK_CPSR_N);
12971             bool v = (m_opcode_cpsr & MASK_CPSR_V);
12972             result = n == v;
12973         }
12974         break;
12975     case 6:
12976         if (m_opcode_cpsr == 0)
12977             result = true;
12978         else
12979 		{
12980             bool n = (m_opcode_cpsr & MASK_CPSR_N);
12981             bool v = (m_opcode_cpsr & MASK_CPSR_V);
12982             result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12983         }
12984         break;
12985     case 7:
12986         // Always execute (cond == 0b1110, or the special 0b1111 which gives
12987         // opcodes different meanings, but always means execution happpens.
12988         if (is_conditional)
12989             *is_conditional = false;
12990         result = true;
12991         break;
12992     }
12993 
12994     if (cond & 1)
12995         result = !result;
12996     return result;
12997 }
12998 
12999 uint32_t
13000 EmulateInstructionARM::CurrentCond (const uint32_t opcode)
13001 {
13002     switch (m_opcode_mode)
13003     {
13004     case eModeInvalid:
13005         break;
13006 
13007     case eModeARM:
13008         return UnsignedBits(opcode, 31, 28);
13009 
13010     case eModeThumb:
13011         // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
13012         // 'cond' field of the encoding.
13013         {
13014             const uint32_t byte_size = m_opcode.GetByteSize();
13015             if (byte_size == 2)
13016             {
13017                 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f)
13018                     return Bits32(opcode, 11, 7);
13019             }
13020             else if (byte_size == 4)
13021             {
13022                 if (Bits32(opcode, 31, 27) == 0x1e &&
13023                     Bits32(opcode, 15, 14) == 0x02 &&
13024                     Bits32(opcode, 12, 12) == 0x00 &&
13025                     Bits32(opcode, 25, 22) <= 0x0d)
13026                 {
13027                     return Bits32(opcode, 25, 22);
13028                 }
13029             }
13030             else
13031                 // We have an invalid thumb instruction, let's bail out.
13032                 break;
13033 
13034             return m_it_session.GetCond();
13035         }
13036     }
13037     return UINT32_MAX;  // Return invalid value
13038 }
13039 
13040 bool
13041 EmulateInstructionARM::InITBlock()
13042 {
13043     return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13044 }
13045 
13046 bool
13047 EmulateInstructionARM::LastInITBlock()
13048 {
13049     return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13050 }
13051 
13052 bool
13053 EmulateInstructionARM::BadMode (uint32_t mode)
13054 {
13055 
13056     switch (mode)
13057     {
13058         case 16: return false; // '10000'
13059         case 17: return false; // '10001'
13060         case 18: return false; // '10010'
13061         case 19: return false; // '10011'
13062         case 22: return false; // '10110'
13063         case 23: return false; // '10111'
13064         case 27: return false; // '11011'
13065         case 31: return false; // '11111'
13066         default: return true;
13067     }
13068     return true;
13069 }
13070 
13071 bool
13072 EmulateInstructionARM::CurrentModeIsPrivileged ()
13073 {
13074     uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
13075 
13076     if (BadMode (mode))
13077         return false;
13078 
13079     if (mode == 16)
13080         return false;
13081 
13082     return true;
13083 }
13084 
13085 void
13086 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
13087 {
13088     bool privileged = CurrentModeIsPrivileged();
13089 
13090     uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20;
13091 
13092     if (BitIsSet (bytemask, 3))
13093     {
13094         tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
13095         if (affect_execstate)
13096             tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
13097     }
13098 
13099     if (BitIsSet (bytemask, 2))
13100     {
13101         tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
13102     }
13103 
13104     if (BitIsSet (bytemask, 1))
13105     {
13106         if (affect_execstate)
13107             tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
13108         tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
13109         if (privileged)
13110             tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
13111     }
13112 
13113     if (BitIsSet (bytemask, 0))
13114     {
13115         if (privileged)
13116             tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
13117         if (affect_execstate)
13118             tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
13119         if (privileged)
13120             tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
13121     }
13122 
13123     m_opcode_cpsr = tmp_cpsr;
13124 }
13125 
13126 
13127 bool
13128 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
13129 {
13130     addr_t target;
13131 
13132     // Check the current instruction set.
13133     if (CurrentInstrSet() == eModeARM)
13134         target = addr & 0xfffffffc;
13135     else
13136         target = addr & 0xfffffffe;
13137 
13138     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13139         return false;
13140 
13141     return true;
13142 }
13143 
13144 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
13145 bool
13146 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
13147 {
13148     addr_t target;
13149     // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
13150     // we want to record it and issue a WriteRegister callback so the clients
13151     // can track the mode changes accordingly.
13152     bool cpsr_changed = false;
13153 
13154     if (BitIsSet(addr, 0))
13155     {
13156         if (CurrentInstrSet() != eModeThumb)
13157         {
13158             SelectInstrSet(eModeThumb);
13159             cpsr_changed = true;
13160         }
13161         target = addr & 0xfffffffe;
13162         context.SetISA (eModeThumb);
13163     }
13164     else if (BitIsClear(addr, 1))
13165     {
13166         if (CurrentInstrSet() != eModeARM)
13167         {
13168             SelectInstrSet(eModeARM);
13169             cpsr_changed = true;
13170         }
13171         target = addr & 0xfffffffc;
13172         context.SetISA (eModeARM);
13173     }
13174     else
13175         return false; // address<1:0> == '10' => UNPREDICTABLE
13176 
13177     if (cpsr_changed)
13178     {
13179         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13180             return false;
13181     }
13182     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13183         return false;
13184 
13185     return true;
13186 }
13187 
13188 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
13189 bool
13190 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
13191 {
13192     if (ArchVersion() >= ARMv5T)
13193         return BXWritePC(context, addr);
13194     else
13195         return BranchWritePC((const Context)context, addr);
13196 }
13197 
13198 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
13199 bool
13200 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
13201 {
13202     if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
13203         return BXWritePC(context, addr);
13204     else
13205         return BranchWritePC((const Context)context, addr);
13206 }
13207 
13208 EmulateInstructionARM::Mode
13209 EmulateInstructionARM::CurrentInstrSet ()
13210 {
13211     return m_opcode_mode;
13212 }
13213 
13214 // Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
13215 // ReadInstruction() is performed.  This function has a side effect of updating
13216 // the m_new_inst_cpsr member variable if necessary.
13217 bool
13218 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
13219 {
13220     m_new_inst_cpsr = m_opcode_cpsr;
13221     switch (arm_or_thumb)
13222     {
13223     default:
13224         return false;
13225     case eModeARM:
13226         // Clear the T bit.
13227         m_new_inst_cpsr &= ~MASK_CPSR_T;
13228         break;
13229     case eModeThumb:
13230         // Set the T bit.
13231         m_new_inst_cpsr |= MASK_CPSR_T;
13232         break;
13233     }
13234     return true;
13235 }
13236 
13237 // This function returns TRUE if the processor currently provides support for
13238 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
13239 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
13240 bool
13241 EmulateInstructionARM::UnalignedSupport()
13242 {
13243     return (ArchVersion() >= ARMv7);
13244 }
13245 
13246 // The main addition and subtraction instructions can produce status information
13247 // about both unsigned carry and signed overflow conditions.  This status
13248 // information can be used to synthesize multi-word additions and subtractions.
13249 EmulateInstructionARM::AddWithCarryResult
13250 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
13251 {
13252     uint32_t result;
13253     uint8_t carry_out;
13254     uint8_t overflow;
13255 
13256     uint64_t unsigned_sum = x + y + carry_in;
13257     int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
13258 
13259     result = UnsignedBits(unsigned_sum, 31, 0);
13260 //    carry_out = (result == unsigned_sum ? 0 : 1);
13261     overflow = ((int32_t)result == signed_sum ? 0 : 1);
13262 
13263     if (carry_in)
13264         carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0;
13265     else
13266         carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0;
13267 
13268     AddWithCarryResult res = { result, carry_out, overflow };
13269     return res;
13270 }
13271 
13272 uint32_t
13273 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
13274 {
13275     uint32_t reg_kind, reg_num;
13276     switch (num)
13277     {
13278     case SP_REG:
13279         reg_kind = eRegisterKindGeneric;
13280         reg_num  = LLDB_REGNUM_GENERIC_SP;
13281         break;
13282     case LR_REG:
13283         reg_kind = eRegisterKindGeneric;
13284         reg_num  = LLDB_REGNUM_GENERIC_RA;
13285         break;
13286     case PC_REG:
13287         reg_kind = eRegisterKindGeneric;
13288         reg_num  = LLDB_REGNUM_GENERIC_PC;
13289         break;
13290     default:
13291         if (num < SP_REG)
13292         {
13293             reg_kind = eRegisterKindDWARF;
13294             reg_num  = dwarf_r0 + num;
13295         }
13296         else
13297         {
13298             //assert(0 && "Invalid register number");
13299             *success = false;
13300             return UINT32_MAX;
13301         }
13302         break;
13303     }
13304 
13305     // Read our register.
13306     uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
13307 
13308     // When executing an ARM instruction , PC reads as the address of the current
13309     // instruction plus 8.
13310     // When executing a Thumb instruction , PC reads as the address of the current
13311     // instruction plus 4.
13312     if (num == 15)
13313     {
13314         if (CurrentInstrSet() == eModeARM)
13315             val += 8;
13316         else
13317             val += 4;
13318     }
13319 
13320     return val;
13321 }
13322 
13323 // Write the result to the ARM core register Rd, and optionally update the
13324 // condition flags based on the result.
13325 //
13326 // This helper method tries to encapsulate the following pseudocode from the
13327 // ARM Architecture Reference Manual:
13328 //
13329 // if d == 15 then         // Can only occur for encoding A1
13330 //     ALUWritePC(result); // setflags is always FALSE here
13331 // else
13332 //     R[d] = result;
13333 //     if setflags then
13334 //         APSR.N = result<31>;
13335 //         APSR.Z = IsZeroBit(result);
13336 //         APSR.C = carry;
13337 //         // APSR.V unchanged
13338 //
13339 // In the above case, the API client does not pass in the overflow arg, which
13340 // defaults to ~0u.
13341 bool
13342 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
13343                                                   const uint32_t result,
13344                                                   const uint32_t Rd,
13345                                                   bool setflags,
13346                                                   const uint32_t carry,
13347                                                   const uint32_t overflow)
13348 {
13349     if (Rd == 15)
13350     {
13351         if (!ALUWritePC (context, result))
13352             return false;
13353     }
13354     else
13355     {
13356         uint32_t reg_kind, reg_num;
13357         switch (Rd)
13358         {
13359         case SP_REG:
13360             reg_kind = eRegisterKindGeneric;
13361             reg_num  = LLDB_REGNUM_GENERIC_SP;
13362             break;
13363         case LR_REG:
13364             reg_kind = eRegisterKindGeneric;
13365             reg_num  = LLDB_REGNUM_GENERIC_RA;
13366             break;
13367         default:
13368             reg_kind = eRegisterKindDWARF;
13369             reg_num  = dwarf_r0 + Rd;
13370         }
13371         if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
13372             return false;
13373         if (setflags)
13374             return WriteFlags (context, result, carry, overflow);
13375     }
13376     return true;
13377 }
13378 
13379 // This helper method tries to encapsulate the following pseudocode from the
13380 // ARM Architecture Reference Manual:
13381 //
13382 // APSR.N = result<31>;
13383 // APSR.Z = IsZeroBit(result);
13384 // APSR.C = carry;
13385 // APSR.V = overflow
13386 //
13387 // Default arguments can be specified for carry and overflow parameters, which means
13388 // not to update the respective flags.
13389 bool
13390 EmulateInstructionARM::WriteFlags (Context &context,
13391                                    const uint32_t result,
13392                                    const uint32_t carry,
13393                                    const uint32_t overflow)
13394 {
13395     m_new_inst_cpsr = m_opcode_cpsr;
13396     SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
13397     SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
13398     if (carry != ~0u)
13399         SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
13400     if (overflow != ~0u)
13401         SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
13402     if (m_new_inst_cpsr != m_opcode_cpsr)
13403     {
13404         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13405             return false;
13406     }
13407     return true;
13408 }
13409 
13410 bool
13411 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
13412 {
13413     // Advance the ITSTATE bits to their values for the next instruction.
13414     if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
13415         m_it_session.ITAdvance();
13416 
13417     ARMOpcode *opcode_data = NULL;
13418 
13419     if (m_opcode_mode == eModeThumb)
13420         opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13421     else if (m_opcode_mode == eModeARM)
13422         opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13423 
13424     if (opcode_data == NULL)
13425         return false;
13426 
13427     const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
13428     m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
13429 
13430     bool success = false;
13431     if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
13432     {
13433         m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF,
13434                                                 dwarf_cpsr,
13435                                                 0,
13436                                                 &success);
13437     }
13438 
13439     // Only return false if we are unable to read the CPSR if we care about conditions
13440     if (success == false && m_ignore_conditions == false)
13441         return false;
13442 
13443     uint32_t orig_pc_value = 0;
13444     if (auto_advance_pc)
13445     {
13446         orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13447         if (!success)
13448             return false;
13449     }
13450 
13451     // Call the Emulate... function.
13452     success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
13453     if (!success)
13454         return false;
13455 
13456     if (auto_advance_pc)
13457     {
13458         uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13459         if (!success)
13460             return false;
13461 
13462         if (auto_advance_pc && (after_pc_value == orig_pc_value))
13463         {
13464             if (opcode_data->size == eSize32)
13465                 after_pc_value += 4;
13466             else if (opcode_data->size == eSize16)
13467                 after_pc_value += 2;
13468 
13469             EmulateInstruction::Context context;
13470             context.type = eContextAdvancePC;
13471             context.SetNoArgs();
13472             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
13473                 return false;
13474 
13475         }
13476     }
13477     return true;
13478 }
13479 
13480 bool
13481 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data)
13482 {
13483     if (!test_data)
13484     {
13485         out_stream->Printf ("TestEmulation: Missing test data.\n");
13486         return false;
13487     }
13488 
13489     static ConstString opcode_key ("opcode");
13490     static ConstString before_key ("before_state");
13491     static ConstString after_key ("after_state");
13492 
13493     OptionValueSP value_sp = test_data->GetValueForKey (opcode_key);
13494 
13495     uint32_t test_opcode;
13496     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64))
13497     {
13498         out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n");
13499         return false;
13500     }
13501     test_opcode = value_sp->GetUInt64Value ();
13502 
13503     if (arch.GetTriple().getArch() == llvm::Triple::arm)
13504     {
13505         m_opcode_mode = eModeARM;
13506         m_opcode.SetOpcode32 (test_opcode);
13507     }
13508     else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
13509     {
13510         m_opcode_mode = eModeThumb;
13511         if (test_opcode < 0x10000)
13512             m_opcode.SetOpcode16 (test_opcode);
13513         else
13514             m_opcode.SetOpcode32 (test_opcode);
13515 
13516     }
13517     else
13518     {
13519         out_stream->Printf ("TestEmulation:  Invalid arch.\n");
13520         return false;
13521     }
13522 
13523     EmulationStateARM before_state;
13524     EmulationStateARM after_state;
13525 
13526     value_sp = test_data->GetValueForKey (before_key);
13527     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13528     {
13529         out_stream->Printf ("TestEmulation:  Failed to find 'before' state.\n");
13530         return false;
13531     }
13532 
13533     OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary ();
13534     if (!before_state.LoadStateFromDictionary (state_dictionary))
13535     {
13536         out_stream->Printf ("TestEmulation:  Failed loading 'before' state.\n");
13537         return false;
13538     }
13539 
13540     value_sp = test_data->GetValueForKey (after_key);
13541     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13542     {
13543         out_stream->Printf ("TestEmulation:  Failed to find 'after' state.\n");
13544         return false;
13545     }
13546 
13547     state_dictionary = value_sp->GetAsDictionary ();
13548     if (!after_state.LoadStateFromDictionary (state_dictionary))
13549     {
13550         out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n");
13551         return false;
13552     }
13553 
13554     SetBaton ((void *) &before_state);
13555     SetCallbacks (&EmulationStateARM::ReadPseudoMemory,
13556                   &EmulationStateARM::WritePseudoMemory,
13557                   &EmulationStateARM::ReadPseudoRegister,
13558                   &EmulationStateARM::WritePseudoRegister);
13559 
13560     bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC);
13561     if (!success)
13562     {
13563         out_stream->Printf ("TestEmulation:  EvaluateInstruction() failed.\n");
13564         return false;
13565     }
13566 
13567     success = before_state.CompareState (after_state);
13568     if (!success)
13569         out_stream->Printf ("TestEmulation:  'before' and 'after' states do not match.\n");
13570 
13571     return success;
13572 }
13573 //
13574 //
13575 //const char *
13576 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
13577 //{
13578 //    if (reg_kind == eRegisterKindGeneric)
13579 //    {
13580 //        switch (reg_num)
13581 //        {
13582 //        case LLDB_REGNUM_GENERIC_PC:    return "pc";
13583 //        case LLDB_REGNUM_GENERIC_SP:    return "sp";
13584 //        case LLDB_REGNUM_GENERIC_FP:    return "fp";
13585 //        case LLDB_REGNUM_GENERIC_RA:    return "lr";
13586 //        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
13587 //        default: return NULL;
13588 //        }
13589 //    }
13590 //    else if (reg_kind == eRegisterKindDWARF)
13591 //    {
13592 //        return GetARMDWARFRegisterName (reg_num);
13593 //    }
13594 //    return NULL;
13595 //}
13596 //
13597 bool
13598 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
13599 {
13600     unwind_plan.Clear();
13601     unwind_plan.SetRegisterKind (eRegisterKindDWARF);
13602 
13603     UnwindPlan::RowSP row(new UnwindPlan::Row);
13604 
13605     // Our previous Call Frame Address is the stack pointer
13606     row->SetCFARegister (dwarf_sp);
13607 
13608     // Our previous PC is in the LR
13609     row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true);
13610     unwind_plan.AppendRow (row);
13611 
13612     // All other registers are the same.
13613 
13614     unwind_plan.SetSourceName ("EmulateInstructionARM");
13615     unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
13616     unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
13617     return true;
13618 }
13619