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 "lldb/Core/ArchSpec.h"
14 #include "lldb/Core/Address.h"
15 #include "lldb/Core/ConstString.h"
16 #include "lldb/Core/PluginManager.h"
17 
18 #include "Plugins/Process/Utility/ARMDefines.h"
19 #include "Plugins/Process/Utility/ARMUtils.h"
20 #include "Utility/ARM_DWARF_Registers.h"
21 
22 #include "llvm/Support/MathExtras.h" // for SignExtend32 template function
23                                      // and CountTrailingZeros_32 function
24 
25 using namespace lldb;
26 using namespace lldb_private;
27 
28 // Convenient macro definitions.
29 #define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS)
30 #define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS)
31 
32 #define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
33 
34 //----------------------------------------------------------------------
35 //
36 // ITSession implementation
37 //
38 //----------------------------------------------------------------------
39 
40 // A8.6.50
41 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
42 static unsigned short CountITSize(unsigned ITMask) {
43     // First count the trailing zeros of the IT mask.
44     unsigned TZ = llvm::CountTrailingZeros_32(ITMask);
45     if (TZ > 3)
46     {
47         printf("Encoding error: IT Mask '0000'\n");
48         return 0;
49     }
50     return (4 - TZ);
51 }
52 
53 // Init ITState.  Note that at least one bit is always 1 in mask.
54 bool ITSession::InitIT(unsigned short bits7_0)
55 {
56     ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
57     if (ITCounter == 0)
58         return false;
59 
60     // A8.6.50 IT
61     unsigned short FirstCond = Bits32(bits7_0, 7, 4);
62     if (FirstCond == 0xF)
63     {
64         printf("Encoding error: IT FirstCond '1111'\n");
65         return false;
66     }
67     if (FirstCond == 0xE && ITCounter != 1)
68     {
69         printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
70         return false;
71     }
72 
73     ITState = bits7_0;
74     return true;
75 }
76 
77 // Update ITState if necessary.
78 void ITSession::ITAdvance()
79 {
80     assert(ITCounter);
81     --ITCounter;
82     if (ITCounter == 0)
83         ITState = 0;
84     else
85     {
86         unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
87         SetBits32(ITState, 4, 0, NewITState4_0);
88     }
89 }
90 
91 // Return true if we're inside an IT Block.
92 bool ITSession::InITBlock()
93 {
94     return ITCounter != 0;
95 }
96 
97 // Return true if we're the last instruction inside an IT Block.
98 bool ITSession::LastInITBlock()
99 {
100     return ITCounter == 1;
101 }
102 
103 // Get condition bits for the current thumb instruction.
104 uint32_t ITSession::GetCond()
105 {
106     if (InITBlock())
107         return Bits32(ITState, 7, 4);
108     else
109         return COND_AL;
110 }
111 
112 // ARM constants used during decoding
113 #define REG_RD          0
114 #define LDM_REGLIST     1
115 #define SP_REG          13
116 #define LR_REG          14
117 #define PC_REG          15
118 #define PC_REGLIST_BIT  0x8000
119 
120 #define ARMv4     (1u << 0)
121 #define ARMv4T    (1u << 1)
122 #define ARMv5T    (1u << 2)
123 #define ARMv5TE   (1u << 3)
124 #define ARMv5TEJ  (1u << 4)
125 #define ARMv6     (1u << 5)
126 #define ARMv6K    (1u << 6)
127 #define ARMv6T2   (1u << 7)
128 #define ARMv7     (1u << 8)
129 #define ARMv8     (1u << 9)
130 #define ARMvAll   (0xffffffffu)
131 
132 #define ARMV4T_ABOVE  (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
133 #define ARMV5_ABOVE   (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
134 #define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
135 #define ARMV5J_ABOVE  (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
136 #define ARMV6_ABOVE   (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv8)
137 #define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv8)
138 
139 #define No_VFP  0
140 #define VFPv1   (1u << 1)
141 #define VFPv2   (1u << 2)
142 #define VFPv3   (1u << 3)
143 #define AdvancedSIMD (1u << 4)
144 
145 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
146 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
147 #define VFPv2v3     (VFPv2 | VFPv3)
148 
149 //----------------------------------------------------------------------
150 //
151 // EmulateInstructionARM implementation
152 //
153 //----------------------------------------------------------------------
154 
155 void
156 EmulateInstructionARM::Initialize ()
157 {
158     PluginManager::RegisterPlugin (GetPluginNameStatic (),
159                                    GetPluginDescriptionStatic (),
160                                    CreateInstance);
161 }
162 
163 void
164 EmulateInstructionARM::Terminate ()
165 {
166     PluginManager::UnregisterPlugin (CreateInstance);
167 }
168 
169 const char *
170 EmulateInstructionARM::GetPluginNameStatic ()
171 {
172     return "lldb.emulate-instruction.arm";
173 }
174 
175 const char *
176 EmulateInstructionARM::GetPluginDescriptionStatic ()
177 {
178     return "Emulate instructions for the ARM architecture.";
179 }
180 
181 EmulateInstruction *
182 EmulateInstructionARM::CreateInstance (const ArchSpec &arch)
183 {
184     if (arch.GetTriple().getArch() == llvm::Triple::arm)
185     {
186         std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
187 
188         if (emulate_insn_ap.get())
189             return emulate_insn_ap.release();
190     }
191     else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
192     {
193         std::auto_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
194 
195         if (emulate_insn_ap.get())
196             return emulate_insn_ap.release();
197     }
198 
199     return NULL;
200 }
201 
202 bool
203 EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch)
204 {
205     if (arch.GetTriple().getArch () == llvm::Triple::arm)
206         return true;
207     else if (arch.GetTriple().getArch () == llvm::Triple::thumb)
208         return true;
209 
210     return false;
211 }
212 
213 // Write "bits (32) UNKNOWN" to memory address "address".  Helper function for many ARM instructions.
214 bool
215 EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address)
216 {
217     EmulateInstruction::Context context;
218     context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
219     context.SetNoArgs ();
220 
221     uint32_t random_data = rand ();
222     const uint32_t addr_byte_size = GetAddressByteSize();
223 
224     if (!MemAWrite (context, address, random_data, addr_byte_size))
225         return false;
226 
227     return true;
228 }
229 
230 // Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM instructions.
231 bool
232 EmulateInstructionARM::WriteBits32Unknown (int n)
233 {
234     EmulateInstruction::Context context;
235     context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
236     context.SetNoArgs ();
237 
238     bool success;
239     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
240 
241     if (!success)
242         return false;
243 
244     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
245         return false;
246 
247     return true;
248 }
249 
250 // Push Multiple Registers stores multiple registers to the stack, storing to
251 // consecutive memory locations ending just below the address in SP, and updates
252 // SP to point to the start of the stored data.
253 bool
254 EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding)
255 {
256 #if 0
257     // ARM pseudo code...
258     if (ConditionPassed())
259     {
260         EncodingSpecificOperations();
261         NullCheckIfThumbEE(13);
262         address = SP - 4*BitCount(registers);
263 
264         for (i = 0 to 14)
265         {
266             if (registers<i> == '1')
267             {
268                 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
269                     MemA[address,4] = bits(32) UNKNOWN;
270                 else
271                     MemA[address,4] = R[i];
272                 address = address + 4;
273             }
274         }
275 
276         if (registers<15> == '1') // Only possible for encoding A1 or A2
277             MemA[address,4] = PCStoreValue();
278 
279         SP = SP - 4*BitCount(registers);
280     }
281 #endif
282 
283     bool success = false;
284     if (ConditionPassed(opcode))
285     {
286         const uint32_t addr_byte_size = GetAddressByteSize();
287         const addr_t sp = ReadCoreReg (SP_REG, &success);
288         if (!success)
289             return false;
290         uint32_t registers = 0;
291         uint32_t Rt; // the source register
292         switch (encoding) {
293         case eEncodingT1:
294             registers = Bits32(opcode, 7, 0);
295             // The M bit represents LR.
296             if (Bit32(opcode, 8))
297                 registers |= (1u << 14);
298             // if BitCount(registers) < 1 then UNPREDICTABLE;
299             if (BitCount(registers) < 1)
300                 return false;
301             break;
302         case eEncodingT2:
303             // Ignore bits 15 & 13.
304             registers = Bits32(opcode, 15, 0) & ~0xa000;
305             // if BitCount(registers) < 2 then UNPREDICTABLE;
306             if (BitCount(registers) < 2)
307                 return false;
308             break;
309         case eEncodingT3:
310             Rt = Bits32(opcode, 15, 12);
311             // if BadReg(t) then UNPREDICTABLE;
312             if (BadReg(Rt))
313                 return false;
314             registers = (1u << Rt);
315             break;
316         case eEncodingA1:
317             registers = Bits32(opcode, 15, 0);
318             // Instead of return false, let's handle the following case as well,
319             // which amounts to pushing one reg onto the full descending stacks.
320             // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
321             break;
322         case eEncodingA2:
323             Rt = Bits32(opcode, 15, 12);
324             // if t == 13 then UNPREDICTABLE;
325             if (Rt == dwarf_sp)
326                 return false;
327             registers = (1u << Rt);
328             break;
329         default:
330             return false;
331         }
332         addr_t sp_offset = addr_byte_size * BitCount (registers);
333         addr_t addr = sp - sp_offset;
334         uint32_t i;
335 
336         EmulateInstruction::Context context;
337         context.type = EmulateInstruction::eContextPushRegisterOnStack;
338         Register dwarf_reg;
339         dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
340         Register sp_reg;
341         sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
342         for (i=0; i<15; ++i)
343         {
344             if (BitIsSet (registers, i))
345             {
346                 dwarf_reg.num = dwarf_r0 + i;
347                 context.SetRegisterToRegisterPlusOffset (dwarf_reg, sp_reg, addr - sp);
348                 uint32_t reg_value = ReadCoreReg(i, &success);
349                 if (!success)
350                     return false;
351                 if (!MemAWrite (context, addr, reg_value, addr_byte_size))
352                     return false;
353                 addr += addr_byte_size;
354             }
355         }
356 
357         if (BitIsSet (registers, 15))
358         {
359             dwarf_reg.num = dwarf_pc;
360             context.SetRegisterPlusOffset (dwarf_reg, addr - sp);
361             const uint32_t pc = ReadCoreReg(PC_REG, &success);
362             if (!success)
363                 return false;
364             if (!MemAWrite (context, addr, pc, addr_byte_size))
365                 return false;
366         }
367 
368         context.type = EmulateInstruction::eContextAdjustStackPointer;
369         context.SetImmediateSigned (-sp_offset);
370 
371         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
372             return false;
373     }
374     return true;
375 }
376 
377 // Pop Multiple Registers loads multiple registers from the stack, loading from
378 // consecutive memory locations staring at the address in SP, and updates
379 // SP to point just above the loaded data.
380 bool
381 EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding)
382 {
383 #if 0
384     // ARM pseudo code...
385     if (ConditionPassed())
386     {
387         EncodingSpecificOperations(); NullCheckIfThumbEE(13);
388         address = SP;
389         for i = 0 to 14
390             if registers<i> == '1' then
391                 R[i} = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
392         if registers<15> == '1' then
393             if UnalignedAllowed then
394                 LoadWritePC(MemU[address,4]);
395             else
396                 LoadWritePC(MemA[address,4]);
397         if registers<13> == '0' then SP = SP + 4*BitCount(registers);
398         if registers<13> == '1' then SP = bits(32) UNKNOWN;
399     }
400 #endif
401 
402     bool success = false;
403 
404     if (ConditionPassed(opcode))
405     {
406         const uint32_t addr_byte_size = GetAddressByteSize();
407         const addr_t sp = ReadCoreReg (SP_REG, &success);
408         if (!success)
409             return false;
410         uint32_t registers = 0;
411         uint32_t Rt; // the destination register
412         switch (encoding) {
413         case eEncodingT1:
414             registers = Bits32(opcode, 7, 0);
415             // The P bit represents PC.
416             if (Bit32(opcode, 8))
417                 registers |= (1u << 15);
418             // if BitCount(registers) < 1 then UNPREDICTABLE;
419             if (BitCount(registers) < 1)
420                 return false;
421             break;
422         case eEncodingT2:
423             // Ignore bit 13.
424             registers = Bits32(opcode, 15, 0) & ~0x2000;
425             // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
426             if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
427                 return false;
428             // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
429             if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
430                 return false;
431             break;
432         case eEncodingT3:
433             Rt = Bits32(opcode, 15, 12);
434             // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
435             if (Rt == 13)
436                 return false;
437             if (Rt == 15 && InITBlock() && !LastInITBlock())
438                 return false;
439             registers = (1u << Rt);
440             break;
441         case eEncodingA1:
442             registers = Bits32(opcode, 15, 0);
443             // Instead of return false, let's handle the following case as well,
444             // which amounts to popping one reg from the full descending stacks.
445             // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
446 
447             // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
448             if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
449                 return false;
450             break;
451         case eEncodingA2:
452             Rt = Bits32(opcode, 15, 12);
453             // if t == 13 then UNPREDICTABLE;
454             if (Rt == dwarf_sp)
455                 return false;
456             registers = (1u << Rt);
457             break;
458         default:
459             return false;
460         }
461         addr_t sp_offset = addr_byte_size * BitCount (registers);
462         addr_t addr = sp;
463         uint32_t i, data;
464 
465         EmulateInstruction::Context context;
466         context.type = EmulateInstruction::eContextPopRegisterOffStack;
467         Register dwarf_reg;
468         dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
469         Register sp_reg;
470         sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
471         for (i=0; i<15; ++i)
472         {
473             if (BitIsSet (registers, i))
474             {
475                 dwarf_reg.num = dwarf_r0 + i;
476                 context.SetRegisterPlusOffset (sp_reg, addr - sp);
477                 data = MemARead(context, addr, 4, 0, &success);
478                 if (!success)
479                     return false;
480                 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data))
481                     return false;
482                 addr += addr_byte_size;
483             }
484         }
485 
486         if (BitIsSet (registers, 15))
487         {
488             dwarf_reg.num = dwarf_pc;
489             context.SetRegisterPlusOffset (sp_reg, addr - sp);
490             data = MemARead(context, addr, 4, 0, &success);
491             if (!success)
492                 return false;
493             // In ARMv5T and above, this is an interworking branch.
494             if (!LoadWritePC(context, data))
495                 return false;
496             addr += addr_byte_size;
497         }
498 
499         context.type = EmulateInstruction::eContextAdjustStackPointer;
500         context.SetImmediateSigned (sp_offset);
501 
502         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
503             return false;
504     }
505     return true;
506 }
507 
508 // Set r7 or ip to point to saved value residing within the stack.
509 // ADD (SP plus immediate)
510 bool
511 EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding)
512 {
513 #if 0
514     // ARM pseudo code...
515     if (ConditionPassed())
516     {
517         EncodingSpecificOperations();
518         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
519         if d == 15 then
520            ALUWritePC(result); // setflags is always FALSE here
521         else
522             R[d] = result;
523             if setflags then
524                 APSR.N = result<31>;
525                 APSR.Z = IsZeroBit(result);
526                 APSR.C = carry;
527                 APSR.V = overflow;
528     }
529 #endif
530 
531     bool success = false;
532 
533     if (ConditionPassed(opcode))
534     {
535         const addr_t sp = ReadCoreReg (SP_REG, &success);
536         if (!success)
537             return false;
538         uint32_t Rd; // the destination register
539         uint32_t imm32;
540         switch (encoding) {
541         case eEncodingT1:
542             Rd = 7;
543             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
544             break;
545         case eEncodingA1:
546             Rd = Bits32(opcode, 15, 12);
547             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
548             break;
549         default:
550             return false;
551         }
552         addr_t sp_offset = imm32;
553         addr_t addr = sp + sp_offset; // a pointer to the stack area
554 
555         EmulateInstruction::Context context;
556         context.type = EmulateInstruction::eContextAdjustStackPointer;
557         Register sp_reg;
558         sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
559         context.SetRegisterPlusOffset (sp_reg, sp_offset);
560 
561         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
562             return false;
563     }
564     return true;
565 }
566 
567 // Set r7 or ip to the current stack pointer.
568 // MOV (register)
569 bool
570 EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding)
571 {
572 #if 0
573     // ARM pseudo code...
574     if (ConditionPassed())
575     {
576         EncodingSpecificOperations();
577         result = R[m];
578         if d == 15 then
579             ALUWritePC(result); // setflags is always FALSE here
580         else
581             R[d] = result;
582             if setflags then
583                 APSR.N = result<31>;
584                 APSR.Z = IsZeroBit(result);
585                 // APSR.C unchanged
586                 // APSR.V unchanged
587     }
588 #endif
589 
590     bool success = false;
591 
592     if (ConditionPassed(opcode))
593     {
594         const addr_t sp = ReadCoreReg (SP_REG, &success);
595         if (!success)
596             return false;
597         uint32_t Rd; // the destination register
598         switch (encoding) {
599         case eEncodingT1:
600             Rd = 7;
601             break;
602         case eEncodingA1:
603             Rd = 12;
604             break;
605         default:
606             return false;
607         }
608 
609         EmulateInstruction::Context context;
610         context.type = EmulateInstruction::eContextRegisterPlusOffset;
611         Register sp_reg;
612         sp_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
613         context.SetRegisterPlusOffset (sp_reg, 0);
614 
615         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
616             return false;
617     }
618     return true;
619 }
620 
621 // Move from high register (r8-r15) to low register (r0-r7).
622 // MOV (register)
623 bool
624 EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding)
625 {
626     return EmulateMOVRdRm (opcode, encoding);
627 }
628 
629 // Move from register to register.
630 // MOV (register)
631 bool
632 EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding)
633 {
634 #if 0
635     // ARM pseudo code...
636     if (ConditionPassed())
637     {
638         EncodingSpecificOperations();
639         result = R[m];
640         if d == 15 then
641             ALUWritePC(result); // setflags is always FALSE here
642         else
643             R[d] = result;
644             if setflags then
645                 APSR.N = result<31>;
646                 APSR.Z = IsZeroBit(result);
647                 // APSR.C unchanged
648                 // APSR.V unchanged
649     }
650 #endif
651 
652     bool success = false;
653 
654     if (ConditionPassed(opcode))
655     {
656         uint32_t Rm; // the source register
657         uint32_t Rd; // the destination register
658         bool setflags;
659         switch (encoding) {
660         case eEncodingT1:
661             Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
662             Rm = Bits32(opcode, 6, 3);
663             setflags = false;
664             if (Rd == 15 && InITBlock() && !LastInITBlock())
665                 return false;
666             break;
667         case eEncodingT2:
668             Rd = Bits32(opcode, 2, 0);
669             Rm = Bits32(opcode, 5, 3);
670             setflags = true;
671             if (InITBlock())
672                 return false;
673             break;
674         case eEncodingT3:
675             Rd = Bits32(opcode, 11, 8);
676             Rm = Bits32(opcode, 3, 0);
677             setflags = BitIsSet(opcode, 20);
678             // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
679             if (setflags && (BadReg(Rd) || BadReg(Rm)))
680                 return false;
681             // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE;
682             if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
683                 return false;
684             break;
685         case eEncodingA1:
686             Rd = Bits32(opcode, 15, 12);
687             Rm = Bits32(opcode, 3, 0);
688             setflags = BitIsSet(opcode, 20);
689 
690             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
691             if (Rd == 15 && setflags)
692                 return EmulateSUBSPcLrEtc (opcode, encoding);
693             break;
694         default:
695             return false;
696         }
697         uint32_t result = ReadCoreReg(Rm, &success);
698         if (!success)
699             return false;
700 
701         // The context specifies that Rm is to be moved into Rd.
702         EmulateInstruction::Context context;
703         context.type = EmulateInstruction::eContextRegisterLoad;
704         Register dwarf_reg;
705         dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
706         context.SetRegister (dwarf_reg);
707 
708         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
709             return false;
710     }
711     return true;
712 }
713 
714 // Move (immediate) writes an immediate value to the destination register.  It
715 // can optionally update the condition flags based on the value.
716 // MOV (immediate)
717 bool
718 EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding)
719 {
720 #if 0
721     // ARM pseudo code...
722     if (ConditionPassed())
723     {
724         EncodingSpecificOperations();
725         result = imm32;
726         if d == 15 then         // Can only occur for ARM encoding
727             ALUWritePC(result); // setflags is always FALSE here
728         else
729             R[d] = result;
730             if setflags then
731                 APSR.N = result<31>;
732                 APSR.Z = IsZeroBit(result);
733                 APSR.C = carry;
734                 // APSR.V unchanged
735     }
736 #endif
737 
738     if (ConditionPassed(opcode))
739     {
740         uint32_t Rd; // the destination register
741         uint32_t imm32; // the immediate value to be written to Rd
742         uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
743         bool setflags;
744         switch (encoding) {
745             case eEncodingT1:
746                 Rd = Bits32(opcode, 10, 8);
747                 setflags = !InITBlock();
748                 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
749                 carry = APSR_C;
750 
751                 break;
752 
753             case eEncodingT2:
754                 Rd = Bits32(opcode, 11, 8);
755                 setflags = BitIsSet(opcode, 20);
756                 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
757                 if (BadReg(Rd))
758                   return false;
759 
760                 break;
761 
762             case eEncodingT3:
763             {
764                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32);
765                 Rd = Bits32 (opcode, 11, 8);
766                 setflags = false;
767                 uint32_t imm4 = Bits32 (opcode, 19, 16);
768                 uint32_t imm3 = Bits32 (opcode, 14, 12);
769                 uint32_t i = Bit32 (opcode, 26);
770                 uint32_t imm8 = Bits32 (opcode, 7, 0);
771                 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
772 
773                 // if BadReg(d) then UNPREDICTABLE;
774                 if (BadReg (Rd))
775                     return false;
776             }
777                 break;
778 
779             case eEncodingA1:
780                 // d = UInt(Rd); setflags = (S == ‘1’); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C);
781                 Rd = Bits32 (opcode, 15, 12);
782                 setflags = BitIsSet (opcode, 20);
783                 imm32 = ARMExpandImm_C (opcode, APSR_C, carry);
784 
785                 // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions;
786                 if ((Rd == 15) && setflags)
787                     return EmulateSUBSPcLrEtc (opcode, encoding);
788 
789                 break;
790 
791             case eEncodingA2:
792             {
793                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
794                 Rd = Bits32 (opcode, 15, 12);
795                 setflags = false;
796                 uint32_t imm4 = Bits32 (opcode, 19, 16);
797                 uint32_t imm12 = Bits32 (opcode, 11, 0);
798                 imm32 = (imm4 << 12) | imm12;
799 
800                 // if d == 15 then UNPREDICTABLE;
801                 if (Rd == 15)
802                     return false;
803             }
804                 break;
805 
806             default:
807                 return false;
808         }
809         uint32_t result = imm32;
810 
811         // The context specifies that an immediate is to be moved into Rd.
812         EmulateInstruction::Context context;
813         context.type = EmulateInstruction::eContextImmediate;
814         context.SetNoArgs ();
815 
816         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
817             return false;
818     }
819     return true;
820 }
821 
822 // MUL multiplies two register values.  The least significant 32 bits of the result are written to the destination
823 // register.  These 32 bits do not depend on whether the source register values are considered to be signed values or
824 // unsigned values.
825 //
826 // Optionally, it can update the condition flags based on the result.  In the Thumb instruction set, this option is
827 // limited to only a few forms of the instruction.
828 bool
829 EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding)
830 {
831 #if 0
832     if ConditionPassed() then
833         EncodingSpecificOperations();
834         operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
835         operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
836         result = operand1 * operand2;
837         R[d] = result<31:0>;
838         if setflags then
839             APSR.N = result<31>;
840             APSR.Z = IsZeroBit(result);
841             if ArchVersion() == 4 then
842                 APSR.C = bit UNKNOWN;
843             // else APSR.C unchanged
844             // APSR.V always unchanged
845 #endif
846 
847     if (ConditionPassed(opcode))
848     {
849         uint32_t d;
850         uint32_t n;
851         uint32_t m;
852         bool setflags;
853 
854         // EncodingSpecificOperations();
855         switch (encoding)
856         {
857             case eEncodingT1:
858                 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
859                 d = Bits32 (opcode, 2, 0);
860                 n = Bits32 (opcode, 5, 3);
861                 m = Bits32 (opcode, 2, 0);
862                 setflags = !InITBlock();
863 
864                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
865                 if ((ArchVersion() < ARMv6) && (d == n))
866                     return false;
867 
868                 break;
869 
870             case eEncodingT2:
871                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
872                 d = Bits32 (opcode, 11, 8);
873                 n = Bits32 (opcode, 19, 16);
874                 m = Bits32 (opcode, 3, 0);
875                 setflags = false;
876 
877                 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
878                 if (BadReg (d) || BadReg (n) || BadReg (m))
879                     return false;
880 
881                 break;
882 
883             case eEncodingA1:
884                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
885                 d = Bits32 (opcode, 19, 16);
886                 n = Bits32 (opcode, 3, 0);
887                 m = Bits32 (opcode, 11, 8);
888                 setflags = BitIsSet (opcode, 20);
889 
890                 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
891                 if ((d == 15) ||  (n == 15) || (m == 15))
892                     return false;
893 
894                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
895                 if ((ArchVersion() < ARMv6) && (d == n))
896                     return false;
897 
898                 break;
899 
900             default:
901                 return false;
902         }
903 
904         bool success = false;
905 
906         // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
907         uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
908         if (!success)
909             return false;
910 
911         // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
912         uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
913         if (!success)
914             return false;
915 
916         // result = operand1 * operand2;
917         uint64_t result = operand1 * operand2;
918 
919         // R[d] = result<31:0>;
920         Register op1_reg;
921         Register op2_reg;
922         op1_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
923         op2_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
924 
925         EmulateInstruction::Context context;
926         context.type = eContextMultiplication;
927         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
928 
929         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result)))
930             return false;
931 
932         // if setflags then
933         if (setflags)
934         {
935             // APSR.N = result<31>;
936             // APSR.Z = IsZeroBit(result);
937             m_new_inst_cpsr = m_opcode_cpsr;
938             SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31));
939             SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
940             if (m_new_inst_cpsr != m_opcode_cpsr)
941             {
942                 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
943                     return false;
944             }
945 
946             // if ArchVersion() == 4 then
947                 // APSR.C = bit UNKNOWN;
948         }
949     }
950     return true;
951 }
952 
953 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register.
954 // It can optionally update the condition flags based on the value.
955 bool
956 EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding)
957 {
958 #if 0
959     // ARM pseudo code...
960     if (ConditionPassed())
961     {
962         EncodingSpecificOperations();
963         result = NOT(imm32);
964         if d == 15 then         // Can only occur for ARM encoding
965             ALUWritePC(result); // setflags is always FALSE here
966         else
967             R[d] = result;
968             if setflags then
969                 APSR.N = result<31>;
970                 APSR.Z = IsZeroBit(result);
971                 APSR.C = carry;
972                 // APSR.V unchanged
973     }
974 #endif
975 
976     if (ConditionPassed(opcode))
977     {
978         uint32_t Rd; // the destination register
979         uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
980         uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
981         bool setflags;
982         switch (encoding) {
983         case eEncodingT1:
984             Rd = Bits32(opcode, 11, 8);
985             setflags = BitIsSet(opcode, 20);
986             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
987             break;
988         case eEncodingA1:
989             Rd = Bits32(opcode, 15, 12);
990             setflags = BitIsSet(opcode, 20);
991             imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
992 
993             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
994             if (Rd == 15 && setflags)
995                 return EmulateSUBSPcLrEtc (opcode, encoding);
996             break;
997         default:
998             return false;
999         }
1000         uint32_t result = ~imm32;
1001 
1002         // The context specifies that an immediate is to be moved into Rd.
1003         EmulateInstruction::Context context;
1004         context.type = EmulateInstruction::eContextImmediate;
1005         context.SetNoArgs ();
1006 
1007         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1008             return false;
1009     }
1010     return true;
1011 }
1012 
1013 // Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register.
1014 // It can optionally update the condition flags based on the result.
1015 bool
1016 EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding)
1017 {
1018 #if 0
1019     // ARM pseudo code...
1020     if (ConditionPassed())
1021     {
1022         EncodingSpecificOperations();
1023         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1024         result = NOT(shifted);
1025         if d == 15 then         // Can only occur for ARM encoding
1026             ALUWritePC(result); // setflags is always FALSE here
1027         else
1028             R[d] = result;
1029             if setflags then
1030                 APSR.N = result<31>;
1031                 APSR.Z = IsZeroBit(result);
1032                 APSR.C = carry;
1033                 // APSR.V unchanged
1034     }
1035 #endif
1036 
1037     if (ConditionPassed(opcode))
1038     {
1039         uint32_t Rm; // the source register
1040         uint32_t Rd; // the destination register
1041         ARM_ShifterType shift_t;
1042         uint32_t shift_n; // the shift applied to the value read from Rm
1043         bool setflags;
1044         uint32_t carry; // the carry bit after the shift operation
1045         switch (encoding) {
1046         case eEncodingT1:
1047             Rd = Bits32(opcode, 2, 0);
1048             Rm = Bits32(opcode, 5, 3);
1049             setflags = !InITBlock();
1050             shift_t = SRType_LSL;
1051             shift_n = 0;
1052             if (InITBlock())
1053                 return false;
1054             break;
1055         case eEncodingT2:
1056             Rd = Bits32(opcode, 11, 8);
1057             Rm = Bits32(opcode, 3, 0);
1058             setflags = BitIsSet(opcode, 20);
1059             shift_n = DecodeImmShiftThumb(opcode, shift_t);
1060             // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1061             if (BadReg(Rd) || BadReg(Rm))
1062                 return false;
1063             break;
1064         case eEncodingA1:
1065             Rd = Bits32(opcode, 15, 12);
1066             Rm = Bits32(opcode, 3, 0);
1067             setflags = BitIsSet(opcode, 20);
1068             shift_n = DecodeImmShiftARM(opcode, shift_t);
1069             break;
1070         default:
1071             return false;
1072         }
1073         bool success = false;
1074         uint32_t value = ReadCoreReg(Rm, &success);
1075         if (!success)
1076             return false;
1077 
1078         uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry);
1079         uint32_t result = ~shifted;
1080 
1081         // The context specifies that an immediate is to be moved into Rd.
1082         EmulateInstruction::Context context;
1083         context.type = EmulateInstruction::eContextImmediate;
1084         context.SetNoArgs ();
1085 
1086         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1087             return false;
1088     }
1089     return true;
1090 }
1091 
1092 // PC relative immediate load into register, possibly followed by ADD (SP plus register).
1093 // LDR (literal)
1094 bool
1095 EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding)
1096 {
1097 #if 0
1098     // ARM pseudo code...
1099     if (ConditionPassed())
1100     {
1101         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1102         base = Align(PC,4);
1103         address = if add then (base + imm32) else (base - imm32);
1104         data = MemU[address,4];
1105         if t == 15 then
1106             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1107         elsif UnalignedSupport() || address<1:0> = '00' then
1108             R[t] = data;
1109         else // Can only apply before ARMv7
1110             if CurrentInstrSet() == InstrSet_ARM then
1111                 R[t] = ROR(data, 8*UInt(address<1:0>));
1112             else
1113                 R[t] = bits(32) UNKNOWN;
1114     }
1115 #endif
1116 
1117     if (ConditionPassed(opcode))
1118     {
1119         bool success = false;
1120         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1121         if (!success)
1122             return false;
1123 
1124         // PC relative immediate load context
1125         EmulateInstruction::Context context;
1126         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1127         Register pc_reg;
1128         pc_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
1129         context.SetRegisterPlusOffset (pc_reg, 0);
1130 
1131         uint32_t Rt;    // the destination register
1132         uint32_t imm32; // immediate offset from the PC
1133         bool add;       // +imm32 or -imm32?
1134         addr_t base;    // the base address
1135         addr_t address; // the PC relative address
1136         uint32_t data;  // the literal data value from the PC relative load
1137         switch (encoding) {
1138         case eEncodingT1:
1139             Rt = Bits32(opcode, 10, 8);
1140             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1141             add = true;
1142             break;
1143         case eEncodingT2:
1144             Rt = Bits32(opcode, 15, 12);
1145             imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1146             add = BitIsSet(opcode, 23);
1147             if (Rt == 15 && InITBlock() && !LastInITBlock())
1148                 return false;
1149             break;
1150         default:
1151             return false;
1152         }
1153 
1154         base = Align(pc, 4);
1155         if (add)
1156             address = base + imm32;
1157         else
1158             address = base - imm32;
1159 
1160         context.SetRegisterPlusOffset(pc_reg, address - base);
1161         data = MemURead(context, address, 4, 0, &success);
1162         if (!success)
1163             return false;
1164 
1165         if (Rt == 15)
1166         {
1167             if (Bits32(address, 1, 0) == 0)
1168             {
1169                 // In ARMv5T and above, this is an interworking branch.
1170                 if (!LoadWritePC(context, data))
1171                     return false;
1172             }
1173             else
1174                 return false;
1175         }
1176         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
1177         {
1178             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
1179                 return false;
1180         }
1181         else // We don't handle ARM for now.
1182             return false;
1183 
1184     }
1185     return true;
1186 }
1187 
1188 // An add operation to adjust the SP.
1189 // ADD (SP plus immediate)
1190 bool
1191 EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding)
1192 {
1193 #if 0
1194     // ARM pseudo code...
1195     if (ConditionPassed())
1196     {
1197         EncodingSpecificOperations();
1198         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1199         if d == 15 then // Can only occur for ARM encoding
1200             ALUWritePC(result); // setflags is always FALSE here
1201         else
1202             R[d] = result;
1203             if setflags then
1204                 APSR.N = result<31>;
1205                 APSR.Z = IsZeroBit(result);
1206                 APSR.C = carry;
1207                 APSR.V = overflow;
1208     }
1209 #endif
1210 
1211     bool success = false;
1212 
1213     if (ConditionPassed(opcode))
1214     {
1215         const addr_t sp = ReadCoreReg (SP_REG, &success);
1216         if (!success)
1217             return false;
1218         uint32_t imm32; // the immediate operand
1219         uint32_t d;
1220         bool setflags;
1221         switch (encoding)
1222         {
1223             case eEncodingT1:
1224                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1225                 d = Bits32 (opcode, 10, 8);
1226                 setflags = false;
1227                 imm32 = (Bits32 (opcode, 7, 0) << 2);
1228 
1229                 break;
1230 
1231             case eEncodingT2:
1232                 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1233                 d = 13;
1234                 setflags = false;
1235                 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1236 
1237                 break;
1238 
1239             default:
1240                 return false;
1241         }
1242         addr_t sp_offset = imm32;
1243         addr_t addr = sp + sp_offset; // the adjusted stack pointer value
1244 
1245         EmulateInstruction::Context context;
1246         context.type = EmulateInstruction::eContextAdjustStackPointer;
1247         Register sp_reg;
1248         sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
1249         context.SetRegisterPlusOffset (sp_reg, sp_offset);
1250 
1251         if (d == 15)
1252         {
1253             if (!ALUWritePC (context, addr))
1254                 return false;
1255         }
1256         else
1257         {
1258             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr))
1259                 return false;
1260         }
1261     }
1262     return true;
1263 }
1264 
1265 // An add operation to adjust the SP.
1266 // ADD (SP plus register)
1267 bool
1268 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding)
1269 {
1270 #if 0
1271     // ARM pseudo code...
1272     if (ConditionPassed())
1273     {
1274         EncodingSpecificOperations();
1275         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1276         (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1277         if d == 15 then
1278             ALUWritePC(result); // setflags is always FALSE here
1279         else
1280             R[d] = result;
1281             if setflags then
1282                 APSR.N = result<31>;
1283                 APSR.Z = IsZeroBit(result);
1284                 APSR.C = carry;
1285                 APSR.V = overflow;
1286     }
1287 #endif
1288 
1289     bool success = false;
1290 
1291     if (ConditionPassed(opcode))
1292     {
1293         const addr_t sp = ReadCoreReg (SP_REG, &success);
1294         if (!success)
1295             return false;
1296         uint32_t Rm; // the second operand
1297         switch (encoding) {
1298         case eEncodingT2:
1299             Rm = Bits32(opcode, 6, 3);
1300             break;
1301         default:
1302             return false;
1303         }
1304         int32_t reg_value = ReadCoreReg(Rm, &success);
1305         if (!success)
1306             return false;
1307 
1308         addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1309 
1310         EmulateInstruction::Context context;
1311         context.type = EmulateInstruction::eContextAddition;
1312         Register sp_reg;
1313         sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
1314         Register other_reg;
1315         other_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
1316         context.SetRegisterRegisterOperands (sp_reg, other_reg);
1317 
1318         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
1319             return false;
1320     }
1321     return true;
1322 }
1323 
1324 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
1325 // at a PC-relative address, and changes instruction set from ARM to Thumb, or
1326 // from Thumb to ARM.
1327 // BLX (immediate)
1328 bool
1329 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding)
1330 {
1331 #if 0
1332     // ARM pseudo code...
1333     if (ConditionPassed())
1334     {
1335         EncodingSpecificOperations();
1336         if CurrentInstrSet() == InstrSet_ARM then
1337             LR = PC - 4;
1338         else
1339             LR = PC<31:1> : '1';
1340         if targetInstrSet == InstrSet_ARM then
1341             targetAddress = Align(PC,4) + imm32;
1342         else
1343             targetAddress = PC + imm32;
1344         SelectInstrSet(targetInstrSet);
1345         BranchWritePC(targetAddress);
1346     }
1347 #endif
1348 
1349     bool success = true;
1350 
1351     if (ConditionPassed(opcode))
1352     {
1353         EmulateInstruction::Context context;
1354         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1355         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1356         if (!success)
1357             return false;
1358         addr_t lr; // next instruction address
1359         addr_t target; // target address
1360         int32_t imm32; // PC-relative offset
1361         switch (encoding) {
1362         case eEncodingT1:
1363             {
1364             lr = pc | 1u; // return address
1365             uint32_t S = Bit32(opcode, 26);
1366             uint32_t imm10 = Bits32(opcode, 25, 16);
1367             uint32_t J1 = Bit32(opcode, 13);
1368             uint32_t J2 = Bit32(opcode, 11);
1369             uint32_t imm11 = Bits32(opcode, 10, 0);
1370             uint32_t I1 = !(J1 ^ S);
1371             uint32_t I2 = !(J2 ^ S);
1372             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1373             imm32 = llvm::SignExtend32<25>(imm25);
1374             target = pc + imm32;
1375             context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
1376             if (InITBlock() && !LastInITBlock())
1377                 return false;
1378             break;
1379             }
1380         case eEncodingT2:
1381             {
1382             lr = pc | 1u; // return address
1383             uint32_t S = Bit32(opcode, 26);
1384             uint32_t imm10H = Bits32(opcode, 25, 16);
1385             uint32_t J1 = Bit32(opcode, 13);
1386             uint32_t J2 = Bit32(opcode, 11);
1387             uint32_t imm10L = Bits32(opcode, 10, 1);
1388             uint32_t I1 = !(J1 ^ S);
1389             uint32_t I2 = !(J2 ^ S);
1390             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
1391             imm32 = llvm::SignExtend32<25>(imm25);
1392             target = Align(pc, 4) + imm32;
1393             context.SetModeAndImmediateSigned (eModeARM, 4 + imm32);
1394             if (InITBlock() && !LastInITBlock())
1395                 return false;
1396             break;
1397             }
1398         case eEncodingA1:
1399             lr = pc - 4; // return address
1400             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1401             target = Align(pc, 4) + imm32;
1402             context.SetModeAndImmediateSigned (eModeARM, 8 + imm32);
1403             break;
1404         case eEncodingA2:
1405             lr = pc - 4; // return address
1406             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
1407             target = pc + imm32;
1408             context.SetModeAndImmediateSigned (eModeThumb, 8 + imm32);
1409             break;
1410         default:
1411             return false;
1412         }
1413         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1414             return false;
1415         if (!BranchWritePC(context, target))
1416             return false;
1417     }
1418     return true;
1419 }
1420 
1421 // Branch with Link and Exchange (register) calls a subroutine at an address and
1422 // instruction set specified by a register.
1423 // BLX (register)
1424 bool
1425 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding)
1426 {
1427 #if 0
1428     // ARM pseudo code...
1429     if (ConditionPassed())
1430     {
1431         EncodingSpecificOperations();
1432         target = R[m];
1433         if CurrentInstrSet() == InstrSet_ARM then
1434             next_instr_addr = PC - 4;
1435             LR = next_instr_addr;
1436         else
1437             next_instr_addr = PC - 2;
1438             LR = next_instr_addr<31:1> : '1';
1439         BXWritePC(target);
1440     }
1441 #endif
1442 
1443     bool success = false;
1444 
1445     if (ConditionPassed(opcode))
1446     {
1447         EmulateInstruction::Context context;
1448         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1449         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1450         addr_t lr; // next instruction address
1451         if (!success)
1452             return false;
1453         uint32_t Rm; // the register with the target address
1454         switch (encoding) {
1455         case eEncodingT1:
1456             lr = (pc - 2) | 1u; // return address
1457             Rm = Bits32(opcode, 6, 3);
1458             // if m == 15 then UNPREDICTABLE;
1459             if (Rm == 15)
1460                 return false;
1461             if (InITBlock() && !LastInITBlock())
1462                 return false;
1463             break;
1464         case eEncodingA1:
1465             lr = pc - 4; // return address
1466             Rm = Bits32(opcode, 3, 0);
1467             // if m == 15 then UNPREDICTABLE;
1468             if (Rm == 15)
1469                 return false;
1470             break;
1471         default:
1472             return false;
1473         }
1474         addr_t target = ReadCoreReg (Rm, &success);
1475         if (!success)
1476             return false;
1477         Register dwarf_reg;
1478         dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
1479         context.SetRegister (dwarf_reg);
1480         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1481             return false;
1482         if (!BXWritePC(context, target))
1483             return false;
1484     }
1485     return true;
1486 }
1487 
1488 // Branch and Exchange causes a branch to an address and instruction set specified by a register.
1489 bool
1490 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding)
1491 {
1492 #if 0
1493     // ARM pseudo code...
1494     if (ConditionPassed())
1495     {
1496         EncodingSpecificOperations();
1497         BXWritePC(R[m]);
1498     }
1499 #endif
1500 
1501     if (ConditionPassed(opcode))
1502     {
1503         EmulateInstruction::Context context;
1504         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1505         uint32_t Rm; // the register with the target address
1506         switch (encoding) {
1507         case eEncodingT1:
1508             Rm = Bits32(opcode, 6, 3);
1509             if (InITBlock() && !LastInITBlock())
1510                 return false;
1511             break;
1512         case eEncodingA1:
1513             Rm = Bits32(opcode, 3, 0);
1514             break;
1515         default:
1516             return false;
1517         }
1518         bool success = false;
1519         addr_t target = ReadCoreReg (Rm, &success);
1520         if (!success)
1521             return false;
1522 
1523         Register dwarf_reg;
1524         dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
1525         context.SetRegister (dwarf_reg);
1526         if (!BXWritePC(context, target))
1527             return false;
1528     }
1529     return true;
1530 }
1531 
1532 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an
1533 // address and instruction set specified by a register as though it were a BX instruction.
1534 //
1535 // TODO: Emulate Jazelle architecture?
1536 //       We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation.
1537 bool
1538 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding)
1539 {
1540 #if 0
1541     // ARM pseudo code...
1542     if (ConditionPassed())
1543     {
1544         EncodingSpecificOperations();
1545         if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
1546             BXWritePC(R[m]);
1547         else
1548             if JazelleAcceptsExecution() then
1549                 SwitchToJazelleExecution();
1550             else
1551                 SUBARCHITECTURE_DEFINED handler call;
1552     }
1553 #endif
1554 
1555     if (ConditionPassed(opcode))
1556     {
1557         EmulateInstruction::Context context;
1558         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1559         uint32_t Rm; // the register with the target address
1560         switch (encoding) {
1561         case eEncodingT1:
1562             Rm = Bits32(opcode, 19, 16);
1563             if (BadReg(Rm))
1564                 return false;
1565             if (InITBlock() && !LastInITBlock())
1566                 return false;
1567             break;
1568         case eEncodingA1:
1569             Rm = Bits32(opcode, 3, 0);
1570             if (Rm == 15)
1571                 return false;
1572             break;
1573         default:
1574             return false;
1575         }
1576         bool success = false;
1577         addr_t target = ReadCoreReg (Rm, &success);
1578         if (!success)
1579             return false;
1580 
1581         Register dwarf_reg;
1582         dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
1583         context.SetRegister (dwarf_reg);
1584         if (!BXWritePC(context, target))
1585             return false;
1586     }
1587     return true;
1588 }
1589 
1590 // Set r7 to point to some ip offset.
1591 // SUB (immediate)
1592 bool
1593 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding)
1594 {
1595 #if 0
1596     // ARM pseudo code...
1597     if (ConditionPassed())
1598     {
1599         EncodingSpecificOperations();
1600         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1601         if d == 15 then // Can only occur for ARM encoding
1602            ALUWritePC(result); // setflags is always FALSE here
1603         else
1604             R[d] = result;
1605             if setflags then
1606                 APSR.N = result<31>;
1607                 APSR.Z = IsZeroBit(result);
1608                 APSR.C = carry;
1609                 APSR.V = overflow;
1610     }
1611 #endif
1612 
1613     if (ConditionPassed(opcode))
1614     {
1615         bool success = false;
1616         const addr_t ip = ReadCoreReg (12, &success);
1617         if (!success)
1618             return false;
1619         uint32_t imm32;
1620         switch (encoding) {
1621         case eEncodingA1:
1622             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1623             break;
1624         default:
1625             return false;
1626         }
1627         addr_t ip_offset = imm32;
1628         addr_t addr = ip - ip_offset; // the adjusted ip value
1629 
1630         EmulateInstruction::Context context;
1631         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1632         Register dwarf_reg;
1633         dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r12);
1634         context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
1635 
1636         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
1637             return false;
1638     }
1639     return true;
1640 }
1641 
1642 // Set ip to point to some stack offset.
1643 // SUB (SP minus immediate)
1644 bool
1645 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding)
1646 {
1647 #if 0
1648     // ARM pseudo code...
1649     if (ConditionPassed())
1650     {
1651         EncodingSpecificOperations();
1652         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1653         if d == 15 then // Can only occur for ARM encoding
1654            ALUWritePC(result); // setflags is always FALSE here
1655         else
1656             R[d] = result;
1657             if setflags then
1658                 APSR.N = result<31>;
1659                 APSR.Z = IsZeroBit(result);
1660                 APSR.C = carry;
1661                 APSR.V = overflow;
1662     }
1663 #endif
1664 
1665     if (ConditionPassed(opcode))
1666     {
1667         bool success = false;
1668         const addr_t sp = ReadCoreReg (SP_REG, &success);
1669         if (!success)
1670             return false;
1671         uint32_t imm32;
1672         switch (encoding) {
1673         case eEncodingA1:
1674             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1675             break;
1676         default:
1677             return false;
1678         }
1679         addr_t sp_offset = imm32;
1680         addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1681 
1682         EmulateInstruction::Context context;
1683         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1684         Register dwarf_reg;
1685         dwarf_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
1686         context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
1687 
1688         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
1689             return false;
1690     }
1691     return true;
1692 }
1693 
1694 // This instruction subtracts an immediate value from the SP value, and writes
1695 // the result to the destination register.
1696 //
1697 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage.
1698 bool
1699 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding)
1700 {
1701 #if 0
1702     // ARM pseudo code...
1703     if (ConditionPassed())
1704     {
1705         EncodingSpecificOperations();
1706         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1707         if d == 15 then        // Can only occur for ARM encoding
1708            ALUWritePC(result); // setflags is always FALSE here
1709         else
1710             R[d] = result;
1711             if setflags then
1712                 APSR.N = result<31>;
1713                 APSR.Z = IsZeroBit(result);
1714                 APSR.C = carry;
1715                 APSR.V = overflow;
1716     }
1717 #endif
1718 
1719     bool success = false;
1720     if (ConditionPassed(opcode))
1721     {
1722         const addr_t sp = ReadCoreReg (SP_REG, &success);
1723         if (!success)
1724             return false;
1725 
1726         uint32_t Rd;
1727         bool setflags;
1728         uint32_t imm32;
1729         switch (encoding) {
1730         case eEncodingT1:
1731             Rd = 13;
1732             setflags = false;
1733             imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1734             break;
1735         case eEncodingT2:
1736             Rd = Bits32(opcode, 11, 8);
1737             setflags = BitIsSet(opcode, 20);
1738             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1739             if (Rd == 15 && setflags)
1740                 return EmulateCMPImm(opcode, eEncodingT2);
1741             if (Rd == 15 && !setflags)
1742                 return false;
1743             break;
1744         case eEncodingT3:
1745             Rd = Bits32(opcode, 11, 8);
1746             setflags = false;
1747             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
1748             if (Rd == 15)
1749                 return false;
1750             break;
1751         case eEncodingA1:
1752             Rd = Bits32(opcode, 15, 12);
1753             setflags = BitIsSet(opcode, 20);
1754             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1755 
1756             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1757             if (Rd == 15 && setflags)
1758                 return EmulateSUBSPcLrEtc (opcode, encoding);
1759             break;
1760         default:
1761             return false;
1762         }
1763         AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
1764 
1765         EmulateInstruction::Context context;
1766         if (Rd == 13)
1767         {
1768             uint64_t imm64 = imm32;  // Need to expand it to 64 bits before attempting to negate it, or the wrong
1769                                      // value gets passed down to context.SetImmediateSigned.
1770             context.type = EmulateInstruction::eContextAdjustStackPointer;
1771             context.SetImmediateSigned (-imm64); // the stack pointer offset
1772         }
1773         else
1774         {
1775             context.type = EmulateInstruction::eContextImmediate;
1776             context.SetNoArgs ();
1777         }
1778 
1779         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
1780             return false;
1781     }
1782     return true;
1783 }
1784 
1785 // A store operation to the stack that also updates the SP.
1786 bool
1787 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding)
1788 {
1789 #if 0
1790     // ARM pseudo code...
1791     if (ConditionPassed())
1792     {
1793         EncodingSpecificOperations();
1794         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1795         address = if index then offset_addr else R[n];
1796         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1797         if wback then R[n] = offset_addr;
1798     }
1799 #endif
1800 
1801     bool success = false;
1802 
1803     if (ConditionPassed(opcode))
1804     {
1805         const uint32_t addr_byte_size = GetAddressByteSize();
1806         const addr_t sp = ReadCoreReg (SP_REG, &success);
1807         if (!success)
1808             return false;
1809         uint32_t Rt; // the source register
1810         uint32_t imm12;
1811         uint32_t Rn;  // This function assumes Rn is the SP, but we should verify that.
1812 
1813         bool index;
1814         bool add;
1815         bool wback;
1816         switch (encoding) {
1817         case eEncodingA1:
1818             Rt = Bits32(opcode, 15, 12);
1819             imm12 = Bits32(opcode, 11, 0);
1820             Rn = Bits32 (opcode, 19, 16);
1821 
1822             if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
1823                 return false;
1824 
1825             index = BitIsSet (opcode, 24);
1826             add = BitIsSet (opcode, 23);
1827             wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
1828 
1829             if (wback && ((Rn == 15) || (Rn == Rt)))
1830                 return false;
1831             break;
1832         default:
1833             return false;
1834         }
1835         addr_t offset_addr;
1836         if (add)
1837             offset_addr = sp + imm12;
1838         else
1839             offset_addr = sp - imm12;
1840 
1841         addr_t addr;
1842         if (index)
1843             addr = offset_addr;
1844         else
1845             addr = sp;
1846 
1847         EmulateInstruction::Context context;
1848         context.type = EmulateInstruction::eContextPushRegisterOnStack;
1849         Register sp_reg;
1850         sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
1851         context.SetRegisterPlusOffset (sp_reg, addr - sp);
1852         if (Rt != 15)
1853         {
1854             uint32_t reg_value = ReadCoreReg(Rt, &success);
1855             if (!success)
1856                 return false;
1857             if (!MemUWrite (context, addr, reg_value, addr_byte_size))
1858                 return false;
1859         }
1860         else
1861         {
1862             const uint32_t pc = ReadCoreReg(PC_REG, &success);
1863             if (!success)
1864                 return false;
1865             if (!MemUWrite (context, addr, pc, addr_byte_size))
1866                 return false;
1867         }
1868 
1869 
1870         if (wback)
1871         {
1872             context.type = EmulateInstruction::eContextAdjustStackPointer;
1873             context.SetImmediateSigned (addr - sp);
1874             if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr))
1875                 return false;
1876         }
1877     }
1878     return true;
1879 }
1880 
1881 // Vector Push stores multiple extension registers to the stack.
1882 // It also updates SP to point to the start of the stored data.
1883 bool
1884 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding)
1885 {
1886 #if 0
1887     // ARM pseudo code...
1888     if (ConditionPassed())
1889     {
1890         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1891         address = SP - imm32;
1892         SP = SP - imm32;
1893         if single_regs then
1894             for r = 0 to regs-1
1895                 MemA[address,4] = S[d+r]; address = address+4;
1896         else
1897             for r = 0 to regs-1
1898                 // Store as two word-aligned words in the correct order for current endianness.
1899                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
1900                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
1901                 address = address+8;
1902     }
1903 #endif
1904 
1905     bool success = false;
1906 
1907     if (ConditionPassed(opcode))
1908     {
1909         const uint32_t addr_byte_size = GetAddressByteSize();
1910         const addr_t sp = ReadCoreReg (SP_REG, &success);
1911         if (!success)
1912             return false;
1913         bool single_regs;
1914         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
1915         uint32_t imm32; // stack offset
1916         uint32_t regs;  // number of registers
1917         switch (encoding) {
1918         case eEncodingT1:
1919         case eEncodingA1:
1920             single_regs = false;
1921             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
1922             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1923             // If UInt(imm8) is odd, see "FSTMX".
1924             regs = Bits32(opcode, 7, 0) / 2;
1925             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1926             if (regs == 0 || regs > 16 || (d + regs) > 32)
1927                 return false;
1928             break;
1929         case eEncodingT2:
1930         case eEncodingA2:
1931             single_regs = true;
1932             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
1933             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
1934             regs = Bits32(opcode, 7, 0);
1935             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
1936             if (regs == 0 || regs > 16 || (d + regs) > 32)
1937                 return false;
1938             break;
1939         default:
1940             return false;
1941         }
1942         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
1943         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
1944         addr_t sp_offset = imm32;
1945         addr_t addr = sp - sp_offset;
1946         uint32_t i;
1947 
1948         EmulateInstruction::Context context;
1949         context.type = EmulateInstruction::eContextPushRegisterOnStack;
1950         Register dwarf_reg;
1951         dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
1952         Register sp_reg;
1953         sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
1954         for (i=0; i<regs; ++i)
1955         {
1956             dwarf_reg.num = start_reg + d + i;
1957             context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
1958             // uint64_t to accommodate 64-bit registers.
1959             uint64_t reg_value = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_reg.num, 0, &success);
1960             if (!success)
1961                 return false;
1962             if (!MemAWrite (context, addr, reg_value, reg_byte_size))
1963                 return false;
1964             addr += reg_byte_size;
1965         }
1966 
1967         context.type = EmulateInstruction::eContextAdjustStackPointer;
1968         context.SetImmediateSigned (-sp_offset);
1969 
1970         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
1971             return false;
1972     }
1973     return true;
1974 }
1975 
1976 // Vector Pop loads multiple extension registers from the stack.
1977 // It also updates SP to point just above the loaded data.
1978 bool
1979 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding)
1980 {
1981 #if 0
1982     // ARM pseudo code...
1983     if (ConditionPassed())
1984     {
1985         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1986         address = SP;
1987         SP = SP + imm32;
1988         if single_regs then
1989             for r = 0 to regs-1
1990                 S[d+r] = MemA[address,4]; address = address+4;
1991         else
1992             for r = 0 to regs-1
1993                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
1994                 // Combine the word-aligned words in the correct order for current endianness.
1995                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
1996     }
1997 #endif
1998 
1999     bool success = false;
2000 
2001     if (ConditionPassed(opcode))
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 "FLDMX".
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;
2040         uint32_t i;
2041         uint64_t data; // uint64_t to accomodate 64-bit registers.
2042 
2043         EmulateInstruction::Context context;
2044         context.type = EmulateInstruction::eContextPopRegisterOffStack;
2045         Register dwarf_reg;
2046         dwarf_reg.SetRegister (eRegisterKindDWARF, 0);
2047         Register sp_reg;
2048         sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
2049         for (i=0; i<regs; ++i)
2050         {
2051             dwarf_reg.num = start_reg + d + i;
2052             context.SetRegisterPlusOffset (sp_reg, addr - sp);
2053             data = MemARead(context, addr, reg_byte_size, 0, &success);
2054             if (!success)
2055                 return false;
2056             if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_reg.num, data))
2057                 return false;
2058             addr += reg_byte_size;
2059         }
2060 
2061         context.type = EmulateInstruction::eContextAdjustStackPointer;
2062         context.SetImmediateSigned (sp_offset);
2063 
2064         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2065             return false;
2066     }
2067     return true;
2068 }
2069 
2070 // SVC (previously SWI)
2071 bool
2072 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding)
2073 {
2074 #if 0
2075     // ARM pseudo code...
2076     if (ConditionPassed())
2077     {
2078         EncodingSpecificOperations();
2079         CallSupervisor();
2080     }
2081 #endif
2082 
2083     bool success = false;
2084 
2085     if (ConditionPassed(opcode))
2086     {
2087         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2088         addr_t lr; // next instruction address
2089         if (!success)
2090             return false;
2091         uint32_t imm32; // the immediate constant
2092         uint32_t mode;  // ARM or Thumb mode
2093         switch (encoding) {
2094         case eEncodingT1:
2095             lr = (pc + 2) | 1u; // return address
2096             imm32 = Bits32(opcode, 7, 0);
2097             mode = eModeThumb;
2098             break;
2099         case eEncodingA1:
2100             lr = pc + 4; // return address
2101             imm32 = Bits32(opcode, 23, 0);
2102             mode = eModeARM;
2103             break;
2104         default:
2105             return false;
2106         }
2107 
2108         EmulateInstruction::Context context;
2109         context.type = EmulateInstruction::eContextSupervisorCall;
2110         context.SetModeAndImmediate (mode, imm32);
2111         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
2112             return false;
2113     }
2114     return true;
2115 }
2116 
2117 // If Then makes up to four following instructions (the IT block) conditional.
2118 bool
2119 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding)
2120 {
2121 #if 0
2122     // ARM pseudo code...
2123     EncodingSpecificOperations();
2124     ITSTATE.IT<7:0> = firstcond:mask;
2125 #endif
2126 
2127     m_it_session.InitIT(Bits32(opcode, 7, 0));
2128     return true;
2129 }
2130 
2131 // Branch causes a branch to a target address.
2132 bool
2133 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding)
2134 {
2135 #if 0
2136     // ARM pseudo code...
2137     if (ConditionPassed())
2138     {
2139         EncodingSpecificOperations();
2140         BranchWritePC(PC + imm32);
2141     }
2142 #endif
2143 
2144     bool success = false;
2145 
2146     if (ConditionPassed(opcode))
2147     {
2148         EmulateInstruction::Context context;
2149         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2150         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2151         if (!success)
2152             return false;
2153         addr_t target; // target address
2154         int32_t imm32; // PC-relative offset
2155         switch (encoding) {
2156         case eEncodingT1:
2157             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2158             imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2159             target = pc + imm32;
2160             context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
2161             break;
2162         case eEncodingT2:
2163             imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0));
2164             target = pc + imm32;
2165             context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
2166             break;
2167         case eEncodingT3:
2168             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2169             {
2170             uint32_t S = Bit32(opcode, 26);
2171             uint32_t imm6 = Bits32(opcode, 21, 16);
2172             uint32_t J1 = Bit32(opcode, 13);
2173             uint32_t J2 = Bit32(opcode, 11);
2174             uint32_t imm11 = Bits32(opcode, 10, 0);
2175             uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2176             imm32 = llvm::SignExtend32<21>(imm21);
2177             target = pc + imm32;
2178             context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
2179             break;
2180             }
2181         case eEncodingT4:
2182             {
2183             uint32_t S = Bit32(opcode, 26);
2184             uint32_t imm10 = Bits32(opcode, 25, 16);
2185             uint32_t J1 = Bit32(opcode, 13);
2186             uint32_t J2 = Bit32(opcode, 11);
2187             uint32_t imm11 = Bits32(opcode, 10, 0);
2188             uint32_t I1 = !(J1 ^ S);
2189             uint32_t I2 = !(J2 ^ S);
2190             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2191             imm32 = llvm::SignExtend32<25>(imm25);
2192             target = pc + imm32;
2193             context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
2194             break;
2195             }
2196         case eEncodingA1:
2197             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2198             target = pc + imm32;
2199             context.SetModeAndImmediateSigned (eModeARM, 8 + imm32);
2200             break;
2201         default:
2202             return false;
2203         }
2204         if (!BranchWritePC(context, target))
2205             return false;
2206     }
2207     return true;
2208 }
2209 
2210 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
2211 // zero and conditionally branch forward a constant value.  They do not affect the condition flags.
2212 // CBNZ, CBZ
2213 bool
2214 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding)
2215 {
2216 #if 0
2217     // ARM pseudo code...
2218     EncodingSpecificOperations();
2219     if nonzero ^ IsZero(R[n]) then
2220         BranchWritePC(PC + imm32);
2221 #endif
2222 
2223     bool success = false;
2224 
2225     // Read the register value from the operand register Rn.
2226     uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2227     if (!success)
2228         return false;
2229 
2230     EmulateInstruction::Context context;
2231     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2232     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2233     if (!success)
2234         return false;
2235 
2236     addr_t target;  // target address
2237     uint32_t imm32; // PC-relative offset to branch forward
2238     bool nonzero;
2239     switch (encoding) {
2240     case eEncodingT1:
2241         imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2242         nonzero = BitIsSet(opcode, 11);
2243         target = pc + imm32;
2244         context.SetModeAndImmediateSigned (eModeThumb, 4 + imm32);
2245         break;
2246     default:
2247         return false;
2248     }
2249     if (nonzero ^ (reg_val == 0))
2250         if (!BranchWritePC(context, target))
2251             return false;
2252 
2253     return true;
2254 }
2255 
2256 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
2257 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2258 // The branch length is twice the value of the byte returned from the table.
2259 //
2260 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
2261 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2262 // The branch length is twice the value of the halfword returned from the table.
2263 // TBB, TBH
2264 bool
2265 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding)
2266 {
2267 #if 0
2268     // ARM pseudo code...
2269     EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2270     if is_tbh then
2271         halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2272     else
2273         halfwords = UInt(MemU[R[n]+R[m], 1]);
2274     BranchWritePC(PC + 2*halfwords);
2275 #endif
2276 
2277     bool success = false;
2278 
2279     uint32_t Rn;     // the base register which contains the address of the table of branch lengths
2280     uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
2281     bool is_tbh;     // true if table branch halfword
2282     switch (encoding) {
2283     case eEncodingT1:
2284         Rn = Bits32(opcode, 19, 16);
2285         Rm = Bits32(opcode, 3, 0);
2286         is_tbh = BitIsSet(opcode, 4);
2287         if (Rn == 13 || BadReg(Rm))
2288             return false;
2289         if (InITBlock() && !LastInITBlock())
2290             return false;
2291         break;
2292     default:
2293         return false;
2294     }
2295 
2296     // Read the address of the table from the operand register Rn.
2297     // The PC can be used, in which case the table immediately follows this instruction.
2298     uint32_t base = ReadCoreReg(Rm, &success);
2299     if (!success)
2300         return false;
2301 
2302     // the table index
2303     uint32_t index = ReadCoreReg(Rm, &success);
2304     if (!success)
2305         return false;
2306 
2307     // the offsetted table address
2308     addr_t addr = base + (is_tbh ? index*2 : index);
2309 
2310     // PC-relative offset to branch forward
2311     EmulateInstruction::Context context;
2312     context.type = EmulateInstruction::eContextTableBranchReadMemory;
2313     uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2314     if (!success)
2315         return false;
2316 
2317     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2318     if (!success)
2319         return false;
2320 
2321     // target address
2322     addr_t target = pc + offset;
2323     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2324     context.SetModeAndImmediateSigned (eModeThumb, 4 + offset);
2325 
2326     if (!BranchWritePC(context, target))
2327         return false;
2328 
2329     return true;
2330 }
2331 
2332 // This instruction adds an immediate value to a register value, and writes the result to the destination register.
2333 // It can optionally update the condition flags based on the result.
2334 bool
2335 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding)
2336 {
2337 #if 0
2338     if ConditionPassed() then
2339         EncodingSpecificOperations();
2340         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2341         R[d] = result;
2342         if setflags then
2343             APSR.N = result<31>;
2344             APSR.Z = IsZeroBit(result);
2345             APSR.C = carry;
2346             APSR.V = overflow;
2347 #endif
2348 
2349     bool success = false;
2350 
2351     if (ConditionPassed(opcode))
2352     {
2353         uint32_t d;
2354         uint32_t n;
2355         bool setflags;
2356         uint32_t imm32;
2357         uint32_t carry_out;
2358 
2359         //EncodingSpecificOperations();
2360         switch (encoding)
2361         {
2362             case eEncodingT1:
2363                 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32);
2364                 d = Bits32 (opcode, 2, 0);
2365                 n = Bits32 (opcode, 5, 3);
2366                 setflags = !InITBlock();
2367                 imm32 = Bits32 (opcode, 8,6);
2368 
2369                 break;
2370 
2371             case eEncodingT2:
2372                 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32);
2373                 d = Bits32 (opcode, 10, 8);
2374                 n = Bits32 (opcode, 10, 8);
2375                 setflags = !InITBlock();
2376                 imm32 = Bits32 (opcode, 7, 0);
2377 
2378                 break;
2379 
2380             case eEncodingT3:
2381                 // if Rd == '1111' && S == '1' then SEE CMN (immediate);
2382                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2383                 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8);
2384                 d = Bits32 (opcode, 11, 8);
2385                 n = Bits32 (opcode, 19, 16);
2386                 setflags = BitIsSet (opcode, 20);
2387                 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out);
2388 
2389                 // if BadReg(d) || n == 15 then UNPREDICTABLE;
2390                 if (BadReg (d) || (n == 15))
2391                     return false;
2392 
2393                 break;
2394 
2395             case eEncodingT4:
2396             {
2397                 // if Rn == '1111' then SEE ADR;
2398                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2399                 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
2400                 d = Bits32 (opcode, 11, 8);
2401                 n = Bits32 (opcode, 19, 16);
2402                 setflags = false;
2403                 uint32_t i = Bit32 (opcode, 26);
2404                 uint32_t imm3 = Bits32 (opcode, 14, 12);
2405                 uint32_t imm8 = Bits32 (opcode, 7, 0);
2406                 imm32 = (i << 11) | (imm3 << 8) | imm8;
2407 
2408                 // if BadReg(d) then UNPREDICTABLE;
2409                 if (BadReg (d))
2410                     return false;
2411 
2412                 break;
2413             }
2414             default:
2415                 return false;
2416         }
2417 
2418         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2419         if (!success)
2420             return false;
2421 
2422         //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2423         AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
2424 
2425         Register reg_n;
2426         reg_n.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
2427 
2428         EmulateInstruction::Context context;
2429         context.type = eContextAddition;
2430         context.SetRegisterPlusOffset (reg_n, imm32);
2431 
2432         //R[d] = result;
2433         //if setflags then
2434             //APSR.N = result<31>;
2435             //APSR.Z = IsZeroBit(result);
2436             //APSR.C = carry;
2437             //APSR.V = overflow;
2438         if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
2439             return false;
2440 
2441     }
2442     return true;
2443 }
2444 
2445 // This instruction adds an immediate value to a register value, and writes the result to the destination
2446 // register.  It can optionally update the condition flags based on the result.
2447 bool
2448 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding)
2449 {
2450 #if 0
2451     // ARM pseudo code...
2452     if ConditionPassed() then
2453         EncodingSpecificOperations();
2454         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2455         if d == 15 then
2456             ALUWritePC(result); // setflags is always FALSE here
2457         else
2458             R[d] = result;
2459             if setflags then
2460                 APSR.N = result<31>;
2461                 APSR.Z = IsZeroBit(result);
2462                 APSR.C = carry;
2463                 APSR.V = overflow;
2464 #endif
2465 
2466     bool success = false;
2467 
2468     if (ConditionPassed(opcode))
2469     {
2470         uint32_t Rd, Rn;
2471         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
2472         bool setflags;
2473         switch (encoding)
2474         {
2475         case eEncodingA1:
2476             Rd = Bits32(opcode, 15, 12);
2477             Rn = Bits32(opcode, 19, 16);
2478             setflags = BitIsSet(opcode, 20);
2479             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2480             break;
2481         default:
2482             return false;
2483         }
2484 
2485         // Read the first operand.
2486         uint32_t val1 = ReadCoreReg(Rn, &success);
2487         if (!success)
2488             return false;
2489 
2490         AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
2491 
2492         EmulateInstruction::Context context;
2493         context.type = EmulateInstruction::eContextAddition;
2494         Register dwarf_reg;
2495         dwarf_reg.SetRegister (eRegisterKindDWARF, Rn);
2496         context.SetRegisterPlusOffset (dwarf_reg, imm32);
2497 
2498         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2499             return false;
2500     }
2501     return true;
2502 }
2503 
2504 // This instruction adds a register value and an optionally-shifted register value, and writes the result
2505 // to the destination register. It can optionally update the condition flags based on the result.
2506 bool
2507 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding)
2508 {
2509 #if 0
2510     // ARM pseudo code...
2511     if ConditionPassed() then
2512         EncodingSpecificOperations();
2513         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2514         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2515         if d == 15 then
2516             ALUWritePC(result); // setflags is always FALSE here
2517         else
2518             R[d] = result;
2519             if setflags then
2520                 APSR.N = result<31>;
2521                 APSR.Z = IsZeroBit(result);
2522                 APSR.C = carry;
2523                 APSR.V = overflow;
2524 #endif
2525 
2526     bool success = false;
2527 
2528     if (ConditionPassed(opcode))
2529     {
2530         uint32_t Rd, Rn, Rm;
2531         ARM_ShifterType shift_t;
2532         uint32_t shift_n; // the shift applied to the value read from Rm
2533         bool setflags;
2534         switch (encoding)
2535         {
2536         case eEncodingT1:
2537             Rd = Bits32(opcode, 2, 0);
2538             Rn = Bits32(opcode, 5, 3);
2539             Rm = Bits32(opcode, 8, 6);
2540             setflags = !InITBlock();
2541             shift_t = SRType_LSL;
2542             shift_n = 0;
2543             break;
2544         case eEncodingT2:
2545             Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2546             Rm = Bits32(opcode, 6, 3);
2547             setflags = false;
2548             shift_t = SRType_LSL;
2549             shift_n = 0;
2550             if (Rn == 15 && Rm == 15)
2551                 return false;
2552             if (Rd == 15 && InITBlock() && !LastInITBlock())
2553                 return false;
2554             break;
2555         case eEncodingA1:
2556             Rd = Bits32(opcode, 15, 12);
2557             Rn = Bits32(opcode, 19, 16);
2558             Rm = Bits32(opcode, 3, 0);
2559             setflags = BitIsSet(opcode, 20);
2560             shift_n = DecodeImmShiftARM(opcode, shift_t);
2561             break;
2562         default:
2563             return false;
2564         }
2565 
2566         // Read the first operand.
2567         uint32_t val1 = ReadCoreReg(Rn, &success);
2568         if (!success)
2569             return false;
2570 
2571         // Read the second operand.
2572         uint32_t val2 = ReadCoreReg(Rm, &success);
2573         if (!success)
2574             return false;
2575 
2576         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
2577         AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2578 
2579         EmulateInstruction::Context context;
2580         context.type = EmulateInstruction::eContextAddition;
2581         Register op1_reg;
2582         Register op2_reg;
2583         op1_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rn);
2584         op2_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rm);
2585         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
2586 
2587         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2588             return false;
2589     }
2590     return true;
2591 }
2592 
2593 // Compare Negative (immediate) adds a register value and an immediate value.
2594 // It updates the condition flags based on the result, and discards the result.
2595 bool
2596 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding)
2597 {
2598 #if 0
2599     // ARM pseudo code...
2600     if ConditionPassed() then
2601         EncodingSpecificOperations();
2602         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2603         APSR.N = result<31>;
2604         APSR.Z = IsZeroBit(result);
2605         APSR.C = carry;
2606         APSR.V = overflow;
2607 #endif
2608 
2609     bool success = false;
2610 
2611     uint32_t Rn; // the first operand
2612     uint32_t imm32; // the immediate value to be compared with
2613     switch (encoding) {
2614     case eEncodingT1:
2615         Rn = Bits32(opcode, 19, 16);
2616         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2617         if (Rn == 15)
2618             return false;
2619         break;
2620     case eEncodingA1:
2621         Rn = Bits32(opcode, 19, 16);
2622         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2623         break;
2624     default:
2625         return false;
2626     }
2627     // Read the register value from the operand register Rn.
2628     uint32_t reg_val = ReadCoreReg(Rn, &success);
2629     if (!success)
2630         return false;
2631 
2632     AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
2633 
2634     EmulateInstruction::Context context;
2635     context.type = EmulateInstruction::eContextImmediate;
2636     context.SetNoArgs ();
2637     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2638         return false;
2639 
2640     return true;
2641 }
2642 
2643 // Compare Negative (register) adds a register value and an optionally-shifted register value.
2644 // It updates the condition flags based on the result, and discards the result.
2645 bool
2646 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding)
2647 {
2648 #if 0
2649     // ARM pseudo code...
2650     if ConditionPassed() then
2651         EncodingSpecificOperations();
2652         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2653         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2654         APSR.N = result<31>;
2655         APSR.Z = IsZeroBit(result);
2656         APSR.C = carry;
2657         APSR.V = overflow;
2658 #endif
2659 
2660     bool success = false;
2661 
2662     uint32_t Rn; // the first operand
2663     uint32_t Rm; // the second operand
2664     ARM_ShifterType shift_t;
2665     uint32_t shift_n; // the shift applied to the value read from Rm
2666     switch (encoding) {
2667     case eEncodingT1:
2668         Rn = Bits32(opcode, 2, 0);
2669         Rm = Bits32(opcode, 5, 3);
2670         shift_t = SRType_LSL;
2671         shift_n = 0;
2672         break;
2673     case eEncodingT2:
2674         Rn = Bits32(opcode, 19, 16);
2675         Rm = Bits32(opcode, 3, 0);
2676         shift_n = DecodeImmShiftThumb(opcode, shift_t);
2677         // if n == 15 || BadReg(m) then UNPREDICTABLE;
2678         if (Rn == 15 || BadReg(Rm))
2679             return false;
2680         break;
2681     case eEncodingA1:
2682         Rn = Bits32(opcode, 19, 16);
2683         Rm = Bits32(opcode, 3, 0);
2684         shift_n = DecodeImmShiftARM(opcode, shift_t);
2685         break;
2686     default:
2687         return false;
2688     }
2689     // Read the register value from register Rn.
2690     uint32_t val1 = ReadCoreReg(Rn, &success);
2691     if (!success)
2692         return false;
2693 
2694     // Read the register value from register Rm.
2695     uint32_t val2 = ReadCoreReg(Rm, &success);
2696     if (!success)
2697         return false;
2698 
2699     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
2700     AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2701 
2702     EmulateInstruction::Context context;
2703     context.type = EmulateInstruction::eContextImmediate;
2704     context.SetNoArgs();
2705     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2706         return false;
2707 
2708     return true;
2709 }
2710 
2711 // Compare (immediate) subtracts an immediate value from a register value.
2712 // It updates the condition flags based on the result, and discards the result.
2713 bool
2714 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding)
2715 {
2716 #if 0
2717     // ARM pseudo code...
2718     if ConditionPassed() then
2719         EncodingSpecificOperations();
2720         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2721         APSR.N = result<31>;
2722         APSR.Z = IsZeroBit(result);
2723         APSR.C = carry;
2724         APSR.V = overflow;
2725 #endif
2726 
2727     bool success = false;
2728 
2729     uint32_t Rn; // the first operand
2730     uint32_t imm32; // the immediate value to be compared with
2731     switch (encoding) {
2732     case eEncodingT1:
2733         Rn = Bits32(opcode, 10, 8);
2734         imm32 = Bits32(opcode, 7, 0);
2735         break;
2736     case eEncodingT2:
2737         Rn = Bits32(opcode, 19, 16);
2738         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2739         if (Rn == 15)
2740             return false;
2741         break;
2742     case eEncodingA1:
2743         Rn = Bits32(opcode, 19, 16);
2744         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2745         break;
2746     default:
2747         return false;
2748     }
2749     // Read the register value from the operand register Rn.
2750     uint32_t reg_val = ReadCoreReg(Rn, &success);
2751     if (!success)
2752         return false;
2753 
2754     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
2755 
2756     EmulateInstruction::Context context;
2757     context.type = EmulateInstruction::eContextImmediate;
2758     context.SetNoArgs ();
2759     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2760         return false;
2761 
2762     return true;
2763 }
2764 
2765 // Compare (register) subtracts an optionally-shifted register value from a register value.
2766 // It updates the condition flags based on the result, and discards the result.
2767 bool
2768 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding)
2769 {
2770 #if 0
2771     // ARM pseudo code...
2772     if ConditionPassed() then
2773         EncodingSpecificOperations();
2774         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2775         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2776         APSR.N = result<31>;
2777         APSR.Z = IsZeroBit(result);
2778         APSR.C = carry;
2779         APSR.V = overflow;
2780 #endif
2781 
2782     bool success = false;
2783 
2784     uint32_t Rn; // the first operand
2785     uint32_t Rm; // the second operand
2786     ARM_ShifterType shift_t;
2787     uint32_t shift_n; // the shift applied to the value read from Rm
2788     switch (encoding) {
2789     case eEncodingT1:
2790         Rn = Bits32(opcode, 2, 0);
2791         Rm = Bits32(opcode, 5, 3);
2792         shift_t = SRType_LSL;
2793         shift_n = 0;
2794         break;
2795     case eEncodingT2:
2796         Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2797         Rm = Bits32(opcode, 6, 3);
2798         shift_t = SRType_LSL;
2799         shift_n = 0;
2800         if (Rn < 8 && Rm < 8)
2801             return false;
2802         if (Rn == 15 || Rm == 15)
2803             return false;
2804         break;
2805     case eEncodingA1:
2806         Rn = Bits32(opcode, 19, 16);
2807         Rm = Bits32(opcode, 3, 0);
2808         shift_n = DecodeImmShiftARM(opcode, shift_t);
2809         break;
2810     default:
2811         return false;
2812     }
2813     // Read the register value from register Rn.
2814     uint32_t val1 = ReadCoreReg(Rn, &success);
2815     if (!success)
2816         return false;
2817 
2818     // Read the register value from register Rm.
2819     uint32_t val2 = ReadCoreReg(Rm, &success);
2820     if (!success)
2821         return false;
2822 
2823     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
2824     AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
2825 
2826     EmulateInstruction::Context context;
2827     context.type = EmulateInstruction::eContextImmediate;
2828     context.SetNoArgs();
2829     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2830         return false;
2831 
2832     return true;
2833 }
2834 
2835 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
2836 // shifting in copies of its sign bit, and writes the result to the destination register.  It can
2837 // optionally update the condition flags based on the result.
2838 bool
2839 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding)
2840 {
2841 #if 0
2842     // ARM pseudo code...
2843     if ConditionPassed() then
2844         EncodingSpecificOperations();
2845         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2846         if d == 15 then         // Can only occur for ARM encoding
2847             ALUWritePC(result); // setflags is always FALSE here
2848         else
2849             R[d] = result;
2850             if setflags then
2851                 APSR.N = result<31>;
2852                 APSR.Z = IsZeroBit(result);
2853                 APSR.C = carry;
2854                 // APSR.V unchanged
2855 #endif
2856 
2857     return EmulateShiftImm (opcode, encoding, SRType_ASR);
2858 }
2859 
2860 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
2861 // shifting in copies of its sign bit, and writes the result to the destination register.
2862 // The variable number of bits is read from the bottom byte of a register. It can optionally update
2863 // the condition flags based on the result.
2864 bool
2865 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding)
2866 {
2867 #if 0
2868     // ARM pseudo code...
2869     if ConditionPassed() then
2870         EncodingSpecificOperations();
2871         shift_n = UInt(R[m]<7:0>);
2872         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2873         R[d] = result;
2874         if setflags then
2875             APSR.N = result<31>;
2876             APSR.Z = IsZeroBit(result);
2877             APSR.C = carry;
2878             // APSR.V unchanged
2879 #endif
2880 
2881     return EmulateShiftReg (opcode, encoding, SRType_ASR);
2882 }
2883 
2884 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
2885 // shifting in zeros, and writes the result to the destination register.  It can optionally
2886 // update the condition flags based on the result.
2887 bool
2888 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding)
2889 {
2890 #if 0
2891     // ARM pseudo code...
2892     if ConditionPassed() then
2893         EncodingSpecificOperations();
2894         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
2895         if d == 15 then         // Can only occur for ARM encoding
2896             ALUWritePC(result); // setflags is always FALSE here
2897         else
2898             R[d] = result;
2899             if setflags then
2900                 APSR.N = result<31>;
2901                 APSR.Z = IsZeroBit(result);
2902                 APSR.C = carry;
2903                 // APSR.V unchanged
2904 #endif
2905 
2906     return EmulateShiftImm (opcode, encoding, SRType_LSL);
2907 }
2908 
2909 // Logical Shift Left (register) shifts a register value left by a variable number of bits,
2910 // shifting in zeros, and writes the result to the destination register.  The variable number
2911 // of bits is read from the bottom byte of a register. It can optionally update the condition
2912 // flags based on the result.
2913 bool
2914 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding)
2915 {
2916 #if 0
2917     // ARM pseudo code...
2918     if ConditionPassed() then
2919         EncodingSpecificOperations();
2920         shift_n = UInt(R[m]<7:0>);
2921         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
2922         R[d] = result;
2923         if setflags then
2924             APSR.N = result<31>;
2925             APSR.Z = IsZeroBit(result);
2926             APSR.C = carry;
2927             // APSR.V unchanged
2928 #endif
2929 
2930     return EmulateShiftReg (opcode, encoding, SRType_LSL);
2931 }
2932 
2933 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
2934 // shifting in zeros, and writes the result to the destination register.  It can optionally
2935 // update the condition flags based on the result.
2936 bool
2937 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding)
2938 {
2939 #if 0
2940     // ARM pseudo code...
2941     if ConditionPassed() then
2942         EncodingSpecificOperations();
2943         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
2944         if d == 15 then         // Can only occur for ARM encoding
2945             ALUWritePC(result); // setflags is always FALSE here
2946         else
2947             R[d] = result;
2948             if setflags then
2949                 APSR.N = result<31>;
2950                 APSR.Z = IsZeroBit(result);
2951                 APSR.C = carry;
2952                 // APSR.V unchanged
2953 #endif
2954 
2955     return EmulateShiftImm (opcode, encoding, SRType_LSR);
2956 }
2957 
2958 // Logical Shift Right (register) shifts a register value right by a variable number of bits,
2959 // shifting in zeros, and writes the result to the destination register.  The variable number
2960 // of bits is read from the bottom byte of a register. It can optionally update the condition
2961 // flags based on the result.
2962 bool
2963 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding)
2964 {
2965 #if 0
2966     // ARM pseudo code...
2967     if ConditionPassed() then
2968         EncodingSpecificOperations();
2969         shift_n = UInt(R[m]<7:0>);
2970         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
2971         R[d] = result;
2972         if setflags then
2973             APSR.N = result<31>;
2974             APSR.Z = IsZeroBit(result);
2975             APSR.C = carry;
2976             // APSR.V unchanged
2977 #endif
2978 
2979     return EmulateShiftReg (opcode, encoding, SRType_LSR);
2980 }
2981 
2982 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
2983 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
2984 // It can optionally update the condition flags based on the result.
2985 bool
2986 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding)
2987 {
2988 #if 0
2989     // ARM pseudo code...
2990     if ConditionPassed() then
2991         EncodingSpecificOperations();
2992         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
2993         if d == 15 then         // Can only occur for ARM encoding
2994             ALUWritePC(result); // setflags is always FALSE here
2995         else
2996             R[d] = result;
2997             if setflags then
2998                 APSR.N = result<31>;
2999                 APSR.Z = IsZeroBit(result);
3000                 APSR.C = carry;
3001                 // APSR.V unchanged
3002 #endif
3003 
3004     return EmulateShiftImm (opcode, encoding, SRType_ROR);
3005 }
3006 
3007 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
3008 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3009 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
3010 // flags based on the result.
3011 bool
3012 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding)
3013 {
3014 #if 0
3015     // ARM pseudo code...
3016     if ConditionPassed() then
3017         EncodingSpecificOperations();
3018         shift_n = UInt(R[m]<7:0>);
3019         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3020         R[d] = result;
3021         if setflags then
3022             APSR.N = result<31>;
3023             APSR.Z = IsZeroBit(result);
3024             APSR.C = carry;
3025             // APSR.V unchanged
3026 #endif
3027 
3028     return EmulateShiftReg (opcode, encoding, SRType_ROR);
3029 }
3030 
3031 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
3032 // with the carry flag shifted into bit [31].
3033 //
3034 // RRX can optionally update the condition flags based on the result.
3035 // In that case, bit [0] is shifted into the carry flag.
3036 bool
3037 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding)
3038 {
3039 #if 0
3040     // ARM pseudo code...
3041     if ConditionPassed() then
3042         EncodingSpecificOperations();
3043         (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3044         if d == 15 then         // Can only occur for ARM encoding
3045             ALUWritePC(result); // setflags is always FALSE here
3046         else
3047             R[d] = result;
3048             if setflags then
3049                 APSR.N = result<31>;
3050                 APSR.Z = IsZeroBit(result);
3051                 APSR.C = carry;
3052                 // APSR.V unchanged
3053 #endif
3054 
3055     return EmulateShiftImm (opcode, encoding, SRType_RRX);
3056 }
3057 
3058 bool
3059 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3060 {
3061     assert(shift_type == SRType_ASR
3062            || shift_type == SRType_LSL
3063            || shift_type == SRType_LSR
3064            || shift_type == SRType_ROR
3065            || shift_type == SRType_RRX);
3066 
3067     bool success = false;
3068 
3069     if (ConditionPassed(opcode))
3070     {
3071         uint32_t Rd;    // the destination register
3072         uint32_t Rm;    // the first operand register
3073         uint32_t imm5;  // encoding for the shift amount
3074         uint32_t carry; // the carry bit after the shift operation
3075         bool setflags;
3076 
3077         // Special case handling!
3078         // A8.6.139 ROR (immediate) -- Encoding T1
3079         ARMEncoding use_encoding = encoding;
3080         if (shift_type == SRType_ROR && use_encoding == eEncodingT1)
3081         {
3082             // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
3083             // have the same decoding of bit fields as the other Thumb2 shift operations.
3084             use_encoding = eEncodingT2;
3085         }
3086 
3087         switch (use_encoding) {
3088         case eEncodingT1:
3089             // Due to the above special case handling!
3090             assert(shift_type != SRType_ROR);
3091 
3092             Rd = Bits32(opcode, 2, 0);
3093             Rm = Bits32(opcode, 5, 3);
3094             setflags = !InITBlock();
3095             imm5 = Bits32(opcode, 10, 6);
3096             break;
3097         case eEncodingT2:
3098             // A8.6.141 RRX
3099             assert(shift_type != SRType_RRX);
3100 
3101             Rd = Bits32(opcode, 11, 8);
3102             Rm = Bits32(opcode, 3, 0);
3103             setflags = BitIsSet(opcode, 20);
3104             imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3105             if (BadReg(Rd) || BadReg(Rm))
3106                 return false;
3107             break;
3108         case eEncodingA1:
3109             Rd = Bits32(opcode, 15, 12);
3110             Rm = Bits32(opcode, 3, 0);
3111             setflags = BitIsSet(opcode, 20);
3112             imm5 = Bits32(opcode, 11, 7);
3113             break;
3114         default:
3115             return false;
3116         }
3117 
3118         // A8.6.139 ROR (immediate)
3119         if (shift_type == SRType_ROR && imm5 == 0)
3120             shift_type = SRType_RRX;
3121 
3122         // Get the first operand.
3123         uint32_t value = ReadCoreReg (Rm, &success);
3124         if (!success)
3125             return false;
3126 
3127         // Decode the shift amount if not RRX.
3128         uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3129 
3130         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry);
3131 
3132         // The context specifies that an immediate is to be moved into Rd.
3133         EmulateInstruction::Context context;
3134         context.type = EmulateInstruction::eContextImmediate;
3135         context.SetNoArgs ();
3136 
3137         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3138             return false;
3139     }
3140     return true;
3141 }
3142 
3143 bool
3144 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3145 {
3146     assert(shift_type == SRType_ASR || shift_type == SRType_LSL || shift_type == SRType_LSR);
3147 
3148     bool success = false;
3149 
3150     if (ConditionPassed(opcode))
3151     {
3152         uint32_t Rd;    // the destination register
3153         uint32_t Rn;    // the first operand register
3154         uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
3155         uint32_t carry; // the carry bit after the shift operation
3156         bool setflags;
3157         switch (encoding) {
3158         case eEncodingT1:
3159             Rd = Bits32(opcode, 2, 0);
3160             Rn = Rd;
3161             Rm = Bits32(opcode, 5, 3);
3162             setflags = !InITBlock();
3163             break;
3164         case eEncodingT2:
3165             Rd = Bits32(opcode, 11, 8);
3166             Rn = Bits32(opcode, 19, 16);
3167             Rm = Bits32(opcode, 3, 0);
3168             setflags = BitIsSet(opcode, 20);
3169             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3170                 return false;
3171             break;
3172         case eEncodingA1:
3173             Rd = Bits32(opcode, 15, 12);
3174             Rn = Bits32(opcode, 3, 0);
3175             Rm = Bits32(opcode, 11, 8);
3176             setflags = BitIsSet(opcode, 20);
3177             if (Rd == 15 || Rn == 15 || Rm == 15)
3178                 return false;
3179             break;
3180         default:
3181             return false;
3182         }
3183 
3184         // Get the first operand.
3185         uint32_t value = ReadCoreReg (Rn, &success);
3186         if (!success)
3187             return false;
3188         // Get the Rm register content.
3189         uint32_t val = ReadCoreReg (Rm, &success);
3190         if (!success)
3191             return false;
3192 
3193         // Get the shift amount.
3194         uint32_t amt = Bits32(val, 7, 0);
3195 
3196         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry);
3197 
3198         // The context specifies that an immediate is to be moved into Rd.
3199         EmulateInstruction::Context context;
3200         context.type = EmulateInstruction::eContextImmediate;
3201         context.SetNoArgs ();
3202 
3203         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3204             return false;
3205     }
3206     return true;
3207 }
3208 
3209 // LDM loads multiple registers from consecutive memory locations, using an
3210 // address from a base register.  Optionally the address just above the highest of those locations
3211 // can be written back to the base register.
3212 bool
3213 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding)
3214 {
3215 #if 0
3216     // ARM pseudo code...
3217     if ConditionPassed()
3218         EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3219         address = R[n];
3220 
3221         for i = 0 to 14
3222             if registers<i> == '1' then
3223                 R[i] = MemA[address, 4]; address = address + 4;
3224         if registers<15> == '1' then
3225             LoadWritePC (MemA[address, 4]);
3226 
3227         if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3228         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3229 
3230 #endif
3231 
3232     bool success = false;
3233 
3234     if (ConditionPassed(opcode))
3235     {
3236         uint32_t n;
3237         uint32_t registers = 0;
3238         bool wback;
3239         const uint32_t addr_byte_size = GetAddressByteSize();
3240         switch (encoding)
3241         {
3242             case eEncodingT1:
3243                 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0');
3244                 n = Bits32 (opcode, 10, 8);
3245                 registers = Bits32 (opcode, 7, 0);
3246                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3247                 wback = BitIsClear (registers, n);
3248                 // if BitCount(registers) < 1 then UNPREDICTABLE;
3249                 if (BitCount(registers) < 1)
3250                     return false;
3251                 break;
3252             case eEncodingT2:
3253                 // if W == '1' && Rn == '1101' then SEE POP;
3254                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3255                 n = Bits32 (opcode, 19, 16);
3256                 registers = Bits32 (opcode, 15, 0);
3257                 registers = registers & 0xdfff; // Make sure bit 13 is zero.
3258                 wback = BitIsSet (opcode, 21);
3259 
3260                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3261                 if ((n == 15)
3262                     || (BitCount (registers) < 2)
3263                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3264                     return false;
3265 
3266                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3267                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3268                     return false;
3269 
3270                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3271                 if (wback
3272                     && BitIsSet (registers, n))
3273                     return false;
3274                 break;
3275 
3276             case eEncodingA1:
3277                 n = Bits32 (opcode, 19, 16);
3278                 registers = Bits32 (opcode, 15, 0);
3279                 wback = BitIsSet (opcode, 21);
3280                 if ((n == 15)
3281                     || (BitCount (registers) < 1))
3282                     return false;
3283                 break;
3284             default:
3285                 return false;
3286         }
3287 
3288         int32_t offset = 0;
3289         const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3290         if (!success)
3291             return false;
3292 
3293         EmulateInstruction::Context context;
3294         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3295         Register dwarf_reg;
3296         dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3297         context.SetRegisterPlusOffset (dwarf_reg, offset);
3298 
3299         for (int i = 0; i < 14; ++i)
3300         {
3301             if (BitIsSet (registers, i))
3302             {
3303                 context.type = EmulateInstruction::eContextRegisterPlusOffset;
3304                 context.SetRegisterPlusOffset (dwarf_reg, offset);
3305                 if (wback && (n == 13)) // Pop Instruction
3306                     context.type = EmulateInstruction::eContextPopRegisterOffStack;
3307 
3308                 // R[i] = MemA [address, 4]; address = address + 4;
3309                 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3310                 if (!success)
3311                     return false;
3312 
3313                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3314                     return false;
3315 
3316                 offset += addr_byte_size;
3317             }
3318         }
3319 
3320         if (BitIsSet (registers, 15))
3321         {
3322             //LoadWritePC (MemA [address, 4]);
3323             context.type = EmulateInstruction::eContextRegisterPlusOffset;
3324             context.SetRegisterPlusOffset (dwarf_reg, offset);
3325             uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3326             if (!success)
3327                 return false;
3328             // In ARMv5T and above, this is an interworking branch.
3329             if (!LoadWritePC(context, data))
3330                 return false;
3331         }
3332 
3333         if (wback && BitIsClear (registers, n))
3334         {
3335             // R[n] = R[n] + 4 * BitCount (registers)
3336             int32_t offset = addr_byte_size * BitCount (registers);
3337             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3338             context.SetRegisterPlusOffset (dwarf_reg, offset);
3339 
3340             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
3341                 return false;
3342         }
3343         if (wback && BitIsSet (registers, n))
3344             // R[n] bits(32) UNKNOWN;
3345             return WriteBits32Unknown (n);
3346     }
3347     return true;
3348 }
3349 
3350 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register.
3351 // The consecutive memory locations end at this address and the address just below the lowest of those locations
3352 // can optionally be written back to the base register.
3353 bool
3354 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding)
3355 {
3356 #if 0
3357     // ARM pseudo code...
3358     if ConditionPassed() then
3359         EncodingSpecificOperations();
3360         address = R[n] - 4*BitCount(registers) + 4;
3361 
3362         for i = 0 to 14
3363             if registers<i> == '1' then
3364                   R[i] = MemA[address,4]; address = address + 4;
3365 
3366         if registers<15> == '1' then
3367             LoadWritePC(MemA[address,4]);
3368 
3369         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3370         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3371 #endif
3372 
3373     bool success = false;
3374 
3375     if (ConditionPassed(opcode))
3376     {
3377         uint32_t n;
3378         uint32_t registers = 0;
3379         bool wback;
3380         const uint32_t addr_byte_size = GetAddressByteSize();
3381 
3382         // EncodingSpecificOperations();
3383         switch (encoding)
3384         {
3385             case eEncodingA1:
3386                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3387                 n = Bits32 (opcode, 19, 16);
3388                 registers = Bits32 (opcode, 15, 0);
3389                 wback = BitIsSet (opcode, 21);
3390 
3391                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3392                 if ((n == 15) || (BitCount (registers) < 1))
3393                     return false;
3394 
3395                 break;
3396 
3397             default:
3398                 return false;
3399         }
3400         // address = R[n] - 4*BitCount(registers) + 4;
3401 
3402         int32_t offset = 0;
3403         addr_t Rn = ReadCoreReg (n, &success);
3404 
3405         if (!success)
3406             return false;
3407 
3408         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size;
3409 
3410         EmulateInstruction::Context context;
3411         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3412         Register dwarf_reg;
3413         dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3414         context.SetRegisterPlusOffset (dwarf_reg, offset);
3415 
3416         // for i = 0 to 14
3417         for (int i = 0; i < 14; ++i)
3418         {
3419             // if registers<i> == '1' then
3420             if (BitIsSet (registers, i))
3421             {
3422                   // R[i] = MemA[address,4]; address = address + 4;
3423                   context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3424                   uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3425                   if (!success)
3426                       return false;
3427                   if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3428                       return false;
3429                   offset += addr_byte_size;
3430             }
3431         }
3432 
3433         // if registers<15> == '1' then
3434         //     LoadWritePC(MemA[address,4]);
3435         if (BitIsSet (registers, 15))
3436         {
3437             context.SetRegisterPlusOffset (dwarf_reg, offset);
3438             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3439             if (!success)
3440                 return false;
3441             // In ARMv5T and above, this is an interworking branch.
3442             if (!LoadWritePC(context, data))
3443                 return false;
3444         }
3445 
3446         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3447         if (wback && BitIsClear (registers, n))
3448         {
3449             if (!success)
3450                 return false;
3451 
3452             offset = (addr_byte_size * BitCount (registers)) * -1;
3453             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3454             context.SetImmediateSigned (offset);
3455             addr_t addr = Rn + offset;
3456             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3457                 return false;
3458         }
3459 
3460         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3461         if (wback && BitIsSet (registers, n))
3462             return WriteBits32Unknown (n);
3463     }
3464     return true;
3465 }
3466 
3467 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
3468 // consecutive memory lcoations end just below this address, and the address of the lowest of those locations can
3469 // be optionally written back to the base register.
3470 bool
3471 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding)
3472 {
3473 #if 0
3474     // ARM pseudo code...
3475     if ConditionPassed() then
3476         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3477         address = R[n] - 4*BitCount(registers);
3478 
3479         for i = 0 to 14
3480             if registers<i> == '1' then
3481                   R[i] = MemA[address,4]; address = address + 4;
3482         if registers<15> == '1' then
3483                   LoadWritePC(MemA[address,4]);
3484 
3485         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3486         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3487 #endif
3488 
3489     bool success = false;
3490 
3491     if (ConditionPassed(opcode))
3492     {
3493         uint32_t n;
3494         uint32_t registers = 0;
3495         bool wback;
3496         const uint32_t addr_byte_size = GetAddressByteSize();
3497         switch (encoding)
3498         {
3499             case eEncodingT1:
3500                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3501                 n = Bits32 (opcode, 19, 16);
3502                 registers = Bits32 (opcode, 15, 0);
3503                 registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
3504                 wback = BitIsSet (opcode, 21);
3505 
3506                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3507                 if ((n == 15)
3508                     || (BitCount (registers) < 2)
3509                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3510                     return false;
3511 
3512                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3513                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3514                     return false;
3515 
3516                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3517                 if (wback && BitIsSet (registers, n))
3518                     return false;
3519 
3520                 break;
3521 
3522             case eEncodingA1:
3523                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3524                 n = Bits32 (opcode, 19, 16);
3525                 registers = Bits32 (opcode, 15, 0);
3526                 wback = BitIsSet (opcode, 21);
3527 
3528                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3529                 if ((n == 15) || (BitCount (registers) < 1))
3530                     return false;
3531 
3532                 break;
3533 
3534             default:
3535                 return false;
3536         }
3537 
3538         // address = R[n] - 4*BitCount(registers);
3539 
3540         int32_t offset = 0;
3541         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3542 
3543         if (!success)
3544             return false;
3545 
3546         addr_t address = Rn - (addr_byte_size * BitCount (registers));
3547         EmulateInstruction::Context context;
3548         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3549         Register dwarf_reg;
3550         dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3551         context.SetRegisterPlusOffset (dwarf_reg, Rn - address);
3552 
3553         for (int i = 0; i < 14; ++i)
3554         {
3555             if (BitIsSet (registers, i))
3556             {
3557                 // R[i] = MemA[address,4]; address = address + 4;
3558                 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3559                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3560                 if (!success)
3561                     return false;
3562 
3563                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3564                     return false;
3565 
3566                 offset += addr_byte_size;
3567             }
3568         }
3569 
3570         // if registers<15> == '1' then
3571         //     LoadWritePC(MemA[address,4]);
3572         if (BitIsSet (registers, 15))
3573         {
3574             context.SetRegisterPlusOffset (dwarf_reg, offset);
3575             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3576             if (!success)
3577                 return false;
3578             // In ARMv5T and above, this is an interworking branch.
3579             if (!LoadWritePC(context, data))
3580                 return false;
3581         }
3582 
3583         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3584         if (wback && BitIsClear (registers, n))
3585         {
3586             if (!success)
3587                 return false;
3588 
3589             offset = (addr_byte_size * BitCount (registers)) * -1;
3590             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3591             context.SetImmediateSigned (offset);
3592             addr_t addr = Rn + offset;
3593             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3594                 return false;
3595         }
3596 
3597         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3598         if (wback && BitIsSet (registers, n))
3599             return WriteBits32Unknown (n);
3600     }
3601     return true;
3602 }
3603 
3604 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
3605 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can
3606 // optinoally be written back to the base register.
3607 bool
3608 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding)
3609 {
3610 #if 0
3611     if ConditionPassed() then
3612         EncodingSpecificOperations();
3613         address = R[n] + 4;
3614 
3615         for i = 0 to 14
3616             if registers<i> == '1' then
3617                   R[i] = MemA[address,4]; address = address + 4;
3618         if registers<15> == '1' then
3619             LoadWritePC(MemA[address,4]);
3620 
3621         if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3622         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3623 #endif
3624 
3625     bool success = false;
3626 
3627     if (ConditionPassed(opcode))
3628     {
3629         uint32_t n;
3630         uint32_t registers = 0;
3631         bool wback;
3632         const uint32_t addr_byte_size = GetAddressByteSize();
3633         switch (encoding)
3634         {
3635             case eEncodingA1:
3636                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3637                 n = Bits32 (opcode, 19, 16);
3638                 registers = Bits32 (opcode, 15, 0);
3639                 wback = BitIsSet (opcode, 21);
3640 
3641                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3642                 if ((n == 15) || (BitCount (registers) < 1))
3643                     return false;
3644 
3645                 break;
3646             default:
3647                 return false;
3648         }
3649         // address = R[n] + 4;
3650 
3651         int32_t offset = 0;
3652         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3653 
3654         if (!success)
3655             return false;
3656 
3657         addr_t address = Rn + addr_byte_size;
3658 
3659         EmulateInstruction::Context context;
3660         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3661         Register dwarf_reg;
3662         dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3663         context.SetRegisterPlusOffset (dwarf_reg, offset);
3664 
3665         for (int i = 0; i < 14; ++i)
3666         {
3667             if (BitIsSet (registers, i))
3668             {
3669                 // R[i] = MemA[address,4]; address = address + 4;
3670 
3671                 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size);
3672                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3673                 if (!success)
3674                     return false;
3675 
3676                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3677                     return false;
3678 
3679                 offset += addr_byte_size;
3680             }
3681         }
3682 
3683         // if registers<15> == '1' then
3684         //     LoadWritePC(MemA[address,4]);
3685         if (BitIsSet (registers, 15))
3686         {
3687             context.SetRegisterPlusOffset (dwarf_reg, offset);
3688             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3689             if (!success)
3690                 return false;
3691             // In ARMv5T and above, this is an interworking branch.
3692             if (!LoadWritePC(context, data))
3693                 return false;
3694         }
3695 
3696         // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3697         if (wback && BitIsClear (registers, n))
3698         {
3699             if (!success)
3700                 return false;
3701 
3702             offset = addr_byte_size * BitCount (registers);
3703             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3704             context.SetImmediateSigned (offset);
3705             addr_t addr = Rn + offset;
3706             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3707                 return false;
3708         }
3709 
3710         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3711         if (wback && BitIsSet (registers, n))
3712             return WriteBits32Unknown (n);
3713     }
3714     return true;
3715 }
3716 
3717 // Load Register (immediate) calculates an address from a base register value and
3718 // an immediate offset, loads a word from memory, and writes to a register.
3719 // LDR (immediate, Thumb)
3720 bool
3721 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding)
3722 {
3723 #if 0
3724     // ARM pseudo code...
3725     if (ConditionPassed())
3726     {
3727         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3728         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3729         address = if index then offset_addr else R[n];
3730         data = MemU[address,4];
3731         if wback then R[n] = offset_addr;
3732         if t == 15 then
3733             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3734         elsif UnalignedSupport() || address<1:0> = '00' then
3735             R[t] = data;
3736         else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3737     }
3738 #endif
3739 
3740     bool success = false;
3741 
3742     if (ConditionPassed(opcode))
3743     {
3744         uint32_t Rt; // the destination register
3745         uint32_t Rn; // the base register
3746         uint32_t imm32; // the immediate offset used to form the address
3747         addr_t offset_addr; // the offset address
3748         addr_t address; // the calculated address
3749         uint32_t data; // the literal data value from memory load
3750         bool add, index, wback;
3751         switch (encoding) {
3752             case eEncodingT1:
3753                 Rt = Bits32(opcode, 2, 0);
3754                 Rn = Bits32(opcode, 5, 3);
3755                 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3756                 // index = TRUE; add = TRUE; wback = FALSE
3757                 add = true;
3758                 index = true;
3759                 wback = false;
3760 
3761                 break;
3762 
3763             case eEncodingT2:
3764                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
3765                 Rt = Bits32 (opcode, 10, 8);
3766                 Rn = 13;
3767                 imm32 = Bits32 (opcode, 7, 0) << 2;
3768 
3769                 // index = TRUE; add = TRUE; wback = FALSE;
3770                 index = true;
3771                 add = true;
3772                 wback = false;
3773 
3774                 break;
3775 
3776             case eEncodingT3:
3777                 // if Rn == '1111' then SEE LDR (literal);
3778                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
3779                 Rt = Bits32 (opcode, 15, 12);
3780                 Rn = Bits32 (opcode, 19, 16);
3781                 imm32 = Bits32 (opcode, 11, 0);
3782 
3783                 // index = TRUE; add = TRUE; wback = FALSE;
3784                 index = true;
3785                 add = true;
3786                 wback = false;
3787 
3788                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3789                 if ((Rt == 15) && InITBlock() && !LastInITBlock())
3790                     return false;
3791 
3792                 break;
3793 
3794             case eEncodingT4:
3795                 // if Rn == '1111' then SEE LDR (literal);
3796                 // if P == '1' && U == '1' && W == '0' then SEE LDRT;
3797                 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
3798                 // if P == '0' && W == '0' then UNDEFINED;
3799                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
3800                     return false;
3801 
3802                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
3803                 Rt = Bits32 (opcode, 15, 12);
3804                 Rn = Bits32 (opcode, 19, 16);
3805                 imm32 = Bits32 (opcode, 7, 0);
3806 
3807                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
3808                 index = BitIsSet (opcode, 10);
3809                 add = BitIsSet (opcode, 9);
3810                 wback = BitIsSet (opcode, 8);
3811 
3812                 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
3813                 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock()))
3814                     return false;
3815 
3816                 break;
3817 
3818             default:
3819                 return false;
3820         }
3821         uint32_t base = ReadCoreReg (Rn, &success);
3822         if (!success)
3823             return false;
3824         if (add)
3825             offset_addr = base + imm32;
3826         else
3827             offset_addr = base - imm32;
3828 
3829         address = (index ? offset_addr : base);
3830 
3831         Register base_reg;
3832         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + Rn);
3833         if (wback)
3834         {
3835             EmulateInstruction::Context ctx;
3836             ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
3837             ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3838 
3839             if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
3840                 return false;
3841         }
3842 
3843         // Prepare to write to the Rt register.
3844         EmulateInstruction::Context context;
3845         context.type = EmulateInstruction::eContextRegisterLoad;
3846         context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3847 
3848         // Read memory from the address.
3849         data = MemURead(context, address, 4, 0, &success);
3850         if (!success)
3851             return false;
3852 
3853         if (Rt == 15)
3854         {
3855             if (Bits32(address, 1, 0) == 0)
3856             {
3857                 if (!LoadWritePC(context, data))
3858                     return false;
3859             }
3860             else
3861                 return false;
3862         }
3863         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
3864         {
3865             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
3866                 return false;
3867         }
3868         else
3869             WriteBits32Unknown (Rt);
3870     }
3871     return true;
3872 }
3873 
3874 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
3875 // from a base register.  The consecutive memory locations start at this address, and teh address just above the last
3876 // of those locations can optionally be written back to the base register.
3877 bool
3878 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding)
3879 {
3880 #if 0
3881     if ConditionPassed() then
3882         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3883         address = R[n];
3884 
3885         for i = 0 to 14
3886             if registers<i> == '1' then
3887                 if i == n && wback && i != LowestSetBit(registers) then
3888                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
3889                 else
3890                     MemA[address,4] = R[i];
3891                 address = address + 4;
3892 
3893         if registers<15> == '1' then // Only possible for encoding A1
3894             MemA[address,4] = PCStoreValue();
3895         if wback then R[n] = R[n] + 4*BitCount(registers);
3896 #endif
3897 
3898     bool success = false;
3899 
3900     if (ConditionPassed(opcode))
3901     {
3902         uint32_t n;
3903         uint32_t registers = 0;
3904         bool wback;
3905         const uint32_t addr_byte_size = GetAddressByteSize();
3906 
3907         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3908         switch (encoding)
3909         {
3910             case eEncodingT1:
3911                 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
3912                 n = Bits32 (opcode, 10, 8);
3913                 registers = Bits32 (opcode, 7, 0);
3914                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3915                 wback = true;
3916 
3917                 // if BitCount(registers) < 1 then UNPREDICTABLE;
3918                 if (BitCount (registers) < 1)
3919                     return false;
3920 
3921                 break;
3922 
3923             case eEncodingT2:
3924                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
3925                 n = Bits32 (opcode, 19, 16);
3926                 registers = Bits32 (opcode, 15, 0);
3927                 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
3928                 wback = BitIsSet (opcode, 21);
3929 
3930                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
3931                 if ((n == 15) || (BitCount (registers) < 2))
3932                     return false;
3933 
3934                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3935                 if (wback && BitIsSet (registers, n))
3936                     return false;
3937 
3938                 break;
3939 
3940             case eEncodingA1:
3941                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3942                 n = Bits32 (opcode, 19, 16);
3943                 registers = Bits32 (opcode, 15, 0);
3944                 wback = BitIsSet (opcode, 21);
3945 
3946                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3947                 if ((n == 15) || (BitCount (registers) < 1))
3948                     return false;
3949 
3950                 break;
3951 
3952             default:
3953                 return false;
3954         }
3955 
3956         // address = R[n];
3957         int32_t offset = 0;
3958         const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3959         if (!success)
3960             return false;
3961 
3962         EmulateInstruction::Context context;
3963         context.type = EmulateInstruction::eContextRegisterStore;
3964         Register base_reg;
3965         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
3966 
3967         // for i = 0 to 14
3968         int lowest_set_bit = 14;
3969         for (int i = 0; i < 14; ++i)
3970         {
3971             // if registers<i> == '1' then
3972             if (BitIsSet (registers, i))
3973             {
3974                   if (i < lowest_set_bit)
3975                       lowest_set_bit = i;
3976                   // if i == n && wback && i != LowestSetBit(registers) then
3977                   if ((i == n) && wback && (i != lowest_set_bit))
3978                       // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
3979                       WriteBits32UnknownToMemory (address + offset);
3980                   else
3981                   {
3982                      // MemA[address,4] = R[i];
3983                       uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
3984                       if (!success)
3985                           return false;
3986 
3987                       Register data_reg;
3988                       data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
3989                       context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
3990                       if (!MemAWrite (context, address + offset, data, addr_byte_size))
3991                           return false;
3992                   }
3993 
3994                   // address = address + 4;
3995                   offset += addr_byte_size;
3996             }
3997         }
3998 
3999         // if registers<15> == '1' then // Only possible for encoding A1
4000         //     MemA[address,4] = PCStoreValue();
4001         if (BitIsSet (registers, 15))
4002         {
4003             Register pc_reg;
4004             pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
4005             context.SetRegisterPlusOffset (pc_reg, 8);
4006             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4007             if (!success)
4008                 return false;
4009 
4010             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4011                 return false;
4012         }
4013 
4014         // if wback then R[n] = R[n] + 4*BitCount(registers);
4015         if (wback)
4016         {
4017             offset = addr_byte_size * BitCount (registers);
4018             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4019             context.SetImmediateSigned (offset);
4020             addr_t data = address + offset;
4021             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4022                 return false;
4023         }
4024     }
4025     return true;
4026 }
4027 
4028 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
4029 // from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
4030 // of those locations can optionally be written back to the base register.
4031 bool
4032 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding)
4033 {
4034 #if 0
4035     if ConditionPassed() then
4036         EncodingSpecificOperations();
4037         address = R[n] - 4*BitCount(registers) + 4;
4038 
4039         for i = 0 to 14
4040             if registers<i> == '1' then
4041                 if i == n && wback && i != LowestSetBit(registers) then
4042                     MemA[address,4] = bits(32) UNKNOWN;
4043                 else
4044                     MemA[address,4] = R[i];
4045                 address = address + 4;
4046 
4047         if registers<15> == '1' then
4048             MemA[address,4] = PCStoreValue();
4049 
4050         if wback then R[n] = R[n] - 4*BitCount(registers);
4051 #endif
4052 
4053     bool success = false;
4054 
4055     if (ConditionPassed(opcode))
4056     {
4057         uint32_t n;
4058         uint32_t registers = 0;
4059         bool wback;
4060         const uint32_t addr_byte_size = GetAddressByteSize();
4061 
4062         // EncodingSpecificOperations();
4063         switch (encoding)
4064         {
4065             case eEncodingA1:
4066                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4067                 n = Bits32 (opcode, 19, 16);
4068                 registers = Bits32 (opcode, 15, 0);
4069                 wback = BitIsSet (opcode, 21);
4070 
4071                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4072                 if ((n == 15) || (BitCount (registers) < 1))
4073                     return false;
4074                 break;
4075             default:
4076                 return false;
4077         }
4078 
4079         // address = R[n] - 4*BitCount(registers) + 4;
4080         int32_t offset = 0;
4081         addr_t Rn = ReadCoreReg (n, &success);
4082         if (!success)
4083             return false;
4084 
4085         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4;
4086 
4087         EmulateInstruction::Context context;
4088         context.type = EmulateInstruction::eContextRegisterStore;
4089         Register base_reg;
4090         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
4091 
4092         // for i = 0 to 14
4093         int lowest_bit_set = 14;
4094         for (int i = 0; i < 14; ++i)
4095         {
4096             // if registers<i> == '1' then
4097             if (BitIsSet (registers, i))
4098             {
4099                 if (i < lowest_bit_set)
4100                     lowest_bit_set = i;
4101                 //if i == n && wback && i != LowestSetBit(registers) then
4102                 if ((i == n) && wback && (i != lowest_bit_set))
4103                     // MemA[address,4] = bits(32) UNKNOWN;
4104                     WriteBits32UnknownToMemory (address + offset);
4105                 else
4106                 {
4107                     // MemA[address,4] = R[i];
4108                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4109                     if (!success)
4110                         return false;
4111 
4112                     Register data_reg;
4113                     data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
4114                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4115                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4116                         return false;
4117                 }
4118 
4119                 // address = address + 4;
4120                 offset += addr_byte_size;
4121             }
4122         }
4123 
4124         // if registers<15> == '1' then
4125         //    MemA[address,4] = PCStoreValue();
4126         if (BitIsSet (registers, 15))
4127         {
4128             Register pc_reg;
4129             pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
4130             context.SetRegisterPlusOffset (pc_reg, 8);
4131             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4132             if (!success)
4133                 return false;
4134 
4135             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4136                 return false;
4137         }
4138 
4139         // if wback then R[n] = R[n] - 4*BitCount(registers);
4140         if (wback)
4141         {
4142             offset = (addr_byte_size * BitCount (registers)) * -1;
4143             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4144             context.SetImmediateSigned (offset);
4145             addr_t data = Rn + offset;
4146             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4147                 return false;
4148         }
4149     }
4150     return true;
4151 }
4152 
4153 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
4154 // from a base register.  The consecutive memory locations end just below this address, and the address of the first of
4155 // those locations can optionally be written back to the base register.
4156 bool
4157 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding)
4158 {
4159 #if 0
4160     if ConditionPassed() then
4161         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4162         address = R[n] - 4*BitCount(registers);
4163 
4164         for i = 0 to 14
4165             if registers<i> == '1' then
4166                 if i == n && wback && i != LowestSetBit(registers) then
4167                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4168                 else
4169                     MemA[address,4] = R[i];
4170                 address = address + 4;
4171 
4172         if registers<15> == '1' then // Only possible for encoding A1
4173             MemA[address,4] = PCStoreValue();
4174 
4175         if wback then R[n] = R[n] - 4*BitCount(registers);
4176 #endif
4177 
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(); NullCheckIfThumbEE(n);
4189         switch (encoding)
4190         {
4191             case eEncodingT1:
4192                 // if W == '1' && Rn == '1101' then SEE PUSH;
4193                 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
4194                 {
4195                     // See PUSH
4196                 }
4197                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4198                 n = Bits32 (opcode, 19, 16);
4199                 registers = Bits32 (opcode, 15, 0);
4200                 registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
4201                 wback = BitIsSet (opcode, 21);
4202                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4203                 if ((n == 15) || BitCount (registers) < 2)
4204                     return false;
4205                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4206                 if (wback && BitIsSet (registers, n))
4207                     return false;
4208                 break;
4209 
4210             case eEncodingA1:
4211                 // if W == '1' && Rn == '1101’ && BitCount(register_list) >= 2 then SEE PUSH;
4212                 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
4213                 {
4214                     // See Push
4215                 }
4216                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4217                 n = Bits32 (opcode, 19, 16);
4218                 registers = Bits32 (opcode, 15, 0);
4219                 wback = BitIsSet (opcode, 21);
4220                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4221                 if ((n == 15) || BitCount (registers) < 1)
4222                     return false;
4223                 break;
4224 
4225             default:
4226                 return false;
4227         }
4228 
4229         // address = R[n] - 4*BitCount(registers);
4230 
4231         int32_t offset = 0;
4232         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4233         if (!success)
4234         return false;
4235 
4236         addr_t address = Rn - (addr_byte_size * BitCount (registers));
4237 
4238         EmulateInstruction::Context context;
4239         context.type = EmulateInstruction::eContextRegisterStore;
4240         Register base_reg;
4241         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
4242 
4243         // for i = 0 to 14
4244         uint32_t lowest_set_bit = 14;
4245         for (int i = 0; i < 14; ++i)
4246         {
4247             // if registers<i> == '1' then
4248             if (BitIsSet (registers, i))
4249             {
4250                 if (i < lowest_set_bit)
4251                     lowest_set_bit = i;
4252                 // if i == n && wback && i != LowestSetBit(registers) then
4253                 if ((i == n) && wback && (i != lowest_set_bit))
4254                     // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4255                     WriteBits32UnknownToMemory (address + offset);
4256                 else
4257                 {
4258                     // MemA[address,4] = R[i];
4259                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4260                     if (!success)
4261                         return false;
4262 
4263                     Register data_reg;
4264                     data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
4265                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4266                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4267                         return false;
4268                 }
4269 
4270                 // address = address + 4;
4271                 offset += addr_byte_size;
4272             }
4273         }
4274 
4275         // if registers<15> == '1' then // Only possible for encoding A1
4276         //     MemA[address,4] = PCStoreValue();
4277         if (BitIsSet (registers, 15))
4278         {
4279             Register pc_reg;
4280             pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
4281             context.SetRegisterPlusOffset (pc_reg, 8);
4282             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4283             if (!success)
4284                 return false;
4285 
4286             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4287                 return false;
4288         }
4289 
4290         // if wback then R[n] = R[n] - 4*BitCount(registers);
4291         if (wback)
4292         {
4293             offset = (addr_byte_size * BitCount (registers)) * -1;
4294             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4295             context.SetImmediateSigned (offset);
4296             addr_t data = Rn + offset;
4297             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4298                 return false;
4299         }
4300     }
4301     return true;
4302 }
4303 
4304 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
4305 // from a base register.  The consecutive memory locations start just above this address, and the address of the last
4306 // of those locations can optionally be written back to the base register.
4307 bool
4308 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding)
4309 {
4310 #if 0
4311     if ConditionPassed() then
4312         EncodingSpecificOperations();
4313         address = R[n] + 4;
4314 
4315         for i = 0 to 14
4316             if registers<i> == '1' then
4317                 if i == n && wback && i != LowestSetBit(registers) then
4318                     MemA[address,4] = bits(32) UNKNOWN;
4319                 else
4320                     MemA[address,4] = R[i];
4321                 address = address + 4;
4322 
4323         if registers<15> == '1' then
4324             MemA[address,4] = PCStoreValue();
4325 
4326         if wback then R[n] = R[n] + 4*BitCount(registers);
4327 #endif
4328 
4329     bool success = false;
4330 
4331     if (ConditionPassed(opcode))
4332     {
4333         uint32_t n;
4334         uint32_t registers = 0;
4335         bool wback;
4336         const uint32_t addr_byte_size = GetAddressByteSize();
4337 
4338         // EncodingSpecificOperations();
4339         switch (encoding)
4340         {
4341             case eEncodingA1:
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 
4347                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4348                 if ((n == 15) && (BitCount (registers) < 1))
4349                     return false;
4350                 break;
4351             default:
4352                 return false;
4353         }
4354         // address = R[n] + 4;
4355 
4356         int32_t offset = 0;
4357         addr_t Rn = ReadCoreReg (n, &success);
4358         if (!success)
4359             return false;
4360 
4361         addr_t address = Rn + addr_byte_size;
4362 
4363         EmulateInstruction::Context context;
4364         context.type = EmulateInstruction::eContextRegisterStore;
4365         Register base_reg;
4366         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
4367 
4368         uint32_t lowest_set_bit = 14;
4369         // for i = 0 to 14
4370         for (int i = 0; i < 14; ++i)
4371         {
4372             // if registers<i> == '1' then
4373             if (BitIsSet (registers, i))
4374             {
4375                 if (i < lowest_set_bit)
4376                     lowest_set_bit = i;
4377                 // if i == n && wback && i != LowestSetBit(registers) then
4378                 if ((i == n) && wback && (i != lowest_set_bit))
4379                     // MemA[address,4] = bits(32) UNKNOWN;
4380                     WriteBits32UnknownToMemory (address + offset);
4381                 // else
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                     Register data_reg;
4390                     data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + i);
4391                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size);
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
4402             // MemA[address,4] = PCStoreValue();
4403         if (BitIsSet (registers, 15))
4404         {
4405             Register pc_reg;
4406             pc_reg.SetRegister (eRegisterKindDWARF, dwarf_pc);
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);
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 // STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word
4431 // from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
4432 bool
4433 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding)
4434 {
4435 #if 0
4436     if ConditionPassed() then
4437         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4438         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4439         address = if index then offset_addr else R[n];
4440         if UnalignedSupport() || address<1:0> == '00' then
4441             MemU[address,4] = R[t];
4442         else // Can only occur before ARMv7
4443             MemU[address,4] = bits(32) UNKNOWN;
4444         if wback then R[n] = offset_addr;
4445 #endif
4446 
4447     bool success = false;
4448 
4449     if (ConditionPassed(opcode))
4450     {
4451         const uint32_t addr_byte_size = GetAddressByteSize();
4452 
4453         uint32_t t;
4454         uint32_t n;
4455         uint32_t imm32;
4456         bool index;
4457         bool add;
4458         bool wback;
4459         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4460         switch (encoding)
4461         {
4462             case eEncodingT1:
4463                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
4464                 t = Bits32 (opcode, 2, 0);
4465                 n = Bits32 (opcode, 5, 3);
4466                 imm32 = Bits32 (opcode, 10, 6) << 2;
4467 
4468                 // index = TRUE; add = TRUE; wback = FALSE;
4469                 index = true;
4470                 add = false;
4471                 wback = false;
4472                 break;
4473 
4474             case eEncodingT2:
4475                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4476                 t = Bits32 (opcode, 10, 8);
4477                 n = 13;
4478                 imm32 = Bits32 (opcode, 7, 0) << 2;
4479 
4480                 // index = TRUE; add = TRUE; wback = FALSE;
4481                 index = true;
4482                 add = true;
4483                 wback = false;
4484                 break;
4485 
4486             case eEncodingT3:
4487                 // if Rn == '1111' then UNDEFINED;
4488                 if (Bits32 (opcode, 19, 16) == 15)
4489                     return false;
4490 
4491                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4492                 t = Bits32 (opcode, 15, 12);
4493                 n = Bits32 (opcode, 19, 16);
4494                 imm32 = Bits32 (opcode, 11, 0);
4495 
4496                 // index = TRUE; add = TRUE; wback = FALSE;
4497                 index = true;
4498                 add = true;
4499                 wback = false;
4500 
4501                 // if t == 15 then UNPREDICTABLE;
4502                 if (t == 15)
4503                     return false;
4504                 break;
4505 
4506             case eEncodingT4:
4507                 // if P == '1' && U == '1' && W == '0' then SEE STRT;
4508                 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH;
4509                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4510                 if ((Bits32 (opcode, 19, 16) == 15)
4511                       || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
4512                     return false;
4513 
4514                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4515                 t = Bits32 (opcode, 15, 12);
4516                 n = Bits32 (opcode, 19, 16);
4517                 imm32 = Bits32 (opcode, 7, 0);
4518 
4519                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4520                 index = BitIsSet (opcode, 10);
4521                 add = BitIsSet (opcode, 9);
4522                 wback = BitIsSet (opcode, 8);
4523 
4524                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
4525                 if ((t == 15) || (wback && (n == t)))
4526                     return false;
4527                 break;
4528 
4529             default:
4530                 return false;
4531         }
4532 
4533         addr_t offset_addr;
4534         addr_t address;
4535 
4536         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4537         uint32_t base_address = ReadCoreReg (n, &success);
4538         if (!success)
4539             return false;
4540 
4541         if (add)
4542             offset_addr = base_address + imm32;
4543         else
4544             offset_addr = base_address - imm32;
4545 
4546         // address = if index then offset_addr else R[n];
4547         if (index)
4548             address = offset_addr;
4549         else
4550             address = base_address;
4551 
4552         EmulateInstruction::Context context;
4553         context.type = eContextRegisterStore;
4554         Register base_reg;
4555         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 +  n);
4556 
4557         // if UnalignedSupport() || address<1:0> == '00' then
4558         if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
4559         {
4560             // MemU[address,4] = R[t];
4561             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4562             if (!success)
4563                 return false;
4564 
4565             Register data_reg;
4566             data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
4567             int32_t offset = address - base_address;
4568             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4569             if (!MemUWrite (context, address, data, addr_byte_size))
4570                 return false;
4571         }
4572         else
4573         {
4574             // MemU[address,4] = bits(32) UNKNOWN;
4575             WriteBits32UnknownToMemory (address);
4576         }
4577 
4578         // if wback then R[n] = offset_addr;
4579         if (wback)
4580         {
4581             context.type = eContextRegisterLoad;
4582             context.SetAddress (offset_addr);
4583             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4584                 return false;
4585         }
4586     }
4587     return true;
4588 }
4589 
4590 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a
4591 // word from a register to memory.   The offset register value can optionally be shifted.
4592 bool
4593 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding)
4594 {
4595 #if 0
4596     if ConditionPassed() then
4597         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4598         offset = Shift(R[m], shift_t, shift_n, APSR.C);
4599         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4600         address = if index then offset_addr else R[n];
4601         if t == 15 then // Only possible for encoding A1
4602             data = PCStoreValue();
4603         else
4604             data = R[t];
4605         if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4606             MemU[address,4] = data;
4607         else // Can only occur before ARMv7
4608             MemU[address,4] = bits(32) UNKNOWN;
4609         if wback then R[n] = offset_addr;
4610 #endif
4611 
4612     bool success = false;
4613 
4614     if (ConditionPassed(opcode))
4615     {
4616         const uint32_t addr_byte_size = GetAddressByteSize();
4617 
4618         uint32_t t;
4619         uint32_t n;
4620         uint32_t m;
4621         ARM_ShifterType shift_t;
4622         uint32_t shift_n;
4623         bool index;
4624         bool add;
4625         bool wback;
4626 
4627         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4628         switch (encoding)
4629         {
4630             case eEncodingT1:
4631                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4632                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4633                 t = Bits32 (opcode, 2, 0);
4634                 n = Bits32 (opcode, 5, 3);
4635                 m = Bits32 (opcode, 8, 6);
4636 
4637                 // index = TRUE; add = TRUE; wback = FALSE;
4638                 index = true;
4639                 add = true;
4640                 wback = false;
4641 
4642                 // (shift_t, shift_n) = (SRType_LSL, 0);
4643                 shift_t = SRType_LSL;
4644                 shift_n = 0;
4645                 break;
4646 
4647             case eEncodingT2:
4648                 // if Rn == '1111' then UNDEFINED;
4649                 if (Bits32 (opcode, 19, 16) == 15)
4650                     return false;
4651 
4652                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4653                 t = Bits32 (opcode, 15, 12);
4654                 n = Bits32 (opcode, 19, 16);
4655                 m = Bits32 (opcode, 3, 0);
4656 
4657                 // index = TRUE; add = TRUE; wback = FALSE;
4658                 index = true;
4659                 add = true;
4660                 wback = false;
4661 
4662                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4663                 shift_t = SRType_LSL;
4664                 shift_n = Bits32 (opcode, 5, 4);
4665 
4666                 // if t == 15 || BadReg(m) then UNPREDICTABLE;
4667                 if ((t == 15) || (BadReg (m)))
4668                     return false;
4669                 break;
4670 
4671             case eEncodingA1:
4672             {
4673                 // if P == '0' && W == '1' then SEE STRT;
4674                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4675                 t = Bits32 (opcode, 15, 12);
4676                 n = Bits32 (opcode, 19, 16);
4677                 m = Bits32 (opcode, 3, 0);
4678 
4679                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
4680                 index = BitIsSet (opcode, 24);
4681                 add = BitIsSet (opcode, 23);
4682                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
4683 
4684                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
4685                 uint32_t typ = Bits32 (opcode, 6, 5);
4686                 uint32_t imm5 = Bits32 (opcode, 11, 7);
4687                 shift_n = DecodeImmShift(typ, imm5, shift_t);
4688 
4689                 // if m == 15 then UNPREDICTABLE;
4690                 if (m == 15)
4691                     return false;
4692 
4693                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
4694                 if (wback && ((n == 15) || (n == t)))
4695                     return false;
4696 
4697                 break;
4698             }
4699             default:
4700                 return false;
4701         }
4702 
4703         addr_t offset_addr;
4704         addr_t address;
4705         int32_t offset = 0;
4706 
4707         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4708         if (!success)
4709             return false;
4710 
4711         uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
4712         if (!success)
4713             return false;
4714 
4715         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4716         offset = Shift (Rm_data, shift_t, shift_n, APSR_C);
4717 
4718         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4719         if (add)
4720             offset_addr = base_address + offset;
4721         else
4722             offset_addr = base_address - offset;
4723 
4724         // address = if index then offset_addr else R[n];
4725         if (index)
4726             address = offset_addr;
4727         else
4728             address = base_address;
4729 
4730         uint32_t data;
4731         // if t == 15 then // Only possible for encoding A1
4732         if (t == 15)
4733             // data = PCStoreValue();
4734             data = ReadCoreReg (PC_REG, &success);
4735         else
4736             // data = R[t];
4737             data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4738 
4739         if (!success)
4740             return false;
4741 
4742         EmulateInstruction::Context context;
4743         context.type = eContextRegisterStore;
4744 
4745         // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4746         if (UnalignedSupport ()
4747             || (BitIsClear (address, 1) && BitIsClear (address, 0))
4748             || CurrentInstrSet() == eModeARM)
4749         {
4750             // MemU[address,4] = data;
4751 
4752             Register base_reg;
4753             base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 +  n);
4754 
4755             Register data_reg;
4756             data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
4757 
4758             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4759             if (!MemUWrite (context, address, data, addr_byte_size))
4760                 return false;
4761 
4762         }
4763         else
4764             // MemU[address,4] = bits(32) UNKNOWN;
4765             WriteBits32UnknownToMemory (address);
4766 
4767         // if wback then R[n] = offset_addr;
4768         if (wback)
4769         {
4770             context.type = eContextRegisterLoad;
4771             context.SetAddress (offset_addr);
4772             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4773                 return false;
4774         }
4775 
4776     }
4777     return true;
4778 }
4779 
4780 bool
4781 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding)
4782 {
4783 #if 0
4784     if ConditionPassed() then
4785         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4786         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4787         address = if index then offset_addr else R[n];
4788         MemU[address,1] = R[t]<7:0>;
4789         if wback then R[n] = offset_addr;
4790 #endif
4791 
4792 
4793     bool success = false;
4794 
4795     if (ConditionPassed(opcode))
4796     {
4797         uint32_t t;
4798         uint32_t n;
4799         uint32_t imm32;
4800         bool index;
4801         bool add;
4802         bool wback;
4803         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4804         switch (encoding)
4805         {
4806             case eEncodingT1:
4807                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
4808                 t = Bits32 (opcode, 2, 0);
4809                 n = Bits32 (opcode, 5, 3);
4810                 imm32 = Bits32 (opcode, 10, 6);
4811 
4812                 // index = TRUE; add = TRUE; wback = FALSE;
4813                 index = true;
4814                 add = true;
4815                 wback = false;
4816                 break;
4817 
4818             case eEncodingT2:
4819                 // if Rn == '1111' then UNDEFINED;
4820                 if (Bits32 (opcode, 19, 16) == 15)
4821                     return false;
4822 
4823                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4824                 t = Bits32 (opcode, 15, 12);
4825                 n = Bits32 (opcode, 19, 16);
4826                 imm32 = Bits32 (opcode, 11, 0);
4827 
4828                 // index = TRUE; add = TRUE; wback = FALSE;
4829                 index = true;
4830                 add = true;
4831                 wback = false;
4832 
4833                 // if BadReg(t) then UNPREDICTABLE;
4834                 if (BadReg (t))
4835                     return false;
4836                 break;
4837 
4838             case eEncodingT3:
4839                 // if P == '1' && U == '1' && W == '0' then SEE STRBT;
4840                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4841                 if (Bits32 (opcode, 19, 16) == 15)
4842                     return false;
4843 
4844                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4845                 t = Bits32 (opcode, 15, 12);
4846                 n = Bits32 (opcode, 19, 16);
4847                 imm32 = Bits32 (opcode, 7, 0);
4848 
4849                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4850                 index = BitIsSet (opcode, 10);
4851                 add = BitIsSet (opcode, 9);
4852                 wback = BitIsSet (opcode, 8);
4853 
4854                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
4855                 if ((BadReg (t)) || (wback && (n == t)))
4856                     return false;
4857                 break;
4858 
4859             default:
4860                 return false;
4861         }
4862 
4863         addr_t offset_addr;
4864         addr_t address;
4865         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4866         if (!success)
4867             return false;
4868 
4869         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4870         if (add)
4871             offset_addr = base_address + imm32;
4872         else
4873             offset_addr = base_address - imm32;
4874 
4875         // address = if index then offset_addr else R[n];
4876         if (index)
4877             address = offset_addr;
4878         else
4879             address = base_address;
4880 
4881         // MemU[address,1] = R[t]<7:0>
4882         Register base_reg;
4883         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
4884 
4885         Register data_reg;
4886         data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
4887 
4888         EmulateInstruction::Context context;
4889         context.type = eContextRegisterStore;
4890         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4891 
4892         uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4893         if (!success)
4894             return false;
4895 
4896         data = Bits32 (data, 7, 0);
4897 
4898         if (!MemUWrite (context, address, data, 1))
4899             return false;
4900 
4901         // if wback then R[n] = offset_addr;
4902         if (wback)
4903         {
4904             context.type = eContextRegisterLoad;
4905             context.SetAddress (offset_addr);
4906             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4907                 return false;
4908         }
4909 
4910     }
4911 
4912     return true;
4913 }
4914 
4915 // STRH (register) calculates an address from a base register value and an offset register value, and stores a
4916 // halfword from a register to memory.  The offset register alue can be shifted left by 0, 1, 2, or 3 bits.
4917 bool
4918 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding)
4919 {
4920 #if 0
4921     if ConditionPassed() then
4922         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4923         offset = Shift(R[m], shift_t, shift_n, APSR.C);
4924         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4925         address = if index then offset_addr else R[n];
4926         if UnalignedSupport() || address<0> == '0' then
4927             MemU[address,2] = R[t]<15:0>;
4928         else // Can only occur before ARMv7
4929             MemU[address,2] = bits(16) UNKNOWN;
4930         if wback then R[n] = offset_addr;
4931 #endif
4932 
4933     bool success = false;
4934 
4935     if (ConditionPassed(opcode))
4936     {
4937         uint32_t t;
4938         uint32_t n;
4939         uint32_t m;
4940         bool index;
4941         bool add;
4942         bool wback;
4943         ARM_ShifterType shift_t;
4944         uint32_t shift_n;
4945 
4946         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4947         switch (encoding)
4948         {
4949             case eEncodingT1:
4950                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4951                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4952                 t = Bits32 (opcode, 2, 0);
4953                 n = Bits32 (opcode, 5, 3);
4954                 m = Bits32 (opcode, 8, 6);
4955 
4956                 // index = TRUE; add = TRUE; wback = FALSE;
4957                 index = true;
4958                 add = true;
4959                 wback = false;
4960 
4961                 // (shift_t, shift_n) = (SRType_LSL, 0);
4962                 shift_t = SRType_LSL;
4963                 shift_n = 0;
4964 
4965                 break;
4966 
4967             case eEncodingT2:
4968                 // if Rn == '1111' then UNDEFINED;
4969                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4970                 t = Bits32 (opcode, 15, 12);
4971                 n = Bits32 (opcode, 19, 16);
4972                 m = Bits32 (opcode, 3, 0);
4973                 if (n == 15)
4974                     return false;
4975 
4976                 // index = TRUE; add = TRUE; wback = FALSE;
4977                 index = true;
4978                 add = true;
4979                 wback = false;
4980 
4981                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4982                 shift_t = SRType_LSL;
4983                 shift_n = Bits32 (opcode, 5, 4);
4984 
4985                 // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
4986                 if (BadReg (t) || BadReg (m))
4987                     return false;
4988 
4989                 break;
4990 
4991             case eEncodingA1:
4992                 // if P == '0' && W == '1' then SEE STRHT;
4993                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4994                 t = Bits32 (opcode, 15, 12);
4995                 n = Bits32 (opcode, 19, 16);
4996                 m = Bits32 (opcode, 3, 0);
4997 
4998                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
4999                 index = BitIsSet (opcode, 24);
5000                 add = BitIsSet (opcode, 23);
5001                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5002 
5003                 // (shift_t, shift_n) = (SRType_LSL, 0);
5004                 shift_t = SRType_LSL;
5005                 shift_n = 0;
5006 
5007                 // if t == 15 || m == 15 then UNPREDICTABLE;
5008                 if ((t == 15) || (m == 15))
5009                     return false;
5010 
5011                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5012                 if (wback && ((n == 15) || (n == t)))
5013                     return false;
5014 
5015                 break;
5016 
5017             default:
5018                 return false;
5019         }
5020 
5021         uint32_t Rm = ReadCoreReg (m, &success);
5022         if (!success)
5023             return false;
5024 
5025         uint32_t Rn = ReadCoreReg (n, &success);
5026         if (!success)
5027             return false;
5028 
5029         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5030         uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C);
5031 
5032         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5033         addr_t offset_addr;
5034         if (add)
5035             offset_addr = Rn + offset;
5036         else
5037             offset_addr = Rn - offset;
5038 
5039         // address = if index then offset_addr else R[n];
5040         addr_t address;
5041         if (index)
5042             address = offset_addr;
5043         else
5044             address = Rn;
5045 
5046         EmulateInstruction::Context context;
5047         context.type = eContextRegisterStore;
5048         Register base_reg;
5049         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
5050         Register offset_reg;
5051         offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
5052 
5053         // if UnalignedSupport() || address<0> == '0' then
5054         if (UnalignedSupport() || BitIsClear (address, 0))
5055         {
5056             // MemU[address,2] = R[t]<15:0>;
5057             uint32_t Rt = ReadCoreReg (t, &success);
5058             if (!success)
5059                 return false;
5060 
5061             EmulateInstruction::Context context;
5062             context.type = eContextRegisterStore;
5063             Register base_reg;
5064             base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
5065             Register offset_reg;
5066             offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
5067             Register data_reg;
5068             data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
5069             context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
5070 
5071             if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2))
5072                 return false;
5073         }
5074         else // Can only occur before ARMv7
5075         {
5076             // MemU[address,2] = bits(16) UNKNOWN;
5077         }
5078 
5079         // if wback then R[n] = offset_addr;
5080         if (wback)
5081         {
5082             context.type = eContextAdjustBaseRegister;
5083             context.SetAddress (offset_addr);
5084             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5085                 return false;
5086         }
5087     }
5088 
5089     return true;
5090 }
5091 
5092 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value,
5093 // and writes the result to the destination register.  It can optionally update the condition flags
5094 // based on the result.
5095 bool
5096 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding)
5097 {
5098 #if 0
5099     // ARM pseudo code...
5100     if ConditionPassed() then
5101         EncodingSpecificOperations();
5102         (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5103         if d == 15 then         // Can only occur for ARM encoding
5104             ALUWritePC(result); // setflags is always FALSE here
5105         else
5106             R[d] = result;
5107             if setflags then
5108                 APSR.N = result<31>;
5109                 APSR.Z = IsZeroBit(result);
5110                 APSR.C = carry;
5111                 APSR.V = overflow;
5112 #endif
5113 
5114     bool success = false;
5115 
5116     if (ConditionPassed(opcode))
5117     {
5118         uint32_t Rd, Rn;
5119         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
5120         bool setflags;
5121         switch (encoding)
5122         {
5123         case eEncodingT1:
5124             Rd = Bits32(opcode, 11, 8);
5125             Rn = Bits32(opcode, 19, 16);
5126             setflags = BitIsSet(opcode, 20);
5127             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5128             if (BadReg(Rd) || BadReg(Rn))
5129                 return false;
5130             break;
5131         case eEncodingA1:
5132             Rd = Bits32(opcode, 15, 12);
5133             Rn = Bits32(opcode, 19, 16);
5134             setflags = BitIsSet(opcode, 20);
5135             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5136 
5137             if (Rd == 15 && setflags)
5138                 return EmulateSUBSPcLrEtc (opcode, encoding);
5139             break;
5140         default:
5141             return false;
5142         }
5143 
5144         // Read the first operand.
5145         int32_t val1 = ReadCoreReg(Rn, &success);
5146         if (!success)
5147             return false;
5148 
5149         AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5150 
5151         EmulateInstruction::Context context;
5152         context.type = EmulateInstruction::eContextImmediate;
5153         context.SetNoArgs ();
5154 
5155         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5156             return false;
5157     }
5158     return true;
5159 }
5160 
5161 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted
5162 // register value, and writes the result to the destination register.  It can optionally update the
5163 // condition flags based on the result.
5164 bool
5165 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding)
5166 {
5167 #if 0
5168     // ARM pseudo code...
5169     if ConditionPassed() then
5170         EncodingSpecificOperations();
5171         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5172         (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5173         if d == 15 then         // Can only occur for ARM encoding
5174             ALUWritePC(result); // setflags is always FALSE here
5175         else
5176             R[d] = result;
5177             if setflags then
5178                 APSR.N = result<31>;
5179                 APSR.Z = IsZeroBit(result);
5180                 APSR.C = carry;
5181                 APSR.V = overflow;
5182 #endif
5183 
5184     bool success = false;
5185 
5186     if (ConditionPassed(opcode))
5187     {
5188         uint32_t Rd, Rn, Rm;
5189         ARM_ShifterType shift_t;
5190         uint32_t shift_n; // the shift applied to the value read from Rm
5191         bool setflags;
5192         switch (encoding)
5193         {
5194         case eEncodingT1:
5195             Rd = Rn = Bits32(opcode, 2, 0);
5196             Rm = Bits32(opcode, 5, 3);
5197             setflags = !InITBlock();
5198             shift_t = SRType_LSL;
5199             shift_n = 0;
5200             break;
5201         case eEncodingT2:
5202             Rd = Bits32(opcode, 11, 8);
5203             Rn = Bits32(opcode, 19, 16);
5204             Rm = Bits32(opcode, 3, 0);
5205             setflags = BitIsSet(opcode, 20);
5206             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5207             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5208                 return false;
5209             break;
5210         case eEncodingA1:
5211             Rd = Bits32(opcode, 15, 12);
5212             Rn = Bits32(opcode, 19, 16);
5213             Rm = Bits32(opcode, 3, 0);
5214             setflags = BitIsSet(opcode, 20);
5215             shift_n = DecodeImmShiftARM(opcode, shift_t);
5216 
5217             if (Rd == 15 && setflags)
5218                 return EmulateSUBSPcLrEtc (opcode, encoding);
5219             break;
5220         default:
5221             return false;
5222         }
5223 
5224         // Read the first operand.
5225         int32_t val1 = ReadCoreReg(Rn, &success);
5226         if (!success)
5227             return false;
5228 
5229         // Read the second operand.
5230         int32_t val2 = ReadCoreReg(Rm, &success);
5231         if (!success)
5232             return false;
5233 
5234         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
5235         AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5236 
5237         EmulateInstruction::Context context;
5238         context.type = EmulateInstruction::eContextImmediate;
5239         context.SetNoArgs ();
5240 
5241         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5242             return false;
5243     }
5244     return true;
5245 }
5246 
5247 // This instruction adds an immediate value to the PC value to form a PC-relative address,
5248 // and writes the result to the destination register.
5249 bool
5250 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding)
5251 {
5252 #if 0
5253     // ARM pseudo code...
5254     if ConditionPassed() then
5255         EncodingSpecificOperations();
5256         result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5257         if d == 15 then         // Can only occur for ARM encodings
5258             ALUWritePC(result);
5259         else
5260             R[d] = result;
5261 #endif
5262 
5263     bool success = false;
5264 
5265     if (ConditionPassed(opcode))
5266     {
5267         uint32_t Rd;
5268         uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5269         bool add;
5270         switch (encoding)
5271         {
5272         case eEncodingT1:
5273             Rd = Bits32(opcode, 10, 8);
5274             imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5275             break;
5276         case eEncodingT2:
5277         case eEncodingT3:
5278             Rd = Bits32(opcode, 11, 8);
5279             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5280             add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5281             if (BadReg(Rd))
5282                 return false;
5283             break;
5284         case eEncodingA1:
5285         case eEncodingA2:
5286             Rd = Bits32(opcode, 15, 12);
5287             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5288             add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5289             break;
5290         default:
5291             return false;
5292         }
5293 
5294         // Read the PC value.
5295         uint32_t pc = ReadCoreReg(PC_REG, &success);
5296         if (!success)
5297             return false;
5298 
5299         uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5300 
5301         EmulateInstruction::Context context;
5302         context.type = EmulateInstruction::eContextImmediate;
5303         context.SetNoArgs ();
5304 
5305         if (!WriteCoreReg(context, result, Rd))
5306             return false;
5307     }
5308     return true;
5309 }
5310 
5311 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result
5312 // to the destination register.  It can optionally update the condition flags based on the result.
5313 bool
5314 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding)
5315 {
5316 #if 0
5317     // ARM pseudo code...
5318     if ConditionPassed() then
5319         EncodingSpecificOperations();
5320         result = R[n] AND imm32;
5321         if d == 15 then         // Can only occur for ARM encoding
5322             ALUWritePC(result); // setflags is always FALSE here
5323         else
5324             R[d] = result;
5325             if setflags then
5326                 APSR.N = result<31>;
5327                 APSR.Z = IsZeroBit(result);
5328                 APSR.C = carry;
5329                 // APSR.V unchanged
5330 #endif
5331 
5332     bool success = false;
5333 
5334     if (ConditionPassed(opcode))
5335     {
5336         uint32_t Rd, Rn;
5337         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
5338         bool setflags;
5339         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5340         switch (encoding)
5341         {
5342         case eEncodingT1:
5343             Rd = Bits32(opcode, 11, 8);
5344             Rn = Bits32(opcode, 19, 16);
5345             setflags = BitIsSet(opcode, 20);
5346             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5347             // if Rd == '1111' && S == '1' then SEE TST (immediate);
5348             if (Rd == 15 && setflags)
5349                 return EmulateTSTImm(opcode, eEncodingT1);
5350             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
5351                 return false;
5352             break;
5353         case eEncodingA1:
5354             Rd = Bits32(opcode, 15, 12);
5355             Rn = Bits32(opcode, 19, 16);
5356             setflags = BitIsSet(opcode, 20);
5357             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5358 
5359             if (Rd == 15 && setflags)
5360                 return EmulateSUBSPcLrEtc (opcode, encoding);
5361             break;
5362         default:
5363             return false;
5364         }
5365 
5366         // Read the first operand.
5367         uint32_t val1 = ReadCoreReg(Rn, &success);
5368         if (!success)
5369             return false;
5370 
5371         uint32_t result = val1 & imm32;
5372 
5373         EmulateInstruction::Context context;
5374         context.type = EmulateInstruction::eContextImmediate;
5375         context.SetNoArgs ();
5376 
5377         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5378             return false;
5379     }
5380     return true;
5381 }
5382 
5383 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value,
5384 // and writes the result to the destination register.  It can optionally update the condition flags
5385 // based on the result.
5386 bool
5387 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding)
5388 {
5389 #if 0
5390     // ARM pseudo code...
5391     if ConditionPassed() then
5392         EncodingSpecificOperations();
5393         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5394         result = R[n] AND shifted;
5395         if d == 15 then         // Can only occur for ARM encoding
5396             ALUWritePC(result); // setflags is always FALSE here
5397         else
5398             R[d] = result;
5399             if setflags then
5400                 APSR.N = result<31>;
5401                 APSR.Z = IsZeroBit(result);
5402                 APSR.C = carry;
5403                 // APSR.V unchanged
5404 #endif
5405 
5406     bool success = false;
5407 
5408     if (ConditionPassed(opcode))
5409     {
5410         uint32_t Rd, Rn, Rm;
5411         ARM_ShifterType shift_t;
5412         uint32_t shift_n; // the shift applied to the value read from Rm
5413         bool setflags;
5414         uint32_t carry;
5415         switch (encoding)
5416         {
5417         case eEncodingT1:
5418             Rd = Rn = Bits32(opcode, 2, 0);
5419             Rm = Bits32(opcode, 5, 3);
5420             setflags = !InITBlock();
5421             shift_t = SRType_LSL;
5422             shift_n = 0;
5423             break;
5424         case eEncodingT2:
5425             Rd = Bits32(opcode, 11, 8);
5426             Rn = Bits32(opcode, 19, 16);
5427             Rm = Bits32(opcode, 3, 0);
5428             setflags = BitIsSet(opcode, 20);
5429             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5430             // if Rd == '1111' && S == '1' then SEE TST (register);
5431             if (Rd == 15 && setflags)
5432                 return EmulateTSTReg(opcode, eEncodingT2);
5433             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
5434                 return false;
5435             break;
5436         case eEncodingA1:
5437             Rd = Bits32(opcode, 15, 12);
5438             Rn = Bits32(opcode, 19, 16);
5439             Rm = Bits32(opcode, 3, 0);
5440             setflags = BitIsSet(opcode, 20);
5441             shift_n = DecodeImmShiftARM(opcode, shift_t);
5442 
5443             if (Rd == 15 && setflags)
5444                 return EmulateSUBSPcLrEtc (opcode, encoding);
5445             break;
5446         default:
5447             return false;
5448         }
5449 
5450         // Read the first operand.
5451         uint32_t val1 = ReadCoreReg(Rn, &success);
5452         if (!success)
5453             return false;
5454 
5455         // Read the second operand.
5456         uint32_t val2 = ReadCoreReg(Rm, &success);
5457         if (!success)
5458             return false;
5459 
5460         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
5461         uint32_t result = val1 & shifted;
5462 
5463         EmulateInstruction::Context context;
5464         context.type = EmulateInstruction::eContextImmediate;
5465         context.SetNoArgs ();
5466 
5467         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5468             return false;
5469     }
5470     return true;
5471 }
5472 
5473 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an
5474 // immediate value, and writes the result to the destination register.  It can optionally update the
5475 // condition flags based on the result.
5476 bool
5477 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding)
5478 {
5479 #if 0
5480     // ARM pseudo code...
5481     if ConditionPassed() then
5482         EncodingSpecificOperations();
5483         result = R[n] AND NOT(imm32);
5484         if d == 15 then         // Can only occur for ARM encoding
5485             ALUWritePC(result); // setflags is always FALSE here
5486         else
5487             R[d] = result;
5488             if setflags then
5489                 APSR.N = result<31>;
5490                 APSR.Z = IsZeroBit(result);
5491                 APSR.C = carry;
5492                 // APSR.V unchanged
5493 #endif
5494 
5495     bool success = false;
5496 
5497     if (ConditionPassed(opcode))
5498     {
5499         uint32_t Rd, Rn;
5500         uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn
5501         bool setflags;
5502         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5503         switch (encoding)
5504         {
5505         case eEncodingT1:
5506             Rd = Bits32(opcode, 11, 8);
5507             Rn = Bits32(opcode, 19, 16);
5508             setflags = BitIsSet(opcode, 20);
5509             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5510             if (BadReg(Rd) || BadReg(Rn))
5511                 return false;
5512             break;
5513         case eEncodingA1:
5514             Rd = Bits32(opcode, 15, 12);
5515             Rn = Bits32(opcode, 19, 16);
5516             setflags = BitIsSet(opcode, 20);
5517             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5518 
5519             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5520             if (Rd == 15 && setflags)
5521                 return EmulateSUBSPcLrEtc (opcode, encoding);
5522             break;
5523         default:
5524             return false;
5525         }
5526 
5527         // Read the first operand.
5528         uint32_t val1 = ReadCoreReg(Rn, &success);
5529         if (!success)
5530             return false;
5531 
5532         uint32_t result = val1 & ~imm32;
5533 
5534         EmulateInstruction::Context context;
5535         context.type = EmulateInstruction::eContextImmediate;
5536         context.SetNoArgs ();
5537 
5538         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5539             return false;
5540     }
5541     return true;
5542 }
5543 
5544 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an
5545 // optionally-shifted register value, and writes the result to the destination register.
5546 // It can optionally update the condition flags based on the result.
5547 bool
5548 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding)
5549 {
5550 #if 0
5551     // ARM pseudo code...
5552     if ConditionPassed() then
5553         EncodingSpecificOperations();
5554         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5555         result = R[n] AND NOT(shifted);
5556         if d == 15 then         // Can only occur for ARM encoding
5557             ALUWritePC(result); // setflags is always FALSE here
5558         else
5559             R[d] = result;
5560             if setflags then
5561                 APSR.N = result<31>;
5562                 APSR.Z = IsZeroBit(result);
5563                 APSR.C = carry;
5564                 // APSR.V unchanged
5565 #endif
5566 
5567     bool success = false;
5568 
5569     if (ConditionPassed(opcode))
5570     {
5571         uint32_t Rd, Rn, Rm;
5572         ARM_ShifterType shift_t;
5573         uint32_t shift_n; // the shift applied to the value read from Rm
5574         bool setflags;
5575         uint32_t carry;
5576         switch (encoding)
5577         {
5578         case eEncodingT1:
5579             Rd = Rn = Bits32(opcode, 2, 0);
5580             Rm = Bits32(opcode, 5, 3);
5581             setflags = !InITBlock();
5582             shift_t = SRType_LSL;
5583             shift_n = 0;
5584             break;
5585         case eEncodingT2:
5586             Rd = Bits32(opcode, 11, 8);
5587             Rn = Bits32(opcode, 19, 16);
5588             Rm = Bits32(opcode, 3, 0);
5589             setflags = BitIsSet(opcode, 20);
5590             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5591             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5592                 return false;
5593             break;
5594         case eEncodingA1:
5595             Rd = Bits32(opcode, 15, 12);
5596             Rn = Bits32(opcode, 19, 16);
5597             Rm = Bits32(opcode, 3, 0);
5598             setflags = BitIsSet(opcode, 20);
5599             shift_n = DecodeImmShiftARM(opcode, shift_t);
5600 
5601             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5602             if (Rd == 15 && setflags)
5603                 return EmulateSUBSPcLrEtc (opcode, encoding);
5604             break;
5605         default:
5606             return false;
5607         }
5608 
5609         // Read the first operand.
5610         uint32_t val1 = ReadCoreReg(Rn, &success);
5611         if (!success)
5612             return false;
5613 
5614         // Read the second operand.
5615         uint32_t val2 = ReadCoreReg(Rm, &success);
5616         if (!success)
5617             return false;
5618 
5619         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
5620         uint32_t result = val1 & ~shifted;
5621 
5622         EmulateInstruction::Context context;
5623         context.type = EmulateInstruction::eContextImmediate;
5624         context.SetNoArgs ();
5625 
5626         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5627             return false;
5628     }
5629     return true;
5630 }
5631 
5632 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
5633 // from memory, and writes it to a register.  It can use offset, post-indexed, or pre-indexed addressing.
5634 bool
5635 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding)
5636 {
5637 #if 0
5638     if ConditionPassed() then
5639         EncodingSpecificOperations();
5640         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5641         address = if index then offset_addr else R[n];
5642         data = MemU[address,4];
5643         if wback then R[n] = offset_addr;
5644         if t == 15 then
5645             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5646         elsif UnalignedSupport() || address<1:0> = '00' then
5647             R[t] = data;
5648         else // Can only apply before ARMv7
5649             R[t] = ROR(data, 8*UInt(address<1:0>));
5650 #endif
5651 
5652     bool success = false;
5653 
5654     if (ConditionPassed(opcode))
5655     {
5656         const uint32_t addr_byte_size = GetAddressByteSize();
5657 
5658         uint32_t t;
5659         uint32_t n;
5660         uint32_t imm32;
5661         bool index;
5662         bool add;
5663         bool wback;
5664 
5665         switch (encoding)
5666         {
5667             case eEncodingA1:
5668                 // if Rn == '1111' then SEE LDR (literal);
5669                 // if P == '0' && W == '1' then SEE LDRT;
5670                 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP;
5671                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5672                 t = Bits32 (opcode, 15, 12);
5673                 n = Bits32 (opcode, 19, 16);
5674                 imm32 = Bits32 (opcode, 11, 0);
5675 
5676                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5677                 index = BitIsSet (opcode, 24);
5678                 add = BitIsSet (opcode, 23);
5679                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5680 
5681                 // if wback && n == t then UNPREDICTABLE;
5682                 if (wback && (n == t))
5683                     return false;
5684 
5685                 break;
5686 
5687             default:
5688                 return false;
5689         }
5690 
5691         addr_t address;
5692         addr_t offset_addr;
5693         addr_t base_address = ReadCoreReg (n, &success);
5694         if (!success)
5695             return false;
5696 
5697         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5698         if (add)
5699             offset_addr = base_address + imm32;
5700         else
5701             offset_addr = base_address - imm32;
5702 
5703         // address = if index then offset_addr else R[n];
5704         if (index)
5705             address = offset_addr;
5706         else
5707             address = base_address;
5708 
5709         // data = MemU[address,4];
5710 
5711         Register base_reg;
5712         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
5713 
5714         EmulateInstruction::Context context;
5715         context.type = eContextRegisterLoad;
5716         context.SetRegisterPlusOffset (base_reg, address - base_address);
5717 
5718         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5719         if (!success)
5720             return false;
5721 
5722         // if wback then R[n] = offset_addr;
5723         if (wback)
5724         {
5725             context.type = eContextAdjustBaseRegister;
5726             context.SetAddress (offset_addr);
5727             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5728                 return false;
5729         }
5730 
5731         // if t == 15 then
5732         if (t == 15)
5733         {
5734             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5735             if (BitIsClear (address, 1) && BitIsClear (address, 0))
5736             {
5737                 // LoadWritePC (data);
5738                 context.type = eContextRegisterLoad;
5739                 context.SetRegisterPlusOffset (base_reg, address - base_address);
5740                 LoadWritePC (context, data);
5741             }
5742             else
5743                   return false;
5744         }
5745         // elsif UnalignedSupport() || address<1:0> = '00' then
5746         else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5747         {
5748             // R[t] = data;
5749             context.type = eContextRegisterLoad;
5750             context.SetRegisterPlusOffset (base_reg, address - base_address);
5751             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5752                 return false;
5753         }
5754         // else // Can only apply before ARMv7
5755         else
5756         {
5757             // R[t] = ROR(data, 8*UInt(address<1:0>));
5758             data = ROR (data, Bits32 (address, 1, 0));
5759             context.type = eContextRegisterLoad;
5760             context.SetImmediate (data);
5761             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5762                 return false;
5763         }
5764 
5765     }
5766     return true;
5767 }
5768 
5769 // LDR (register) calculates an address from a base register value and an offset register value, loads a word
5770 // from memory, and writes it to a resgister.  The offset register value can optionally be shifted.
5771 bool
5772 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding)
5773 {
5774 #if 0
5775     if ConditionPassed() then
5776         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5777         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5778         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5779         address = if index then offset_addr else R[n];
5780         data = MemU[address,4];
5781         if wback then R[n] = offset_addr;
5782         if t == 15 then
5783             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5784         elsif UnalignedSupport() || address<1:0> = '00' then
5785             R[t] = data;
5786         else // Can only apply before ARMv7
5787             if CurrentInstrSet() == InstrSet_ARM then
5788                 R[t] = ROR(data, 8*UInt(address<1:0>));
5789             else
5790                 R[t] = bits(32) UNKNOWN;
5791 #endif
5792 
5793     bool success = false;
5794 
5795     if (ConditionPassed(opcode))
5796     {
5797         const uint32_t addr_byte_size = GetAddressByteSize();
5798 
5799         uint32_t t;
5800         uint32_t n;
5801         uint32_t m;
5802         bool index;
5803         bool add;
5804         bool wback;
5805         ARM_ShifterType shift_t;
5806         uint32_t shift_n;
5807 
5808         switch (encoding)
5809         {
5810             case eEncodingT1:
5811                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5812                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5813                 t = Bits32 (opcode, 2, 0);
5814                 n = Bits32 (opcode, 5, 3);
5815                 m = Bits32 (opcode, 8, 6);
5816 
5817                 // index = TRUE; add = TRUE; wback = FALSE;
5818                 index = true;
5819                 add = true;
5820                 wback = false;
5821 
5822                 // (shift_t, shift_n) = (SRType_LSL, 0);
5823                 shift_t = SRType_LSL;
5824                 shift_n = 0;
5825 
5826                 break;
5827 
5828             case eEncodingT2:
5829                 // if Rn == '1111' then SEE LDR (literal);
5830                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5831                 t = Bits32 (opcode, 15, 12);
5832                 n = Bits32 (opcode, 19, 16);
5833                 m = Bits32 (opcode, 3, 0);
5834 
5835                 // index = TRUE; add = TRUE; wback = FALSE;
5836                 index = true;
5837                 add = true;
5838                 wback = false;
5839 
5840                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5841                 shift_t = SRType_LSL;
5842                 shift_n = Bits32 (opcode, 5, 4);
5843 
5844                 // if BadReg(m) then UNPREDICTABLE;
5845                 if (BadReg (m))
5846                     return false;
5847 
5848                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
5849                 if ((t == 15) && InITBlock() && !LastInITBlock())
5850                     return false;
5851 
5852                 break;
5853 
5854             case eEncodingA1:
5855             {
5856                 // if P == '0' && W == '1' then SEE LDRT;
5857                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5858                 t = Bits32 (opcode, 15, 12);
5859                 n = Bits32 (opcode, 19, 16);
5860                 m = Bits32 (opcode, 3, 0);
5861 
5862                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5863                 index = BitIsSet (opcode, 24);
5864                 add = BitIsSet (opcode, 23);
5865                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5866 
5867                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
5868                 uint32_t type = Bits32 (opcode, 6, 5);
5869                 uint32_t imm5 = Bits32 (opcode, 11, 7);
5870                 shift_n = DecodeImmShift (type, imm5, shift_t);
5871 
5872                 // if m == 15 then UNPREDICTABLE;
5873                 if (m == 15)
5874                     return false;
5875 
5876                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5877                 if (wback && ((n == 15) || (n == t)))
5878                     return false;
5879             }
5880                 break;
5881 
5882 
5883             default:
5884                 return false;
5885         }
5886 
5887         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
5888         if (!success)
5889             return false;
5890 
5891         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5892         if (!success)
5893             return false;
5894 
5895         addr_t offset_addr;
5896         addr_t address;
5897 
5898         // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an application level alias for the CPSR".
5899         addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C));
5900 
5901         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5902         if (add)
5903             offset_addr = Rn + offset;
5904         else
5905             offset_addr = Rn - offset;
5906 
5907         // address = if index then offset_addr else R[n];
5908             if (index)
5909                 address = offset_addr;
5910             else
5911                 address = Rn;
5912 
5913         // data = MemU[address,4];
5914         Register base_reg;
5915         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
5916 
5917         EmulateInstruction::Context context;
5918         context.type = eContextRegisterLoad;
5919         context.SetRegisterPlusOffset (base_reg, address - Rn);
5920 
5921         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5922         if (!success)
5923             return false;
5924 
5925         // if wback then R[n] = offset_addr;
5926         if (wback)
5927         {
5928             context.type = eContextAdjustBaseRegister;
5929             context.SetAddress (offset_addr);
5930             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5931                 return false;
5932         }
5933 
5934         // if t == 15 then
5935         if (t == 15)
5936         {
5937             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5938             if (BitIsClear (address, 1) && BitIsClear (address, 0))
5939             {
5940                 context.type = eContextRegisterLoad;
5941                 context.SetRegisterPlusOffset (base_reg, address - Rn);
5942                 LoadWritePC (context, data);
5943             }
5944             else
5945                 return false;
5946         }
5947         // elsif UnalignedSupport() || address<1:0> = '00' then
5948         else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5949         {
5950             // R[t] = data;
5951             context.type = eContextRegisterLoad;
5952             context.SetRegisterPlusOffset (base_reg, address - Rn);
5953             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5954                 return false;
5955         }
5956         else // Can only apply before ARMv7
5957         {
5958             // if CurrentInstrSet() == InstrSet_ARM then
5959             if (CurrentInstrSet () == eModeARM)
5960             {
5961                 // R[t] = ROR(data, 8*UInt(address<1:0>));
5962                 data = ROR (data, Bits32 (address, 1, 0));
5963                 context.type = eContextRegisterLoad;
5964                 context.SetImmediate (data);
5965                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5966                     return false;
5967             }
5968             else
5969             {
5970                 // R[t] = bits(32) UNKNOWN;
5971                 WriteBits32Unknown (t);
5972             }
5973         }
5974     }
5975     return true;
5976 }
5977 
5978 // LDRB (immediate, Thumb)
5979 bool
5980 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding)
5981 {
5982 #if 0
5983     if ConditionPassed() then
5984         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5985         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5986         address = if index then offset_addr else R[n];
5987         R[t] = ZeroExtend(MemU[address,1], 32);
5988         if wback then R[n] = offset_addr;
5989 #endif
5990 
5991     bool success = false;
5992 
5993     if (ConditionPassed(opcode))
5994     {
5995         uint32_t t;
5996         uint32_t n;
5997         uint32_t imm32;
5998         bool index;
5999         bool add;
6000         bool wback;
6001 
6002         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6003         switch (encoding)
6004         {
6005             case eEncodingT1:
6006                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6007                 t = Bits32 (opcode, 2, 0);
6008                 n = Bits32 (opcode, 5, 3);
6009                 imm32 = Bits32 (opcode, 10, 6);
6010 
6011                 // index = TRUE; add = TRUE; wback = FALSE;
6012                 index = true;
6013                 add = true;
6014                 wback= false;
6015 
6016                 break;
6017 
6018             case eEncodingT2:
6019                 // if Rt == '1111' then SEE PLD;
6020                 // if Rn == '1111' then SEE LDRB (literal);
6021                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6022                 t = Bits32 (opcode, 15, 12);
6023                 n = Bits32 (opcode, 19, 16);
6024                 imm32 = Bits32 (opcode, 11, 0);
6025 
6026                 // index = TRUE; add = TRUE; wback = FALSE;
6027                 index = true;
6028                 add = true;
6029                 wback = false;
6030 
6031                 // if t == 13 then UNPREDICTABLE;
6032                 if (t == 13)
6033                     return false;
6034 
6035                 break;
6036 
6037             case eEncodingT3:
6038                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6039                 // if Rn == '1111' then SEE LDRB (literal);
6040                 // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6041                 // if P == '0' && W == '0' then UNDEFINED;
6042                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6043                     return false;
6044 
6045                   // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6046                 t = Bits32 (opcode, 15, 12);
6047                 n = Bits32 (opcode, 19, 16);
6048                 imm32 = Bits32 (opcode, 7, 0);
6049 
6050                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6051                 index = BitIsSet (opcode, 10);
6052                 add = BitIsSet (opcode, 9);
6053                 wback = BitIsSet (opcode, 8);
6054 
6055                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6056                 if (BadReg (t) || (wback && (n == t)))
6057                     return false;
6058 
6059                 break;
6060 
6061             default:
6062                 return false;
6063         }
6064 
6065         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6066         if (!success)
6067             return false;
6068 
6069         addr_t address;
6070         addr_t offset_addr;
6071 
6072         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6073         if (add)
6074             offset_addr = Rn + imm32;
6075         else
6076             offset_addr = Rn - imm32;
6077 
6078         // address = if index then offset_addr else R[n];
6079         if (index)
6080             address = offset_addr;
6081         else
6082             address = Rn;
6083 
6084         // R[t] = ZeroExtend(MemU[address,1], 32);
6085         Register base_reg;
6086         Register data_reg;
6087         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
6088         data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
6089 
6090         EmulateInstruction::Context context;
6091         context.type = eContextRegisterLoad;
6092         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
6093 
6094         uint64_t data = MemURead (context, address, 1, 0, &success);
6095         if (!success)
6096             return false;
6097 
6098         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6099             return false;
6100 
6101         // if wback then R[n] = offset_addr;
6102         if (wback)
6103         {
6104             context.type = eContextAdjustBaseRegister;
6105             context.SetAddress (offset_addr);
6106             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6107                 return false;
6108         }
6109     }
6110     return true;
6111 }
6112 
6113 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6114 // zero-extends it to form a 32-bit word and writes it to a register.
6115 bool
6116 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6117 {
6118 #if 0
6119     if ConditionPassed() then
6120         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6121         base = Align(PC,4);
6122         address = if add then (base + imm32) else (base - imm32);
6123         R[t] = ZeroExtend(MemU[address,1], 32);
6124 #endif
6125 
6126     bool success = false;
6127 
6128     if (ConditionPassed(opcode))
6129     {
6130         uint32_t t;
6131         uint32_t imm32;
6132         bool add;
6133         switch (encoding)
6134         {
6135             case eEncodingT1:
6136                 // if Rt == '1111' then SEE PLD;
6137                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6138                 t = Bits32 (opcode, 15, 12);
6139                 imm32 = Bits32 (opcode, 11, 0);
6140                 add = BitIsSet (opcode, 23);
6141 
6142                 // if t == 13 then UNPREDICTABLE;
6143                 if (t == 13)
6144                     return false;
6145 
6146                 break;
6147 
6148             case eEncodingA1:
6149                 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6150                 t = Bits32 (opcode, 15, 12);
6151                 imm32 = Bits32 (opcode, 11, 0);
6152                 add = BitIsSet (opcode, 23);
6153 
6154                 // if t == 15 then UNPREDICTABLE;
6155                 if (t == 15)
6156                     return false;
6157                 break;
6158 
6159             default:
6160                 return false;
6161         }
6162 
6163         // base = Align(PC,4);
6164         uint32_t pc_val = ReadCoreReg (PC_REG, &success);
6165         if (!success)
6166             return false;
6167 
6168         uint32_t base = AlignPC (pc_val);
6169 
6170         addr_t address;
6171         // address = if add then (base + imm32) else (base - imm32);
6172         if (add)
6173             address = base + imm32;
6174         else
6175             address = base - imm32;
6176 
6177         // R[t] = ZeroExtend(MemU[address,1], 32);
6178         EmulateInstruction::Context context;
6179         context.type = eContextRelativeBranchImmediate;
6180         context.SetImmediate (address - base);
6181 
6182         uint64_t data = MemURead (context, address, 1, 0, &success);
6183         if (!success)
6184             return false;
6185 
6186         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6187             return false;
6188     }
6189     return true;
6190 }
6191 
6192 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from
6193 // memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6194 // optionally be shifted.
6195 bool
6196 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding)
6197 {
6198 #if 0
6199     if ConditionPassed() then
6200         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6201         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6202         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6203         address = if index then offset_addr else R[n];
6204         R[t] = ZeroExtend(MemU[address,1],32);
6205         if wback then R[n] = offset_addr;
6206 #endif
6207 
6208     bool success = false;
6209 
6210     if (ConditionPassed(opcode))
6211     {
6212         uint32_t t;
6213         uint32_t n;
6214         uint32_t m;
6215         bool index;
6216         bool add;
6217         bool wback;
6218         ARM_ShifterType shift_t;
6219         uint32_t shift_n;
6220 
6221         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6222         switch (encoding)
6223         {
6224             case eEncodingT1:
6225                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6226                 t = Bits32 (opcode, 2, 0);
6227                 n = Bits32 (opcode, 5, 3);
6228                 m = Bits32 (opcode, 8, 6);
6229 
6230                 // index = TRUE; add = TRUE; wback = FALSE;
6231                 index = true;
6232                 add = true;
6233                 wback = false;
6234 
6235                 // (shift_t, shift_n) = (SRType_LSL, 0);
6236                 shift_t = SRType_LSL;
6237                 shift_n = 0;
6238                 break;
6239 
6240             case eEncodingT2:
6241                 // if Rt == '1111' then SEE PLD;
6242                 // if Rn == '1111' then SEE LDRB (literal);
6243                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6244                 t = Bits32 (opcode, 15, 12);
6245                 n = Bits32 (opcode, 19, 16);
6246                 m = Bits32 (opcode, 3, 0);
6247 
6248                 // index = TRUE; add = TRUE; wback = FALSE;
6249                 index = true;
6250                 add = true;
6251                 wback = false;
6252 
6253                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6254                 shift_t = SRType_LSL;
6255                 shift_n = Bits32 (opcode, 5, 4);
6256 
6257                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6258                 if ((t == 13) || BadReg (m))
6259                     return false;
6260                 break;
6261 
6262             case eEncodingA1:
6263             {
6264                 // if P == '0' && W == '1' then SEE LDRBT;
6265                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6266                 t = Bits32 (opcode, 15, 12);
6267                 n = Bits32 (opcode, 19, 16);
6268                 m = Bits32 (opcode, 3, 0);
6269 
6270                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6271                 index = BitIsSet (opcode, 24);
6272                 add = BitIsSet (opcode, 23);
6273                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6274 
6275                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6276                 uint32_t type = Bits32 (opcode, 6, 5);
6277                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6278                 shift_n = DecodeImmShift (type, imm5, shift_t);
6279 
6280                 // if t == 15 || m == 15 then UNPREDICTABLE;
6281                 if ((t == 15) || (m == 15))
6282                     return false;
6283 
6284                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6285                 if (wback && ((n == 15) || (n == t)))
6286                     return false;
6287             }
6288                 break;
6289 
6290             default:
6291                 return false;
6292         }
6293 
6294         addr_t offset_addr;
6295         addr_t address;
6296 
6297         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6298         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6299         if (!success)
6300             return false;
6301 
6302         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C);
6303 
6304         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6305         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6306         if (!success)
6307             return false;
6308 
6309         if (add)
6310             offset_addr = Rn + offset;
6311         else
6312             offset_addr = Rn - offset;
6313 
6314         // address = if index then offset_addr else R[n];
6315         if (index)
6316             address = offset_addr;
6317         else
6318             address = Rn;
6319 
6320         // R[t] = ZeroExtend(MemU[address,1],32);
6321         Register base_reg;
6322         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
6323 
6324         EmulateInstruction::Context context;
6325         context.type = eContextRegisterLoad;
6326         context.SetRegisterPlusOffset (base_reg, address - Rn);
6327 
6328         uint64_t data = MemURead (context, address, 1, 0, &success);
6329         if (!success)
6330             return false;
6331 
6332         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6333             return false;
6334 
6335         // if wback then R[n] = offset_addr;
6336         if (wback)
6337         {
6338             context.type = eContextAdjustBaseRegister;
6339             context.SetAddress (offset_addr);
6340             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6341                 return false;
6342         }
6343     }
6344     return true;
6345 }
6346 
6347 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a
6348 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register.  It can use offset,
6349 // post-indexed, or pre-indexed addressing.
6350 bool
6351 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding)
6352 {
6353 #if 0
6354     if ConditionPassed() then
6355         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6356         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6357         address = if index then offset_addr else R[n];
6358         data = MemU[address,2];
6359         if wback then R[n] = offset_addr;
6360         if UnalignedSupport() || address<0> = '0' then
6361             R[t] = ZeroExtend(data, 32);
6362         else // Can only apply before ARMv7
6363             R[t] = bits(32) UNKNOWN;
6364 #endif
6365 
6366 
6367     bool success = false;
6368 
6369     if (ConditionPassed(opcode))
6370     {
6371         uint32_t t;
6372         uint32_t n;
6373         uint32_t imm32;
6374         bool index;
6375         bool add;
6376         bool wback;
6377 
6378         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6379         switch (encoding)
6380         {
6381             case eEncodingT1:
6382                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
6383                 t = Bits32 (opcode, 2, 0);
6384                 n = Bits32 (opcode, 5, 3);
6385                 imm32 = Bits32 (opcode, 10, 6) << 1;
6386 
6387                 // index = TRUE; add = TRUE; wback = FALSE;
6388                 index = true;
6389                 add = true;
6390                 wback = false;
6391 
6392                 break;
6393 
6394             case eEncodingT2:
6395                 // if Rt == '1111' then SEE "Unallocated memory hints";
6396                 // if Rn == '1111' then SEE LDRH (literal);
6397                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6398                 t = Bits32 (opcode, 15, 12);
6399                 n = Bits32 (opcode, 19, 16);
6400                 imm32 = Bits32 (opcode, 11, 0);
6401 
6402                 // index = TRUE; add = TRUE; wback = FALSE;
6403                 index = true;
6404                 add = true;
6405                 wback = false;
6406 
6407                 // if t == 13 then UNPREDICTABLE;
6408                 if (t == 13)
6409                     return false;
6410                 break;
6411 
6412             case eEncodingT3:
6413                 // if Rn == '1111' then SEE LDRH (literal);
6414                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
6415                 // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
6416                 // if P == '0' && W == '0' then UNDEFINED;
6417                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6418                     return false;
6419 
6420                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6421                 t = Bits32 (opcode, 15, 12);
6422                 n = Bits32 (opcode, 19, 16);
6423                 imm32 = Bits32 (opcode, 7, 0);
6424 
6425                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6426                 index = BitIsSet (opcode, 10);
6427                 add = BitIsSet (opcode, 9);
6428                 wback = BitIsSet (opcode, 8);
6429 
6430                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6431                 if (BadReg (t) || (wback && (n == t)))
6432                     return false;
6433                 break;
6434 
6435             default:
6436                 return false;
6437         }
6438 
6439         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6440         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6441         if (!success)
6442             return false;
6443 
6444         addr_t offset_addr;
6445         addr_t address;
6446 
6447         if (add)
6448             offset_addr = Rn + imm32;
6449         else
6450             offset_addr = Rn - imm32;
6451 
6452         // address = if index then offset_addr else R[n];
6453         if (index)
6454             address = offset_addr;
6455         else
6456             address = Rn;
6457 
6458         // data = MemU[address,2];
6459         Register base_reg;
6460         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
6461 
6462         EmulateInstruction::Context context;
6463         context.type = eContextRegisterLoad;
6464         context.SetRegisterPlusOffset (base_reg, address - Rn);
6465 
6466         uint64_t data = MemURead (context, address, 2, 0, &success);
6467         if (!success)
6468             return false;
6469 
6470         // if wback then R[n] = offset_addr;
6471         if (wback)
6472         {
6473             context.type = eContextAdjustBaseRegister;
6474             context.SetAddress (offset_addr);
6475             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6476                 return false;
6477         }
6478 
6479         // if UnalignedSupport() || address<0> = '0' then
6480         if (UnalignedSupport () || BitIsClear (address, 0))
6481         {
6482             // R[t] = ZeroExtend(data, 32);
6483             context.type = eContextRegisterLoad;
6484             context.SetRegisterPlusOffset (base_reg, address - Rn);
6485             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6486                 return false;
6487         }
6488         else // Can only apply before ARMv7
6489         {
6490             // R[t] = bits(32) UNKNOWN;
6491             WriteBits32Unknown (t);
6492         }
6493     }
6494     return true;
6495 }
6496 
6497 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory,
6498 // zero-extends it to form a 32-bit word, and writes it to a register.
6499 bool
6500 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding)
6501 {
6502 #if 0
6503     if ConditionPassed() then
6504         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6505         base = Align(PC,4);
6506         address = if add then (base + imm32) else (base - imm32);
6507         data = MemU[address,2];
6508         if UnalignedSupport() || address<0> = '0' then
6509             R[t] = ZeroExtend(data, 32);
6510         else // Can only apply before ARMv7
6511             R[t] = bits(32) UNKNOWN;
6512 #endif
6513 
6514     bool success = false;
6515 
6516     if (ConditionPassed(opcode))
6517     {
6518         uint32_t t;
6519         uint32_t imm32;
6520         bool add;
6521 
6522         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6523         switch (encoding)
6524         {
6525             case eEncodingT1:
6526                 // if Rt == '1111' then SEE "Unallocated memory hints";
6527                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6528                 t = Bits32 (opcode, 15, 12);
6529                 imm32 = Bits32 (opcode, 11, 0);
6530                 add = BitIsSet (opcode, 23);
6531 
6532                 // if t == 13 then UNPREDICTABLE;
6533                 if (t == 13)
6534                     return false;
6535 
6536                 break;
6537 
6538             case eEncodingA1:
6539             {
6540                 uint32_t imm4H = Bits32 (opcode, 11, 8);
6541                 uint32_t imm4L = Bits32 (opcode, 3, 0);
6542 
6543                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6544                 t = Bits32 (opcode, 15, 12);
6545                 imm32 = (imm4H << 4) | imm4L;
6546                 add = BitIsSet (opcode, 23);
6547 
6548                 // if t == 15 then UNPREDICTABLE;
6549                 if (t == 15)
6550                     return false;
6551                 break;
6552             }
6553 
6554             default:
6555                 return false;
6556         }
6557 
6558         // base = Align(PC,4);
6559         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6560         if (!success)
6561             return false;
6562 
6563         addr_t base = AlignPC (pc_value);
6564         addr_t address;
6565 
6566         // address = if add then (base + imm32) else (base - imm32);
6567         if (add)
6568             address = base + imm32;
6569         else
6570             address = base - imm32;
6571 
6572         // data = MemU[address,2];
6573         Register base_reg;
6574         base_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
6575 
6576         EmulateInstruction::Context context;
6577         context.type = eContextRegisterLoad;
6578         context.SetRegisterPlusOffset (base_reg, address - base);
6579 
6580         uint64_t data = MemURead (context, address, 2, 0, &success);
6581         if (!success)
6582             return false;
6583 
6584 
6585         // if UnalignedSupport() || address<0> = '0' then
6586         if (UnalignedSupport () || BitIsClear (address, 0))
6587         {
6588             // R[t] = ZeroExtend(data, 32);
6589             context.type = eContextRegisterLoad;
6590             context.SetRegisterPlusOffset (base_reg, address - base);
6591             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6592                 return false;
6593 
6594         }
6595         else // Can only apply before ARMv7
6596         {
6597             // R[t] = bits(32) UNKNOWN;
6598             WriteBits32Unknown (t);
6599         }
6600     }
6601     return true;
6602 }
6603 
6604 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword
6605 // from memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6606 // be shifted left by 0, 1, 2, or 3 bits.
6607 bool
6608 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding)
6609 {
6610 #if 0
6611     if ConditionPassed() then
6612         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6613         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6614         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6615         address = if index then offset_addr else R[n];
6616         data = MemU[address,2];
6617         if wback then R[n] = offset_addr;
6618         if UnalignedSupport() || address<0> = '0' then
6619             R[t] = ZeroExtend(data, 32);
6620         else // Can only apply before ARMv7
6621             R[t] = bits(32) UNKNOWN;
6622 #endif
6623 
6624     bool success = false;
6625 
6626     if (ConditionPassed(opcode))
6627     {
6628         uint32_t t;
6629         uint32_t n;
6630         uint32_t m;
6631         bool index;
6632         bool add;
6633         bool wback;
6634         ARM_ShifterType shift_t;
6635         uint32_t shift_n;
6636 
6637         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6638         switch (encoding)
6639         {
6640             case eEncodingT1:
6641                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6642                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6643                 t = Bits32 (opcode, 2, 0);
6644                 n = Bits32 (opcode, 5, 3);
6645                 m = Bits32 (opcode, 8, 6);
6646 
6647                 // index = TRUE; add = TRUE; wback = FALSE;
6648                 index = true;
6649                 add = true;
6650                 wback = false;
6651 
6652                 // (shift_t, shift_n) = (SRType_LSL, 0);
6653                 shift_t = SRType_LSL;
6654                 shift_n = 0;
6655 
6656                 break;
6657 
6658             case eEncodingT2:
6659                 // if Rn == '1111' then SEE LDRH (literal);
6660                 // if Rt == '1111' then SEE "Unallocated memory hints";
6661                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6662                 t = Bits32 (opcode, 15, 12);
6663                 n = Bits32 (opcode, 19, 16);
6664                 m = Bits32 (opcode, 3, 0);
6665 
6666                 // index = TRUE; add = TRUE; wback = FALSE;
6667                 index = true;
6668                 add = true;
6669                 wback = false;
6670 
6671                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6672                 shift_t = SRType_LSL;
6673                 shift_n = Bits32 (opcode, 5, 4);
6674 
6675                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6676                 if ((t == 13) || BadReg (m))
6677                     return false;
6678                 break;
6679 
6680             case eEncodingA1:
6681                 // if P == '0' && W == '1' then SEE LDRHT;
6682                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6683                 t = Bits32 (opcode, 15, 12);
6684                 n = Bits32 (opcode, 19, 16);
6685                 m = Bits32 (opcode, 3, 0);
6686 
6687                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6688                 index = BitIsSet (opcode, 24);
6689                 add = BitIsSet (opcode, 23);
6690                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6691 
6692                 // (shift_t, shift_n) = (SRType_LSL, 0);
6693                 shift_t = SRType_LSL;
6694                 shift_n = 0;
6695 
6696                 // if t == 15 || m == 15 then UNPREDICTABLE;
6697                 if ((t == 15) || (m == 15))
6698                     return false;
6699 
6700                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6701                 if (wback && ((n == 15) || (n == t)))
6702                     return false;
6703 
6704                 break;
6705 
6706             default:
6707                 return false;
6708         }
6709 
6710         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6711 
6712         uint64_t Rm  = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6713         if (!success)
6714             return false;
6715 
6716         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C);
6717 
6718         addr_t offset_addr;
6719         addr_t address;
6720 
6721         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6722         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6723         if (!success)
6724             return false;
6725 
6726         if (add)
6727             offset_addr = Rn + offset;
6728         else
6729             offset_addr = Rn - offset;
6730 
6731         // address = if index then offset_addr else R[n];
6732         if (index)
6733             address = offset_addr;
6734         else
6735             address = Rn;
6736 
6737         // data = MemU[address,2];
6738         Register base_reg;
6739         Register offset_reg;
6740         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
6741         offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
6742 
6743         EmulateInstruction::Context context;
6744         context.type = eContextRegisterLoad;
6745         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6746         uint64_t data = MemURead (context, address, 2, 0, &success);
6747         if (!success)
6748             return false;
6749 
6750         // if wback then R[n] = offset_addr;
6751         if (wback)
6752         {
6753             context.type = eContextAdjustBaseRegister;
6754             context.SetAddress (offset_addr);
6755             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6756                 return false;
6757         }
6758 
6759         // if UnalignedSupport() || address<0> = '0' then
6760         if (UnalignedSupport() || BitIsClear (address, 0))
6761         {
6762             // R[t] = ZeroExtend(data, 32);
6763             context.type = eContextRegisterLoad;
6764             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6765             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6766                 return false;
6767         }
6768         else // Can only apply before ARMv7
6769         {
6770             // R[t] = bits(32) UNKNOWN;
6771             WriteBits32Unknown (t);
6772         }
6773     }
6774     return true;
6775 }
6776 
6777 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from
6778 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed,
6779 // or pre-indexed addressing.
6780 bool
6781 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6782 {
6783 #if 0
6784     if ConditionPassed() then
6785         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6786         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6787         address = if index then offset_addr else R[n];
6788         R[t] = SignExtend(MemU[address,1], 32);
6789         if wback then R[n] = offset_addr;
6790 #endif
6791 
6792     bool success = false;
6793 
6794     if (ConditionPassed(opcode))
6795     {
6796         uint32_t t;
6797         uint32_t n;
6798         uint32_t imm32;
6799         bool index;
6800         bool add;
6801         bool wback;
6802 
6803         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6804         switch (encoding)
6805         {
6806             case eEncodingT1:
6807                 // if Rt == '1111' then SEE PLI;
6808                 // if Rn == '1111' then SEE LDRSB (literal);
6809                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6810                 t = Bits32 (opcode, 15, 12);
6811                 n = Bits32 (opcode, 19, 16);
6812                 imm32 = Bits32 (opcode, 11, 0);
6813 
6814                 // index = TRUE; add = TRUE; wback = FALSE;
6815                 index = true;
6816                 add = true;
6817                 wback = false;
6818 
6819                 // if t == 13 then UNPREDICTABLE;
6820                 if (t == 13)
6821                     return false;
6822 
6823                 break;
6824 
6825             case eEncodingT2:
6826                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
6827                 // if Rn == '1111' then SEE LDRSB (literal);
6828                 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
6829                 // if P == '0' && W == '0' then UNDEFINED;
6830                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6831                     return false;
6832 
6833                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6834                 t = Bits32 (opcode, 15, 12);
6835                 n = Bits32 (opcode, 19, 16);
6836                 imm32 = Bits32 (opcode, 7, 0);
6837 
6838                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6839                 index = BitIsSet (opcode, 10);
6840                 add = BitIsSet (opcode, 9);
6841                 wback = BitIsSet (opcode, 8);
6842 
6843                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6844                   if (((t == 13) || ((t == 15)
6845                                      && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8))))
6846                       || (wback && (n == t)))
6847                     return false;
6848 
6849                 break;
6850 
6851             case eEncodingA1:
6852             {
6853                 // if Rn == '1111' then SEE LDRSB (literal);
6854                 // if P == '0' && W == '1' then SEE LDRSBT;
6855                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
6856                 t = Bits32 (opcode, 15, 12);
6857                 n = Bits32 (opcode, 19, 16);
6858 
6859                 uint32_t imm4H = Bits32 (opcode, 11, 8);
6860                 uint32_t imm4L = Bits32 (opcode, 3, 0);
6861                 imm32 = (imm4H << 4) | imm4L;
6862 
6863                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6864                 index = BitIsSet (opcode, 24);
6865                 add = BitIsSet (opcode, 23);
6866                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6867 
6868                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
6869                 if ((t == 15) || (wback && (n == t)))
6870                     return false;
6871 
6872                 break;
6873             }
6874 
6875             default:
6876                 return false;
6877         }
6878 
6879         uint64_t Rn = ReadCoreReg (n, &success);
6880         if (!success)
6881             return false;
6882 
6883         addr_t offset_addr;
6884         addr_t address;
6885 
6886         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6887         if (add)
6888             offset_addr = Rn + imm32;
6889         else
6890             offset_addr = Rn - imm32;
6891 
6892         // address = if index then offset_addr else R[n];
6893         if (index)
6894             address = offset_addr;
6895         else
6896             address = Rn;
6897 
6898         // R[t] = SignExtend(MemU[address,1], 32);
6899         Register base_reg;
6900         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
6901 
6902         EmulateInstruction::Context context;
6903         context.type = eContextRegisterLoad;
6904         context.SetRegisterPlusOffset (base_reg, address - Rn);
6905 
6906         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
6907         if (!success)
6908             return false;
6909 
6910         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
6911         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
6912             return false;
6913 
6914         // if wback then R[n] = offset_addr;
6915         if (wback)
6916         {
6917             context.type = eContextAdjustBaseRegister;
6918             context.SetAddress (offset_addr);
6919             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6920                 return false;
6921         }
6922     }
6923 
6924     return true;
6925 }
6926 
6927 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6928 // sign-extends it to form a 32-bit word, and writes tit to a register.
6929 bool
6930 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6931 {
6932 #if 0
6933     if ConditionPassed() then
6934         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6935         base = Align(PC,4);
6936         address = if add then (base + imm32) else (base - imm32);
6937         R[t] = SignExtend(MemU[address,1], 32);
6938 #endif
6939 
6940     bool success = false;
6941 
6942     if (ConditionPassed(opcode))
6943     {
6944         uint32_t t;
6945         uint32_t imm32;
6946         bool add;
6947 
6948         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6949         switch (encoding)
6950         {
6951             case eEncodingT1:
6952                 // if Rt == '1111' then SEE PLI;
6953                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6954                 t = Bits32 (opcode, 15, 12);
6955                 imm32 = Bits32 (opcode, 11, 0);
6956                 add = BitIsSet (opcode, 23);
6957 
6958                 // if t == 13 then UNPREDICTABLE;
6959                 if (t == 13)
6960                     return false;
6961 
6962                 break;
6963 
6964             case eEncodingA1:
6965             {
6966                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6967                 t = Bits32 (opcode, 15, 12);
6968                 uint32_t imm4H = Bits32 (opcode, 11, 8);
6969                 uint32_t imm4L = Bits32 (opcode, 3, 0);
6970                 imm32 = (imm4H << 4) | imm4L;
6971                 add = BitIsSet (opcode, 23);
6972 
6973                 // if t == 15 then UNPREDICTABLE;
6974                 if (t == 15)
6975                     return false;
6976 
6977                 break;
6978             }
6979 
6980             default:
6981                 return false;
6982         }
6983 
6984         // base = Align(PC,4);
6985         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6986         if (!success)
6987             return false;
6988         uint64_t base = AlignPC (pc_value);
6989 
6990         // address = if add then (base + imm32) else (base - imm32);
6991         addr_t address;
6992         if (add)
6993             address = base + imm32;
6994         else
6995             address = base - imm32;
6996 
6997         // R[t] = SignExtend(MemU[address,1], 32);
6998         Register base_reg;
6999         base_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
7000 
7001         EmulateInstruction::Context context;
7002         context.type = eContextRegisterLoad;
7003         context.SetRegisterPlusOffset (base_reg, address - base);
7004 
7005         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7006         if (!success)
7007             return false;
7008 
7009         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7010         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7011             return false;
7012     }
7013     return true;
7014 }
7015 
7016 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from
7017 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7018 // shifted left by 0, 1, 2, or 3 bits.
7019 bool
7020 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding)
7021 {
7022 #if 0
7023     if ConditionPassed() then
7024         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7025         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7026         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7027         address = if index then offset_addr else R[n];
7028         R[t] = SignExtend(MemU[address,1], 32);
7029         if wback then R[n] = offset_addr;
7030 #endif
7031 
7032     bool success = false;
7033 
7034     if (ConditionPassed(opcode))
7035     {
7036         uint32_t t;
7037         uint32_t n;
7038         uint32_t m;
7039         bool index;
7040         bool add;
7041         bool wback;
7042         ARM_ShifterType shift_t;
7043         uint32_t shift_n;
7044 
7045         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7046         switch (encoding)
7047         {
7048             case eEncodingT1:
7049                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7050                 t = Bits32 (opcode, 2, 0);
7051                 n = Bits32 (opcode, 5, 3);
7052                 m = Bits32 (opcode, 8, 6);
7053 
7054                 // index = TRUE; add = TRUE; wback = FALSE;
7055                 index = true;
7056                 add = true;
7057                 wback = false;
7058 
7059                 // (shift_t, shift_n) = (SRType_LSL, 0);
7060                 shift_t = SRType_LSL;
7061                 shift_n = 0;
7062 
7063                 break;
7064 
7065             case eEncodingT2:
7066                 // if Rt == '1111' then SEE PLI;
7067                 // if Rn == '1111' then SEE LDRSB (literal);
7068                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7069                 t = Bits32 (opcode, 15, 12);
7070                 n = Bits32 (opcode, 19, 16);
7071                 m = Bits32 (opcode, 3, 0);
7072 
7073                 // index = TRUE; add = TRUE; wback = FALSE;
7074                 index = true;
7075                 add = true;
7076                 wback = false;
7077 
7078                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7079                 shift_t = SRType_LSL;
7080                 shift_n = Bits32 (opcode, 5, 4);
7081 
7082                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7083                 if ((t == 13) || BadReg (m))
7084                     return false;
7085                 break;
7086 
7087             case eEncodingA1:
7088                 // if P == '0' && W == '1' then SEE LDRSBT;
7089                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7090                 t = Bits32 (opcode, 15, 12);
7091                 n = Bits32 (opcode, 19, 16);
7092                 m = Bits32 (opcode, 3, 0);
7093 
7094                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7095                 index = BitIsSet (opcode, 24);
7096                 add = BitIsSet (opcode, 23);
7097                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7098 
7099                 // (shift_t, shift_n) = (SRType_LSL, 0);
7100                 shift_t = SRType_LSL;
7101                 shift_n = 0;
7102 
7103                 // if t == 15 || m == 15 then UNPREDICTABLE;
7104                 if ((t == 15) || (m == 15))
7105                     return false;
7106 
7107                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7108                 if (wback && ((n == 15) || (n == t)))
7109                     return false;
7110                 break;
7111 
7112             default:
7113                 return false;
7114         }
7115 
7116         uint64_t Rm =  ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7117         if (!success)
7118             return false;
7119 
7120         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7121         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C);
7122 
7123         addr_t offset_addr;
7124         addr_t address;
7125 
7126         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7127         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7128         if (!success)
7129             return false;
7130 
7131         if (add)
7132             offset_addr = Rn + offset;
7133         else
7134             offset_addr = Rn - offset;
7135 
7136         // address = if index then offset_addr else R[n];
7137         if (index)
7138             address = offset_addr;
7139         else
7140             address = Rn;
7141 
7142         // R[t] = SignExtend(MemU[address,1], 32);
7143         Register base_reg;
7144         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
7145         Register offset_reg;
7146         offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
7147 
7148         EmulateInstruction::Context context;
7149         context.type = eContextRegisterLoad;
7150         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
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         // if wback then R[n] = offset_addr;
7161         if (wback)
7162         {
7163             context.type = eContextAdjustBaseRegister;
7164             context.SetAddress (offset_addr);
7165             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7166                 return false;
7167         }
7168     }
7169     return true;
7170 }
7171 
7172 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from
7173 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed, or
7174 // pre-indexed addressing.
7175 bool
7176 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding)
7177 {
7178 #if 0
7179     if ConditionPassed() then
7180         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7181         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7182         address = if index then offset_addr else R[n];
7183         data = MemU[address,2];
7184         if wback then R[n] = offset_addr;
7185         if UnalignedSupport() || address<0> = '0' then
7186             R[t] = SignExtend(data, 32);
7187         else // Can only apply before ARMv7
7188             R[t] = bits(32) UNKNOWN;
7189 #endif
7190 
7191     bool success = false;
7192 
7193     if (ConditionPassed(opcode))
7194     {
7195         uint32_t t;
7196         uint32_t n;
7197         uint32_t imm32;
7198         bool index;
7199         bool add;
7200         bool wback;
7201 
7202         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7203         switch (encoding)
7204         {
7205             case eEncodingT1:
7206                 // if Rn == '1111' then SEE LDRSH (literal);
7207                 // if Rt == '1111' then SEE "Unallocated memory hints";
7208                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7209                 t = Bits32 (opcode, 15, 12);
7210                 n = Bits32 (opcode, 19, 16);
7211                 imm32 = Bits32 (opcode, 11, 0);
7212 
7213                 // index = TRUE; add = TRUE; wback = FALSE;
7214                 index = true;
7215                 add = true;
7216                 wback = false;
7217 
7218                 // if t == 13 then UNPREDICTABLE;
7219                 if (t == 13)
7220                     return false;
7221 
7222                 break;
7223 
7224             case eEncodingT2:
7225                 // if Rn == '1111' then SEE LDRSH (literal);
7226                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
7227                 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7228                 // if P == '0' && W == '0' then UNDEFINED;
7229                   if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7230                   return false;
7231 
7232                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7233                 t = Bits32 (opcode, 15, 12);
7234                 n = Bits32 (opcode, 19, 16);
7235                 imm32 = Bits32 (opcode, 7, 0);
7236 
7237                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7238                 index = BitIsSet (opcode, 10);
7239                 add = BitIsSet (opcode, 9);
7240                 wback = BitIsSet (opcode, 8);
7241 
7242                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7243                 if (BadReg (t) || (wback && (n == t)))
7244                     return false;
7245 
7246                 break;
7247 
7248             case eEncodingA1:
7249             {
7250                 // if Rn == '1111' then SEE LDRSH (literal);
7251                 // if P == '0' && W == '1' then SEE LDRSHT;
7252                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7253                 t = Bits32 (opcode, 15, 12);
7254                 n = Bits32 (opcode, 19, 16);
7255                 uint32_t imm4H = Bits32 (opcode, 11,8);
7256                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7257                 imm32 = (imm4H << 4) | imm4L;
7258 
7259                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7260                 index = BitIsSet (opcode, 24);
7261                 add = BitIsSet (opcode, 23);
7262                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7263 
7264                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7265                 if ((t == 15) || (wback && (n == t)))
7266                     return false;
7267 
7268                 break;
7269             }
7270 
7271             default:
7272                 return false;
7273         }
7274 
7275         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7276         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7277         if (!success)
7278             return false;
7279 
7280         addr_t offset_addr;
7281         if (add)
7282             offset_addr = Rn + imm32;
7283         else
7284             offset_addr = Rn - imm32;
7285 
7286         // address = if index then offset_addr else R[n];
7287         addr_t address;
7288         if (index)
7289             address = offset_addr;
7290         else
7291             address = Rn;
7292 
7293         // data = MemU[address,2];
7294         Register base_reg;
7295         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
7296 
7297         EmulateInstruction::Context context;
7298         context.type = eContextRegisterLoad;
7299         context.SetRegisterPlusOffset (base_reg, address - Rn);
7300 
7301         uint64_t data = MemURead (context, address, 2, 0, &success);
7302         if (!success)
7303             return false;
7304 
7305         // if wback then R[n] = offset_addr;
7306         if (wback)
7307         {
7308             context.type = eContextAdjustBaseRegister;
7309             context.SetAddress (offset_addr);
7310             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7311                 return false;
7312         }
7313 
7314         // if UnalignedSupport() || address<0> = '0' then
7315         if (UnalignedSupport() || BitIsClear (address, 0))
7316         {
7317             // R[t] = SignExtend(data, 32);
7318             int64_t signed_data = llvm::SignExtend64<16>(data);
7319             context.type = eContextRegisterLoad;
7320             context.SetRegisterPlusOffset (base_reg, address - Rn);
7321             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7322                 return false;
7323         }
7324         else // Can only apply before ARMv7
7325         {
7326             // R[t] = bits(32) UNKNOWN;
7327             WriteBits32Unknown (t);
7328         }
7329     }
7330     return true;
7331 }
7332 
7333 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory,
7334 // sign-extends it to from a 32-bit word, and writes it to a register.
7335 bool
7336 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding)
7337 {
7338 #if 0
7339     if ConditionPassed() then
7340         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7341         base = Align(PC,4);
7342         address = if add then (base + imm32) else (base - imm32);
7343         data = MemU[address,2];
7344         if UnalignedSupport() || address<0> = '0' then
7345             R[t] = SignExtend(data, 32);
7346         else // Can only apply before ARMv7
7347             R[t] = bits(32) UNKNOWN;
7348 #endif
7349 
7350     bool success = false;
7351 
7352     if (ConditionPassed(opcode))
7353     {
7354         uint32_t t;
7355         uint32_t imm32;
7356         bool add;
7357 
7358         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7359         switch (encoding)
7360         {
7361             case eEncodingT1:
7362                 // if Rt == '1111' then SEE "Unallocated memory hints";
7363                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7364                 t = Bits32  (opcode, 15, 12);
7365                 imm32 = Bits32 (opcode, 11, 0);
7366                 add = BitIsSet (opcode, 23);
7367 
7368                 // if t == 13 then UNPREDICTABLE;
7369                 if (t == 13)
7370                     return false;
7371 
7372                 break;
7373 
7374             case eEncodingA1:
7375             {
7376                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7377                 t = Bits32 (opcode, 15, 12);
7378                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7379                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7380                 imm32 = (imm4H << 4) | imm4L;
7381                 add = BitIsSet (opcode, 23);
7382 
7383                 // if t == 15 then UNPREDICTABLE;
7384                 if (t == 15)
7385                     return false;
7386 
7387                 break;
7388             }
7389             default:
7390                 return false;
7391         }
7392 
7393         // base = Align(PC,4);
7394         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7395         if (!success)
7396             return false;
7397 
7398         uint64_t base = AlignPC (pc_value);
7399 
7400         addr_t address;
7401         // address = if add then (base + imm32) else (base - imm32);
7402         if (add)
7403             address = base + imm32;
7404         else
7405             address = base - imm32;
7406 
7407         // data = MemU[address,2];
7408         Register base_reg;
7409         base_reg.SetRegister (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
7410 
7411         EmulateInstruction::Context context;
7412         context.type = eContextRegisterLoad;
7413         context.SetRegisterPlusOffset (base_reg, imm32);
7414 
7415         uint64_t data = MemURead (context, address, 2, 0, &success);
7416         if (!success)
7417             return false;
7418 
7419         // if UnalignedSupport() || address<0> = '0' then
7420         if (UnalignedSupport() || BitIsClear (address, 0))
7421         {
7422             // R[t] = SignExtend(data, 32);
7423             int64_t signed_data = llvm::SignExtend64<16>(data);
7424             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7425                 return false;
7426         }
7427         else // Can only apply before ARMv7
7428         {
7429             // R[t] = bits(32) UNKNOWN;
7430             WriteBits32Unknown (t);
7431         }
7432     }
7433     return true;
7434 }
7435 
7436 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword
7437 // from memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7438 // shifted left by 0, 1, 2, or 3 bits.
7439 bool
7440 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding)
7441 {
7442 #if 0
7443     if ConditionPassed() then
7444         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7445         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7446         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7447         address = if index then offset_addr else R[n];
7448         data = MemU[address,2];
7449         if wback then R[n] = offset_addr;
7450         if UnalignedSupport() || address<0> = '0' then
7451             R[t] = SignExtend(data, 32);
7452         else // Can only apply before ARMv7
7453             R[t] = bits(32) UNKNOWN;
7454 #endif
7455 
7456     bool success = false;
7457 
7458     if (ConditionPassed(opcode))
7459     {
7460         uint32_t t;
7461         uint32_t n;
7462         uint32_t m;
7463         bool index;
7464         bool add;
7465         bool wback;
7466         ARM_ShifterType shift_t;
7467         uint32_t shift_n;
7468 
7469         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7470         switch (encoding)
7471         {
7472             case eEncodingT1:
7473                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
7474                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7475                 t = Bits32 (opcode, 2, 0);
7476                 n = Bits32 (opcode, 5, 3);
7477                 m = Bits32 (opcode, 8, 6);
7478 
7479                 // index = TRUE; add = TRUE; wback = FALSE;
7480                 index = true;
7481                 add = true;
7482                 wback = false;
7483 
7484                 // (shift_t, shift_n) = (SRType_LSL, 0);
7485                 shift_t = SRType_LSL;
7486                 shift_n = 0;
7487 
7488                 break;
7489 
7490             case eEncodingT2:
7491                 // if Rn == '1111' then SEE LDRSH (literal);
7492                 // if Rt == '1111' then SEE "Unallocated memory hints";
7493                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7494                 t = Bits32 (opcode, 15, 12);
7495                 n = Bits32 (opcode, 19, 16);
7496                 m = Bits32 (opcode, 3, 0);
7497 
7498                 // index = TRUE; add = TRUE; wback = FALSE;
7499                 index = true;
7500                 add = true;
7501                 wback = false;
7502 
7503                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7504                 shift_t = SRType_LSL;
7505                 shift_n = Bits32 (opcode, 5, 4);
7506 
7507                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7508                 if ((t == 13) || BadReg (m))
7509                     return false;
7510 
7511                 break;
7512 
7513             case eEncodingA1:
7514                 // if P == '0' && W == '1' then SEE LDRSHT;
7515                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7516                 t = Bits32 (opcode, 15, 12);
7517                 n = Bits32 (opcode, 19, 16);
7518                 m = Bits32 (opcode, 3, 0);
7519 
7520                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7521                 index = BitIsSet (opcode, 24);
7522                 add = BitIsSet (opcode, 23);
7523                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7524 
7525                 // (shift_t, shift_n) = (SRType_LSL, 0);
7526                 shift_t = SRType_LSL;
7527                 shift_n = 0;
7528 
7529                 // if t == 15 || m == 15 then UNPREDICTABLE;
7530                 if ((t == 15) || (m == 15))
7531                     return false;
7532 
7533                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7534                 if (wback && ((n == 15) || (n == t)))
7535                     return false;
7536 
7537                 break;
7538 
7539             default:
7540                 break;
7541         }
7542 
7543         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7544         if (!success)
7545             return false;
7546 
7547         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7548         if (!success)
7549             return false;
7550 
7551         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7552         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C);
7553 
7554         addr_t offset_addr;
7555         addr_t address;
7556 
7557         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7558         if (add)
7559             offset_addr = Rn + offset;
7560         else
7561             offset_addr = Rn - offset;
7562 
7563         // address = if index then offset_addr else R[n];
7564         if (index)
7565             address = offset_addr;
7566         else
7567             address = Rn;
7568 
7569         // data = MemU[address,2];
7570         Register base_reg;
7571         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
7572 
7573         Register offset_reg;
7574         offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
7575 
7576         EmulateInstruction::Context context;
7577         context.type = eContextRegisterLoad;
7578         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7579 
7580         uint64_t data = MemURead (context, address, 2, 0, &success);
7581         if (!success)
7582             return false;
7583 
7584         // if wback then R[n] = offset_addr;
7585         if (wback)
7586         {
7587             context.type = eContextAdjustBaseRegister;
7588             context.SetAddress (offset_addr);
7589             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7590                 return false;
7591         }
7592 
7593         // if UnalignedSupport() || address<0> = '0' then
7594         if (UnalignedSupport() || BitIsClear (address, 0))
7595         {
7596             // R[t] = SignExtend(data, 32);
7597             context.type = eContextRegisterLoad;
7598             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7599 
7600             int64_t signed_data = llvm::SignExtend64<16>(data);
7601             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7602                 return false;
7603         }
7604         else // Can only apply before ARMv7
7605         {
7606             // R[t] = bits(32) UNKNOWN;
7607             WriteBits32Unknown (t);
7608         }
7609     }
7610     return true;
7611 }
7612 
7613 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7614 // register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7615 bool
7616 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding)
7617 {
7618 #if 0
7619     if ConditionPassed() then
7620         EncodingSpecificOperations();
7621         rotated = ROR(R[m], rotation);
7622         R[d] = SignExtend(rotated<7:0>, 32);
7623 #endif
7624 
7625     bool success = false;
7626 
7627     if (ConditionPassed(opcode))
7628     {
7629         uint32_t d;
7630         uint32_t m;
7631         uint32_t rotation;
7632 
7633         // EncodingSpecificOperations();
7634         switch (encoding)
7635         {
7636             case eEncodingT1:
7637                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7638                 d = Bits32 (opcode, 2, 0);
7639                 m = Bits32 (opcode, 5, 3);
7640                 rotation = 0;
7641 
7642                 break;
7643 
7644             case eEncodingT2:
7645                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7646                 d = Bits32 (opcode, 11, 8);
7647                 m = Bits32 (opcode, 3, 0);
7648                 rotation = Bits32 (opcode, 5, 4) << 3;
7649 
7650                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7651                 if (BadReg (d) || BadReg (m))
7652                     return false;
7653 
7654                 break;
7655 
7656             case eEncodingA1:
7657                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7658                 d = Bits32 (opcode, 15, 12);
7659                 m = Bits32 (opcode, 3, 0);
7660                 rotation = Bits32 (opcode, 11, 10) << 3;
7661 
7662                 // if d == 15 || m == 15 then UNPREDICTABLE;
7663                 if ((d == 15) || (m == 15))
7664                     return false;
7665 
7666                 break;
7667 
7668             default:
7669                 return false;
7670         }
7671 
7672         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7673         if (!success)
7674             return false;
7675 
7676         // rotated = ROR(R[m], rotation);
7677         uint64_t rotated = ROR (Rm, rotation);
7678 
7679         // R[d] = SignExtend(rotated<7:0>, 32);
7680         int64_t data = llvm::SignExtend64<8>(rotated);
7681 
7682         Register source_reg;
7683         source_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
7684 
7685         EmulateInstruction::Context context;
7686         context.type = eContextRegisterLoad;
7687         context.SetRegister (source_reg);
7688 
7689         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7690             return false;
7691     }
7692     return true;
7693 }
7694 
7695 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7696 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7697 bool
7698 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding)
7699 {
7700 #if 0
7701     if ConditionPassed() then
7702         EncodingSpecificOperations();
7703         rotated = ROR(R[m], rotation);
7704         R[d] = SignExtend(rotated<15:0>, 32);
7705 #endif
7706 
7707     bool success = false;
7708 
7709     if (ConditionPassed(opcode))
7710     {
7711         uint32_t d;
7712         uint32_t m;
7713         uint32_t rotation;
7714 
7715         // EncodingSpecificOperations();
7716         switch (encoding)
7717         {
7718             case eEncodingT1:
7719                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7720                 d = Bits32 (opcode, 2, 0);
7721                 m = Bits32 (opcode, 5, 3);
7722                 rotation = 0;
7723 
7724                 break;
7725 
7726             case eEncodingT2:
7727                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7728                 d = Bits32 (opcode, 11, 8);
7729                 m = Bits32 (opcode, 3, 0);
7730                 rotation = Bits32 (opcode, 5, 4) << 3;
7731 
7732                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7733                 if (BadReg (d) || BadReg (m))
7734                     return false;
7735 
7736                 break;
7737 
7738             case eEncodingA1:
7739                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7740                 d = Bits32 (opcode, 15, 12);
7741                 m = Bits32 (opcode, 3, 0);
7742                 rotation = Bits32 (opcode, 11, 10) << 3;
7743 
7744                 // if d == 15 || m == 15 then UNPREDICTABLE;
7745                 if ((d == 15) || (m == 15))
7746                     return false;
7747 
7748                 break;
7749 
7750             default:
7751                 return false;
7752         }
7753 
7754         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7755         if (!success)
7756             return false;
7757 
7758         // rotated = ROR(R[m], rotation);
7759         uint64_t rotated = ROR (Rm, rotation);
7760 
7761         // R[d] = SignExtend(rotated<15:0>, 32);
7762         Register source_reg;
7763         source_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
7764 
7765         EmulateInstruction::Context context;
7766         context.type = eContextRegisterLoad;
7767         context.SetRegister (source_reg);
7768 
7769         int64_t data = llvm::SignExtend64<16> (rotated);
7770         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7771             return false;
7772     }
7773 
7774     return true;
7775 }
7776 
7777 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination
7778 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7779 bool
7780 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding)
7781 {
7782 #if 0
7783     if ConditionPassed() then
7784         EncodingSpecificOperations();
7785         rotated = ROR(R[m], rotation);
7786         R[d] = ZeroExtend(rotated<7:0>, 32);
7787 #endif
7788 
7789     bool success = false;
7790 
7791     if (ConditionPassed(opcode))
7792     {
7793         uint32_t d;
7794         uint32_t m;
7795         uint32_t rotation;
7796 
7797         // EncodingSpecificOperations();
7798         switch (encoding)
7799         {
7800             case eEncodingT1:
7801                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7802                 d = Bits32 (opcode, 2, 0);
7803                 m = Bits32 (opcode, 5, 3);
7804                 rotation = 0;
7805 
7806                 break;
7807 
7808             case eEncodingT2:
7809                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7810                 d = Bits32 (opcode, 11, 8);
7811                 m = Bits32 (opcode, 3, 0);
7812                   rotation = Bits32 (opcode, 5, 4) << 3;
7813 
7814                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7815                 if (BadReg (d) || BadReg (m))
7816                   return false;
7817 
7818                 break;
7819 
7820             case eEncodingA1:
7821                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7822                 d = Bits32 (opcode, 15, 12);
7823                 m = Bits32 (opcode, 3, 0);
7824                 rotation = Bits32 (opcode, 11, 10) << 3;
7825 
7826                 // if d == 15 || m == 15 then UNPREDICTABLE;
7827                 if ((d == 15) || (m == 15))
7828                     return false;
7829 
7830                 break;
7831 
7832             default:
7833                 return false;
7834         }
7835 
7836         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7837         if (!success)
7838             return false;
7839 
7840         // rotated = ROR(R[m], rotation);
7841         uint64_t rotated = ROR (Rm, rotation);
7842 
7843         // R[d] = ZeroExtend(rotated<7:0>, 32);
7844         Register source_reg;
7845         source_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
7846 
7847         EmulateInstruction::Context context;
7848         context.type = eContextRegisterLoad;
7849         context.SetRegister (source_reg);
7850 
7851         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0)))
7852             return false;
7853     }
7854     return true;
7855 }
7856 
7857 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination
7858 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7859 bool
7860 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding)
7861 {
7862 #if 0
7863     if ConditionPassed() then
7864         EncodingSpecificOperations();
7865         rotated = ROR(R[m], rotation);
7866         R[d] = ZeroExtend(rotated<15:0>, 32);
7867 #endif
7868 
7869     bool success = false;
7870 
7871     if (ConditionPassed(opcode))
7872     {
7873         uint32_t d;
7874         uint32_t m;
7875         uint32_t rotation;
7876 
7877         switch (encoding)
7878         {
7879             case eEncodingT1:
7880                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7881                 d = Bits32 (opcode, 2, 0);
7882                 m = Bits32 (opcode, 5, 3);
7883                 rotation = 0;
7884 
7885                 break;
7886 
7887             case eEncodingT2:
7888                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7889                 d = Bits32 (opcode, 11, 8);
7890                 m = Bits32 (opcode, 3, 0);
7891                 rotation = Bits32 (opcode, 5, 4) << 3;
7892 
7893                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7894                 if (BadReg (d) || BadReg (m))
7895                   return false;
7896 
7897                 break;
7898 
7899             case eEncodingA1:
7900                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7901                 d = Bits32 (opcode, 15, 12);
7902                 m = Bits32 (opcode, 3, 0);
7903                 rotation = Bits32 (opcode, 11, 10) << 3;
7904 
7905                 // if d == 15 || m == 15 then UNPREDICTABLE;
7906                 if ((d == 15) || (m == 15))
7907                     return false;
7908 
7909                 break;
7910 
7911             default:
7912                 return false;
7913         }
7914 
7915         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7916         if (!success)
7917             return false;
7918 
7919         // rotated = ROR(R[m], rotation);
7920         uint64_t rotated = ROR (Rm, rotation);
7921 
7922         // R[d] = ZeroExtend(rotated<15:0>, 32);
7923         Register source_reg;
7924         source_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
7925 
7926         EmulateInstruction::Context context;
7927         context.type = eContextRegisterLoad;
7928         context.SetRegister (source_reg);
7929 
7930         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0)))
7931             return false;
7932     }
7933     return true;
7934 }
7935 
7936 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following
7937 // word respectively.
7938 bool
7939 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding)
7940 {
7941 #if 0
7942     if ConditionPassed() then
7943         EncodingSpecificOperations();
7944         if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
7945             UNPREDICTABLE;
7946         else
7947             address = if increment then R[n] else R[n]-8;
7948             if wordhigher then address = address+4;
7949             CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
7950             BranchWritePC(MemA[address,4]);
7951             if wback then R[n] = if increment then R[n]+8 else R[n]-8;
7952 #endif
7953 
7954     bool success = false;
7955 
7956     if (ConditionPassed(opcode))
7957     {
7958         uint32_t n;
7959         bool wback;
7960         bool increment;
7961         bool wordhigher;
7962 
7963         // EncodingSpecificOperations();
7964         switch (encoding)
7965         {
7966             case eEncodingT1:
7967                 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE;
7968                 n = Bits32 (opcode, 19, 16);
7969                 wback = BitIsSet (opcode, 21);
7970                 increment = false;
7971                 wordhigher = false;
7972 
7973                 // if n == 15 then UNPREDICTABLE;
7974                 if (n == 15)
7975                     return false;
7976 
7977                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
7978                 if (InITBlock() && !LastInITBlock())
7979                     return false;
7980 
7981                 break;
7982 
7983             case eEncodingT2:
7984                 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
7985                 n = Bits32 (opcode, 19, 16);
7986                 wback = BitIsSet (opcode, 21);
7987                 increment = true;
7988                 wordhigher = false;
7989 
7990                 // if n == 15 then UNPREDICTABLE;
7991                 if (n == 15)
7992                     return false;
7993 
7994                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
7995                 if (InITBlock() && !LastInITBlock())
7996                     return false;
7997 
7998                 break;
7999 
8000             case eEncodingA1:
8001                 // n = UInt(Rn);
8002                 n = Bits32 (opcode, 19, 16);
8003 
8004                 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8005                 wback = BitIsSet (opcode, 21);
8006                 increment = BitIsSet (opcode, 23);
8007                 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23));
8008 
8009                 // if n == 15 then UNPREDICTABLE;
8010                 if (n == 15)
8011                     return false;
8012 
8013                 break;
8014 
8015             default:
8016                 return false;
8017         }
8018 
8019         // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8020         if (!CurrentModeIsPrivileged ())
8021             // UNPREDICTABLE;
8022             return false;
8023         else
8024         {
8025             uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8026             if (!success)
8027                 return false;
8028 
8029             addr_t address;
8030             // address = if increment then R[n] else R[n]-8;
8031             if (increment)
8032                 address = Rn;
8033             else
8034                 address = Rn - 8;
8035 
8036             // if wordhigher then address = address+4;
8037             if (wordhigher)
8038                 address = address + 4;
8039 
8040             // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8041             Register base_reg;
8042             base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
8043 
8044             EmulateInstruction::Context context;
8045             context.type = eContextReturnFromException;
8046             context.SetRegisterPlusOffset (base_reg, address - Rn);
8047 
8048             uint64_t data = MemARead (context, address + 4, 4, 0, &success);
8049             if (!success)
8050                 return false;
8051 
8052             CPSRWriteByInstr (data, 15, true);
8053 
8054             // BranchWritePC(MemA[address,4]);
8055             uint64_t data2 = MemARead (context, address, 4, 0, &success);
8056             if (!success)
8057                 return false;
8058 
8059             BranchWritePC (context, data2);
8060 
8061             // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8062             if (wback)
8063             {
8064                 context.type = eContextAdjustBaseRegister;
8065                 if (increment)
8066                 {
8067                     context.SetOffset (8);
8068                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8))
8069                         return false;
8070                 }
8071                 else
8072                 {
8073                     context.SetOffset (-8);
8074                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8))
8075                         return false;
8076                 }
8077             } // if wback
8078         }
8079     } // if ConditionPassed()
8080     return true;
8081 }
8082 
8083 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
8084 // and writes the result to the destination register.  It can optionally update the condition flags based on
8085 // the result.
8086 bool
8087 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding)
8088 {
8089 #if 0
8090     // ARM pseudo code...
8091     if ConditionPassed() then
8092         EncodingSpecificOperations();
8093         result = R[n] EOR imm32;
8094         if d == 15 then         // Can only occur for ARM encoding
8095             ALUWritePC(result); // setflags is always FALSE here
8096         else
8097             R[d] = result;
8098             if setflags then
8099                 APSR.N = result<31>;
8100                 APSR.Z = IsZeroBit(result);
8101                 APSR.C = carry;
8102                 // APSR.V unchanged
8103 #endif
8104 
8105     bool success = false;
8106 
8107     if (ConditionPassed(opcode))
8108     {
8109         uint32_t Rd, Rn;
8110         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8111         bool setflags;
8112         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8113         switch (encoding)
8114         {
8115         case eEncodingT1:
8116             Rd = Bits32(opcode, 11, 8);
8117             Rn = Bits32(opcode, 19, 16);
8118             setflags = BitIsSet(opcode, 20);
8119             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8120             // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8121             if (Rd == 15 && setflags)
8122                 return EmulateTEQImm (opcode, eEncodingT1);
8123             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8124                 return false;
8125             break;
8126         case eEncodingA1:
8127             Rd = Bits32(opcode, 15, 12);
8128             Rn = Bits32(opcode, 19, 16);
8129             setflags = BitIsSet(opcode, 20);
8130             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8131 
8132             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8133             if (Rd == 15 && setflags)
8134                 return EmulateSUBSPcLrEtc (opcode, encoding);
8135             break;
8136         default:
8137             return false;
8138         }
8139 
8140         // Read the first operand.
8141         uint32_t val1 = ReadCoreReg(Rn, &success);
8142         if (!success)
8143             return false;
8144 
8145         uint32_t result = val1 ^ imm32;
8146 
8147         EmulateInstruction::Context context;
8148         context.type = EmulateInstruction::eContextImmediate;
8149         context.SetNoArgs ();
8150 
8151         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8152             return false;
8153     }
8154     return true;
8155 }
8156 
8157 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an
8158 // optionally-shifted register value, and writes the result to the destination register.
8159 // It can optionally update the condition flags based on the result.
8160 bool
8161 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding)
8162 {
8163 #if 0
8164     // ARM pseudo code...
8165     if ConditionPassed() then
8166         EncodingSpecificOperations();
8167         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8168         result = R[n] EOR shifted;
8169         if d == 15 then         // Can only occur for ARM encoding
8170             ALUWritePC(result); // setflags is always FALSE here
8171         else
8172             R[d] = result;
8173             if setflags then
8174                 APSR.N = result<31>;
8175                 APSR.Z = IsZeroBit(result);
8176                 APSR.C = carry;
8177                 // APSR.V unchanged
8178 #endif
8179 
8180     bool success = false;
8181 
8182     if (ConditionPassed(opcode))
8183     {
8184         uint32_t Rd, Rn, Rm;
8185         ARM_ShifterType shift_t;
8186         uint32_t shift_n; // the shift applied to the value read from Rm
8187         bool setflags;
8188         uint32_t carry;
8189         switch (encoding)
8190         {
8191         case eEncodingT1:
8192             Rd = Rn = Bits32(opcode, 2, 0);
8193             Rm = Bits32(opcode, 5, 3);
8194             setflags = !InITBlock();
8195             shift_t = SRType_LSL;
8196             shift_n = 0;
8197             break;
8198         case eEncodingT2:
8199             Rd = Bits32(opcode, 11, 8);
8200             Rn = Bits32(opcode, 19, 16);
8201             Rm = Bits32(opcode, 3, 0);
8202             setflags = BitIsSet(opcode, 20);
8203             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8204             // if Rd == '1111' && S == '1' then SEE TEQ (register);
8205             if (Rd == 15 && setflags)
8206                 return EmulateTEQReg (opcode, eEncodingT1);
8207             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8208                 return false;
8209             break;
8210         case eEncodingA1:
8211             Rd = Bits32(opcode, 15, 12);
8212             Rn = Bits32(opcode, 19, 16);
8213             Rm = Bits32(opcode, 3, 0);
8214             setflags = BitIsSet(opcode, 20);
8215             shift_n = DecodeImmShiftARM(opcode, shift_t);
8216 
8217             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8218             if (Rd == 15 && setflags)
8219                 return EmulateSUBSPcLrEtc (opcode, encoding);
8220             break;
8221         default:
8222             return false;
8223         }
8224 
8225         // Read the first operand.
8226         uint32_t val1 = ReadCoreReg(Rn, &success);
8227         if (!success)
8228             return false;
8229 
8230         // Read the second operand.
8231         uint32_t val2 = ReadCoreReg(Rm, &success);
8232         if (!success)
8233             return false;
8234 
8235         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
8236         uint32_t result = val1 ^ shifted;
8237 
8238         EmulateInstruction::Context context;
8239         context.type = EmulateInstruction::eContextImmediate;
8240         context.SetNoArgs ();
8241 
8242         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8243             return false;
8244     }
8245     return true;
8246 }
8247 
8248 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and
8249 // writes the result to the destination register.  It can optionally update the condition flags based
8250 // on the result.
8251 bool
8252 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding)
8253 {
8254 #if 0
8255     // ARM pseudo code...
8256     if ConditionPassed() then
8257         EncodingSpecificOperations();
8258         result = R[n] OR imm32;
8259         if d == 15 then         // Can only occur for ARM encoding
8260             ALUWritePC(result); // setflags is always FALSE here
8261         else
8262             R[d] = result;
8263             if setflags then
8264                 APSR.N = result<31>;
8265                 APSR.Z = IsZeroBit(result);
8266                 APSR.C = carry;
8267                 // APSR.V unchanged
8268 #endif
8269 
8270     bool success = false;
8271 
8272     if (ConditionPassed(opcode))
8273     {
8274         uint32_t Rd, Rn;
8275         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8276         bool setflags;
8277         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8278         switch (encoding)
8279         {
8280         case eEncodingT1:
8281             Rd = Bits32(opcode, 11, 8);
8282             Rn = Bits32(opcode, 19, 16);
8283             setflags = BitIsSet(opcode, 20);
8284             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8285             // if Rn == '1111' then SEE MOV (immediate);
8286             if (Rn == 15)
8287                 return EmulateMOVRdImm (opcode, eEncodingT2);
8288             if (BadReg(Rd) || Rn == 13)
8289                 return false;
8290             break;
8291         case eEncodingA1:
8292             Rd = Bits32(opcode, 15, 12);
8293             Rn = Bits32(opcode, 19, 16);
8294             setflags = BitIsSet(opcode, 20);
8295             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8296 
8297             if (Rd == 15 && setflags)
8298                 return EmulateSUBSPcLrEtc (opcode, encoding);
8299             break;
8300         default:
8301             return false;
8302         }
8303 
8304         // Read the first operand.
8305         uint32_t val1 = ReadCoreReg(Rn, &success);
8306         if (!success)
8307             return false;
8308 
8309         uint32_t result = val1 | imm32;
8310 
8311         EmulateInstruction::Context context;
8312         context.type = EmulateInstruction::eContextImmediate;
8313         context.SetNoArgs ();
8314 
8315         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8316             return false;
8317     }
8318     return true;
8319 }
8320 
8321 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register
8322 // value, and writes the result to the destination register.  It can optionally update the condition flags based
8323 // on the result.
8324 bool
8325 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding)
8326 {
8327 #if 0
8328     // ARM pseudo code...
8329     if ConditionPassed() then
8330         EncodingSpecificOperations();
8331         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8332         result = R[n] OR shifted;
8333         if d == 15 then         // Can only occur for ARM encoding
8334             ALUWritePC(result); // setflags is always FALSE here
8335         else
8336             R[d] = result;
8337             if setflags then
8338                 APSR.N = result<31>;
8339                 APSR.Z = IsZeroBit(result);
8340                 APSR.C = carry;
8341                 // APSR.V unchanged
8342 #endif
8343 
8344     bool success = false;
8345 
8346     if (ConditionPassed(opcode))
8347     {
8348         uint32_t Rd, Rn, Rm;
8349         ARM_ShifterType shift_t;
8350         uint32_t shift_n; // the shift applied to the value read from Rm
8351         bool setflags;
8352         uint32_t carry;
8353         switch (encoding)
8354         {
8355         case eEncodingT1:
8356             Rd = Rn = Bits32(opcode, 2, 0);
8357             Rm = Bits32(opcode, 5, 3);
8358             setflags = !InITBlock();
8359             shift_t = SRType_LSL;
8360             shift_n = 0;
8361             break;
8362         case eEncodingT2:
8363             Rd = Bits32(opcode, 11, 8);
8364             Rn = Bits32(opcode, 19, 16);
8365             Rm = Bits32(opcode, 3, 0);
8366             setflags = BitIsSet(opcode, 20);
8367             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8368             // if Rn == '1111' then SEE MOV (register);
8369             if (Rn == 15)
8370                 return EmulateMOVRdRm (opcode, eEncodingT3);
8371             if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
8372                 return false;
8373             break;
8374         case eEncodingA1:
8375             Rd = Bits32(opcode, 15, 12);
8376             Rn = Bits32(opcode, 19, 16);
8377             Rm = Bits32(opcode, 3, 0);
8378             setflags = BitIsSet(opcode, 20);
8379             shift_n = DecodeImmShiftARM(opcode, shift_t);
8380 
8381             if (Rd == 15 && setflags)
8382                 return EmulateSUBSPcLrEtc (opcode, encoding);
8383             break;
8384         default:
8385             return false;
8386         }
8387 
8388         // Read the first operand.
8389         uint32_t val1 = ReadCoreReg(Rn, &success);
8390         if (!success)
8391             return false;
8392 
8393         // Read the second operand.
8394         uint32_t val2 = ReadCoreReg(Rm, &success);
8395         if (!success)
8396             return false;
8397 
8398         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
8399         uint32_t result = val1 | shifted;
8400 
8401         EmulateInstruction::Context context;
8402         context.type = EmulateInstruction::eContextImmediate;
8403         context.SetNoArgs ();
8404 
8405         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8406             return false;
8407     }
8408     return true;
8409 }
8410 
8411 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to
8412 // the destination register. It can optionally update the condition flags based on the result.
8413 bool
8414 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding)
8415 {
8416 #if 0
8417     // ARM pseudo code...
8418     if ConditionPassed() then
8419         EncodingSpecificOperations();
8420         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
8421         if d == 15 then         // Can only occur for ARM encoding
8422             ALUWritePC(result); // setflags is always FALSE here
8423         else
8424             R[d] = result;
8425             if setflags then
8426                 APSR.N = result<31>;
8427                 APSR.Z = IsZeroBit(result);
8428                 APSR.C = carry;
8429                 APSR.V = overflow;
8430 #endif
8431 
8432     bool success = false;
8433 
8434     uint32_t Rd; // the destination register
8435     uint32_t Rn; // the first operand
8436     bool setflags;
8437     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8438     switch (encoding) {
8439     case eEncodingT1:
8440         Rd = Bits32(opcode, 2, 0);
8441         Rn = Bits32(opcode, 5, 3);
8442         setflags = !InITBlock();
8443         imm32 = 0;
8444         break;
8445     case eEncodingT2:
8446         Rd = Bits32(opcode, 11, 8);
8447         Rn = Bits32(opcode, 19, 16);
8448         setflags = BitIsSet(opcode, 20);
8449         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8450         if (BadReg(Rd) || BadReg(Rn))
8451             return false;
8452         break;
8453     case eEncodingA1:
8454         Rd = Bits32(opcode, 15, 12);
8455         Rn = Bits32(opcode, 19, 16);
8456         setflags = BitIsSet(opcode, 20);
8457         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8458 
8459         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8460         if (Rd == 15 && setflags)
8461             return EmulateSUBSPcLrEtc (opcode, encoding);
8462         break;
8463     default:
8464         return false;
8465     }
8466     // Read the register value from the operand register Rn.
8467     uint32_t reg_val = ReadCoreReg(Rn, &success);
8468     if (!success)
8469         return false;
8470 
8471     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
8472 
8473     EmulateInstruction::Context context;
8474     context.type = EmulateInstruction::eContextImmediate;
8475     context.SetNoArgs ();
8476 
8477     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8478         return false;
8479 
8480     return true;
8481 }
8482 
8483 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the
8484 // result to the destination register. It can optionally update the condition flags based on the result.
8485 bool
8486 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding)
8487 {
8488 #if 0
8489     // ARM pseudo code...
8490     if ConditionPassed() then
8491         EncodingSpecificOperations();
8492         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8493         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
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 = overflow;
8503 #endif
8504 
8505     bool success = false;
8506 
8507     uint32_t Rd; // the destination register
8508     uint32_t Rn; // the first operand
8509     uint32_t Rm; // the second operand
8510     bool setflags;
8511     ARM_ShifterType shift_t;
8512     uint32_t shift_n; // the shift applied to the value read from Rm
8513     switch (encoding) {
8514     case eEncodingT1:
8515         Rd = Bits32(opcode, 11, 8);
8516         Rn = Bits32(opcode, 19, 16);
8517         Rm = Bits32(opcode, 3, 0);
8518         setflags = BitIsSet(opcode, 20);
8519         shift_n = DecodeImmShiftThumb(opcode, shift_t);
8520         // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
8521         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8522             return false;
8523         break;
8524     case eEncodingA1:
8525         Rd = Bits32(opcode, 15, 12);
8526         Rn = Bits32(opcode, 19, 16);
8527         Rm = Bits32(opcode, 3, 0);
8528         setflags = BitIsSet(opcode, 20);
8529         shift_n = DecodeImmShiftARM(opcode, shift_t);
8530 
8531         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8532         if (Rd == 15 && setflags)
8533             return EmulateSUBSPcLrEtc (opcode, encoding);
8534         break;
8535     default:
8536         return false;
8537     }
8538     // Read the register value from register Rn.
8539     uint32_t val1 = ReadCoreReg(Rn, &success);
8540     if (!success)
8541         return false;
8542 
8543     // Read the register value from register Rm.
8544     uint32_t val2 = ReadCoreReg(Rm, &success);
8545     if (!success)
8546         return false;
8547 
8548     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
8549     AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
8550 
8551     EmulateInstruction::Context context;
8552     context.type = EmulateInstruction::eContextImmediate;
8553     context.SetNoArgs();
8554     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8555         return false;
8556 
8557     return true;
8558 }
8559 
8560 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from
8561 // an immediate value, and writes the result to the destination register. It can optionally update the condition
8562 // flags based on the result.
8563 bool
8564 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding)
8565 {
8566 #if 0
8567     // ARM pseudo code...
8568     if ConditionPassed() then
8569         EncodingSpecificOperations();
8570         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
8571         if d == 15 then
8572             ALUWritePC(result); // setflags is always FALSE here
8573         else
8574             R[d] = result;
8575             if setflags then
8576                 APSR.N = result<31>;
8577                 APSR.Z = IsZeroBit(result);
8578                 APSR.C = carry;
8579                 APSR.V = overflow;
8580 #endif
8581 
8582     bool success = false;
8583 
8584     uint32_t Rd; // the destination register
8585     uint32_t Rn; // the first operand
8586     bool setflags;
8587     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8588     switch (encoding) {
8589     case eEncodingA1:
8590         Rd = Bits32(opcode, 15, 12);
8591         Rn = Bits32(opcode, 19, 16);
8592         setflags = BitIsSet(opcode, 20);
8593         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8594 
8595         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8596         if (Rd == 15 && setflags)
8597             return EmulateSUBSPcLrEtc  (opcode, encoding);
8598         break;
8599     default:
8600         return false;
8601     }
8602     // Read the register value from the operand register Rn.
8603     uint32_t reg_val = ReadCoreReg(Rn, &success);
8604     if (!success)
8605         return false;
8606 
8607     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
8608 
8609     EmulateInstruction::Context context;
8610     context.type = EmulateInstruction::eContextImmediate;
8611     context.SetNoArgs ();
8612 
8613     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8614         return false;
8615 
8616     return true;
8617 }
8618 
8619 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an
8620 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the
8621 // condition flags based on the result.
8622 bool
8623 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding)
8624 {
8625 #if 0
8626     // ARM pseudo code...
8627     if ConditionPassed() then
8628         EncodingSpecificOperations();
8629         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8630         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
8631         if d == 15 then
8632             ALUWritePC(result); // setflags is always FALSE here
8633         else
8634             R[d] = result;
8635             if setflags then
8636                 APSR.N = result<31>;
8637                 APSR.Z = IsZeroBit(result);
8638                 APSR.C = carry;
8639                 APSR.V = overflow;
8640 #endif
8641 
8642     bool success = false;
8643 
8644     uint32_t Rd; // the destination register
8645     uint32_t Rn; // the first operand
8646     uint32_t Rm; // the second operand
8647     bool setflags;
8648     ARM_ShifterType shift_t;
8649     uint32_t shift_n; // the shift applied to the value read from Rm
8650     switch (encoding) {
8651     case eEncodingA1:
8652         Rd = Bits32(opcode, 15, 12);
8653         Rn = Bits32(opcode, 19, 16);
8654         Rm = Bits32(opcode, 3, 0);
8655         setflags = BitIsSet(opcode, 20);
8656         shift_n = DecodeImmShiftARM(opcode, shift_t);
8657 
8658         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8659         if (Rd == 15 && setflags)
8660             return EmulateSUBSPcLrEtc (opcode, encoding);
8661         break;
8662     default:
8663         return false;
8664     }
8665     // Read the register value from register Rn.
8666     uint32_t val1 = ReadCoreReg(Rn, &success);
8667     if (!success)
8668         return false;
8669 
8670     // Read the register value from register Rm.
8671     uint32_t val2 = ReadCoreReg(Rm, &success);
8672     if (!success)
8673         return false;
8674 
8675     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
8676     AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
8677 
8678     EmulateInstruction::Context context;
8679     context.type = EmulateInstruction::eContextImmediate;
8680     context.SetNoArgs();
8681     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8682         return false;
8683 
8684     return true;
8685 }
8686 
8687 // Subtract with Carry (immediate) subtracts an immediate value and the value of
8688 // NOT (Carry flag) from a register value, and writes the result to the destination register.
8689 // It can optionally update the condition flags based on the result.
8690 bool
8691 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding)
8692 {
8693 #if 0
8694     // ARM pseudo code...
8695     if ConditionPassed() then
8696         EncodingSpecificOperations();
8697         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
8698         if d == 15 then         // Can only occur for ARM encoding
8699             ALUWritePC(result); // setflags is always FALSE here
8700         else
8701             R[d] = result;
8702             if setflags then
8703                 APSR.N = result<31>;
8704                 APSR.Z = IsZeroBit(result);
8705                 APSR.C = carry;
8706                 APSR.V = overflow;
8707 #endif
8708 
8709     bool success = false;
8710 
8711     uint32_t Rd; // the destination register
8712     uint32_t Rn; // the first operand
8713     bool setflags;
8714     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8715     switch (encoding) {
8716     case eEncodingT1:
8717         Rd = Bits32(opcode, 11, 8);
8718         Rn = Bits32(opcode, 19, 16);
8719         setflags = BitIsSet(opcode, 20);
8720         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8721         if (BadReg(Rd) || BadReg(Rn))
8722             return false;
8723         break;
8724     case eEncodingA1:
8725         Rd = Bits32(opcode, 15, 12);
8726         Rn = Bits32(opcode, 19, 16);
8727         setflags = BitIsSet(opcode, 20);
8728         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8729 
8730         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8731         if (Rd == 15 && setflags)
8732             return EmulateSUBSPcLrEtc (opcode, encoding);
8733         break;
8734     default:
8735         return false;
8736     }
8737     // Read the register value from the operand register Rn.
8738     uint32_t reg_val = ReadCoreReg(Rn, &success);
8739     if (!success)
8740         return false;
8741 
8742     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
8743 
8744     EmulateInstruction::Context context;
8745     context.type = EmulateInstruction::eContextImmediate;
8746     context.SetNoArgs ();
8747 
8748     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8749         return false;
8750 
8751     return true;
8752 }
8753 
8754 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of
8755 // NOT (Carry flag) from a register value, and writes the result to the destination register.
8756 // It can optionally update the condition flags based on the result.
8757 bool
8758 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding)
8759 {
8760 #if 0
8761     // ARM pseudo code...
8762     if ConditionPassed() then
8763         EncodingSpecificOperations();
8764         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8765         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
8766         if d == 15 then         // Can only occur for ARM encoding
8767             ALUWritePC(result); // setflags is always FALSE here
8768         else
8769             R[d] = result;
8770             if setflags then
8771                 APSR.N = result<31>;
8772                 APSR.Z = IsZeroBit(result);
8773                 APSR.C = carry;
8774                 APSR.V = overflow;
8775 #endif
8776 
8777     bool success = false;
8778 
8779     uint32_t Rd; // the destination register
8780     uint32_t Rn; // the first operand
8781     uint32_t Rm; // the second operand
8782     bool setflags;
8783     ARM_ShifterType shift_t;
8784     uint32_t shift_n; // the shift applied to the value read from Rm
8785     switch (encoding) {
8786     case eEncodingT1:
8787         Rd = Rn = Bits32(opcode, 2, 0);
8788         Rm = Bits32(opcode, 5, 3);
8789         setflags = !InITBlock();
8790         shift_t = SRType_LSL;
8791         shift_n = 0;
8792         break;
8793     case eEncodingT2:
8794         Rd = Bits32(opcode, 11, 8);
8795         Rn = Bits32(opcode, 19, 16);
8796         Rm = Bits32(opcode, 3, 0);
8797         setflags = BitIsSet(opcode, 20);
8798         shift_n = DecodeImmShiftThumb(opcode, shift_t);
8799         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8800             return false;
8801         break;
8802     case eEncodingA1:
8803         Rd = Bits32(opcode, 15, 12);
8804         Rn = Bits32(opcode, 19, 16);
8805         Rm = Bits32(opcode, 3, 0);
8806         setflags = BitIsSet(opcode, 20);
8807         shift_n = DecodeImmShiftARM(opcode, shift_t);
8808 
8809         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8810         if (Rd == 15 && setflags)
8811             return EmulateSUBSPcLrEtc (opcode, encoding);
8812         break;
8813     default:
8814         return false;
8815     }
8816     // Read the register value from register Rn.
8817     uint32_t val1 = ReadCoreReg(Rn, &success);
8818     if (!success)
8819         return false;
8820 
8821     // Read the register value from register Rm.
8822     uint32_t val2 = ReadCoreReg(Rm, &success);
8823     if (!success)
8824         return false;
8825 
8826     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C);
8827     AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
8828 
8829     EmulateInstruction::Context context;
8830     context.type = EmulateInstruction::eContextImmediate;
8831     context.SetNoArgs();
8832     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8833         return false;
8834 
8835     return true;
8836 }
8837 
8838 // This instruction subtracts an immediate value from a register value, and writes the result
8839 // to the destination register.  It can optionally update the condition flags based on the result.
8840 bool
8841 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding)
8842 {
8843 #if 0
8844     // ARM pseudo code...
8845     if ConditionPassed() then
8846         EncodingSpecificOperations();
8847         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
8848         R[d] = result;
8849         if setflags then
8850             APSR.N = result<31>;
8851             APSR.Z = IsZeroBit(result);
8852             APSR.C = carry;
8853             APSR.V = overflow;
8854 #endif
8855 
8856     bool success = false;
8857 
8858     uint32_t Rd; // the destination register
8859     uint32_t Rn; // the first operand
8860     bool setflags;
8861     uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
8862     switch (encoding) {
8863     case eEncodingT1:
8864         Rd = Bits32(opcode, 2, 0);
8865         Rn = Bits32(opcode, 5, 3);
8866         setflags = !InITBlock();
8867         imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
8868         break;
8869     case eEncodingT2:
8870         Rd = Rn = Bits32(opcode, 10, 8);
8871         setflags = !InITBlock();
8872         imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
8873         break;
8874     case eEncodingT3:
8875         Rd = Bits32(opcode, 11, 8);
8876         Rn = Bits32(opcode, 19, 16);
8877         setflags = BitIsSet(opcode, 20);
8878         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8879 
8880         // if Rd == '1111' && S == '1' then SEE CMP (immediate);
8881         if (Rd == 15 && setflags)
8882             return EmulateCMPImm (opcode, eEncodingT2);
8883 
8884         // if Rn == '1101' then SEE SUB (SP minus immediate);
8885         if (Rn == 13)
8886             return EmulateSUBSPImm (opcode, eEncodingT2);
8887 
8888         // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
8889         if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
8890             return false;
8891         break;
8892     case eEncodingT4:
8893         Rd = Bits32(opcode, 11, 8);
8894         Rn = Bits32(opcode, 19, 16);
8895         setflags = BitIsSet(opcode, 20);
8896         imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
8897 
8898         // if Rn == '1111' then SEE ADR;
8899         if (Rn == 15)
8900             return EmulateADR (opcode, eEncodingT2);
8901 
8902         // if Rn == '1101' then SEE SUB (SP minus immediate);
8903         if (Rn == 13)
8904             return EmulateSUBSPImm (opcode, eEncodingT3);
8905 
8906         if (BadReg(Rd))
8907             return false;
8908         break;
8909     default:
8910         return false;
8911     }
8912     // Read the register value from the operand register Rn.
8913     uint32_t reg_val = ReadCoreReg(Rn, &success);
8914     if (!success)
8915         return false;
8916 
8917     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
8918 
8919     EmulateInstruction::Context context;
8920     context.type = EmulateInstruction::eContextImmediate;
8921     context.SetNoArgs ();
8922 
8923     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8924         return false;
8925 
8926     return true;
8927 }
8928 
8929 // This instruction subtracts an immediate value from a register value, and writes the result
8930 // to the destination register.  It can optionally update the condition flags based on the result.
8931 bool
8932 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding)
8933 {
8934 #if 0
8935     // ARM pseudo code...
8936     if ConditionPassed() then
8937         EncodingSpecificOperations();
8938         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
8939         if d == 15 then
8940             ALUWritePC(result); // setflags is always FALSE here
8941         else
8942             R[d] = result;
8943             if setflags then
8944                 APSR.N = result<31>;
8945                 APSR.Z = IsZeroBit(result);
8946                 APSR.C = carry;
8947                 APSR.V = overflow;
8948 #endif
8949 
8950     bool success = false;
8951 
8952     uint32_t Rd; // the destination register
8953     uint32_t Rn; // the first operand
8954     bool setflags;
8955     uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
8956     switch (encoding) {
8957     case eEncodingA1:
8958         Rd = Bits32(opcode, 15, 12);
8959         Rn = Bits32(opcode, 19, 16);
8960         setflags = BitIsSet(opcode, 20);
8961         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8962 
8963         // if Rn == '1111' && S == '0' then SEE ADR;
8964         if (Rn == 15 && !setflags)
8965             return EmulateADR (opcode, eEncodingA2);
8966 
8967         // if Rn == '1101' then SEE SUB (SP minus immediate);
8968         if (Rn == 13)
8969             return EmulateSUBSPImm (opcode, eEncodingA1);
8970 
8971         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8972         if (Rd == 15 && setflags)
8973             return EmulateSUBSPcLrEtc (opcode, encoding);
8974         break;
8975     default:
8976         return false;
8977     }
8978     // Read the register value from the operand register Rn.
8979     uint32_t reg_val = ReadCoreReg(Rn, &success);
8980     if (!success)
8981         return false;
8982 
8983     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
8984 
8985     EmulateInstruction::Context context;
8986     context.type = EmulateInstruction::eContextImmediate;
8987     context.SetNoArgs ();
8988 
8989     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8990         return false;
8991 
8992     return true;
8993 }
8994 
8995 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an
8996 // immediate value.  It updates the condition flags based on the result, and discards the result.
8997 bool
8998 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding)
8999 {
9000 #if 0
9001     // ARM pseudo code...
9002     if ConditionPassed() then
9003         EncodingSpecificOperations();
9004         result = R[n] EOR imm32;
9005         APSR.N = result<31>;
9006         APSR.Z = IsZeroBit(result);
9007         APSR.C = carry;
9008         // APSR.V unchanged
9009 #endif
9010 
9011     bool success = false;
9012 
9013     if (ConditionPassed(opcode))
9014     {
9015         uint32_t Rn;
9016         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9017         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9018         switch (encoding)
9019         {
9020         case eEncodingT1:
9021             Rn = Bits32(opcode, 19, 16);
9022             imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9023             if (BadReg(Rn))
9024                 return false;
9025             break;
9026         case eEncodingA1:
9027             Rn = Bits32(opcode, 19, 16);
9028             imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9029             break;
9030         default:
9031             return false;
9032         }
9033 
9034         // Read the first operand.
9035         uint32_t val1 = ReadCoreReg(Rn, &success);
9036         if (!success)
9037             return false;
9038 
9039         uint32_t result = val1 ^ imm32;
9040 
9041         EmulateInstruction::Context context;
9042         context.type = EmulateInstruction::eContextImmediate;
9043         context.SetNoArgs ();
9044 
9045         if (!WriteFlags(context, result, carry))
9046             return false;
9047     }
9048     return true;
9049 }
9050 
9051 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an
9052 // optionally-shifted register value.  It updates the condition flags based on the result, and discards
9053 // the result.
9054 bool
9055 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding)
9056 {
9057 #if 0
9058     // ARM pseudo code...
9059     if ConditionPassed() then
9060         EncodingSpecificOperations();
9061         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9062         result = R[n] EOR shifted;
9063         APSR.N = result<31>;
9064         APSR.Z = IsZeroBit(result);
9065         APSR.C = carry;
9066         // APSR.V unchanged
9067 #endif
9068 
9069     bool success = false;
9070 
9071     if (ConditionPassed(opcode))
9072     {
9073         uint32_t Rn, Rm;
9074         ARM_ShifterType shift_t;
9075         uint32_t shift_n; // the shift applied to the value read from Rm
9076         uint32_t carry;
9077         switch (encoding)
9078         {
9079         case eEncodingT1:
9080             Rn = Bits32(opcode, 19, 16);
9081             Rm = Bits32(opcode, 3, 0);
9082             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9083             if (BadReg(Rn) || BadReg(Rm))
9084                 return false;
9085             break;
9086         case eEncodingA1:
9087             Rn = Bits32(opcode, 19, 16);
9088             Rm = Bits32(opcode, 3, 0);
9089             shift_n = DecodeImmShiftARM(opcode, shift_t);
9090             break;
9091         default:
9092             return false;
9093         }
9094 
9095         // Read the first operand.
9096         uint32_t val1 = ReadCoreReg(Rn, &success);
9097         if (!success)
9098             return false;
9099 
9100         // Read the second operand.
9101         uint32_t val2 = ReadCoreReg(Rm, &success);
9102         if (!success)
9103             return false;
9104 
9105         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
9106         uint32_t result = val1 ^ shifted;
9107 
9108         EmulateInstruction::Context context;
9109         context.type = EmulateInstruction::eContextImmediate;
9110         context.SetNoArgs ();
9111 
9112         if (!WriteFlags(context, result, carry))
9113             return false;
9114     }
9115     return true;
9116 }
9117 
9118 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value.
9119 // It updates the condition flags based on the result, and discards the result.
9120 bool
9121 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding)
9122 {
9123 #if 0
9124     // ARM pseudo code...
9125     if ConditionPassed() then
9126         EncodingSpecificOperations();
9127         result = R[n] AND imm32;
9128         APSR.N = result<31>;
9129         APSR.Z = IsZeroBit(result);
9130         APSR.C = carry;
9131         // APSR.V unchanged
9132 #endif
9133 
9134     bool success = false;
9135 
9136     if (ConditionPassed(opcode))
9137     {
9138         uint32_t Rn;
9139         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9140         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9141         switch (encoding)
9142         {
9143         case eEncodingT1:
9144             Rn = Bits32(opcode, 19, 16);
9145             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9146             if (BadReg(Rn))
9147                 return false;
9148             break;
9149         case eEncodingA1:
9150             Rn = Bits32(opcode, 19, 16);
9151             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9152             break;
9153         default:
9154             return false;
9155         }
9156 
9157         // Read the first operand.
9158         uint32_t val1 = ReadCoreReg(Rn, &success);
9159         if (!success)
9160             return false;
9161 
9162         uint32_t result = val1 & imm32;
9163 
9164         EmulateInstruction::Context context;
9165         context.type = EmulateInstruction::eContextImmediate;
9166         context.SetNoArgs ();
9167 
9168         if (!WriteFlags(context, result, carry))
9169             return false;
9170     }
9171     return true;
9172 }
9173 
9174 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value.
9175 // It updates the condition flags based on the result, and discards the result.
9176 bool
9177 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding)
9178 {
9179 #if 0
9180     // ARM pseudo code...
9181     if ConditionPassed() then
9182         EncodingSpecificOperations();
9183         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9184         result = R[n] AND shifted;
9185         APSR.N = result<31>;
9186         APSR.Z = IsZeroBit(result);
9187         APSR.C = carry;
9188         // APSR.V unchanged
9189 #endif
9190 
9191     bool success = false;
9192 
9193     if (ConditionPassed(opcode))
9194     {
9195         uint32_t Rn, Rm;
9196         ARM_ShifterType shift_t;
9197         uint32_t shift_n; // the shift applied to the value read from Rm
9198         uint32_t carry;
9199         switch (encoding)
9200         {
9201         case eEncodingT1:
9202             Rn = Bits32(opcode, 2, 0);
9203             Rm = Bits32(opcode, 5, 3);
9204             shift_t = SRType_LSL;
9205             shift_n = 0;
9206             break;
9207         case eEncodingT2:
9208             Rn = Bits32(opcode, 19, 16);
9209             Rm = Bits32(opcode, 3, 0);
9210             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9211             if (BadReg(Rn) || BadReg(Rm))
9212                 return false;
9213             break;
9214         case eEncodingA1:
9215             Rn = Bits32(opcode, 19, 16);
9216             Rm = Bits32(opcode, 3, 0);
9217             shift_n = DecodeImmShiftARM(opcode, shift_t);
9218             break;
9219         default:
9220             return false;
9221         }
9222 
9223         // Read the first operand.
9224         uint32_t val1 = ReadCoreReg(Rn, &success);
9225         if (!success)
9226             return false;
9227 
9228         // Read the second operand.
9229         uint32_t val2 = ReadCoreReg(Rm, &success);
9230         if (!success)
9231             return false;
9232 
9233         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry);
9234         uint32_t result = val1 & shifted;
9235 
9236         EmulateInstruction::Context context;
9237         context.type = EmulateInstruction::eContextImmediate;
9238         context.SetNoArgs ();
9239 
9240         if (!WriteFlags(context, result, carry))
9241             return false;
9242     }
9243     return true;
9244 }
9245 
9246 // A8.6.216 SUB (SP minus register)
9247 bool
9248 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding)
9249 {
9250 #if 0
9251     if ConditionPassed() then
9252         EncodingSpecificOperations();
9253         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9254         (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), ‘1’);
9255         if d == 15 then // Can only occur for ARM encoding
9256             ALUWritePC(result); // setflags is always FALSE here
9257         else
9258             R[d] = result;
9259             if setflags then
9260                 APSR.N = result<31>;
9261                 APSR.Z = IsZeroBit(result);
9262                 APSR.C = carry;
9263                 APSR.V = overflow;
9264 #endif
9265 
9266     bool success = false;
9267 
9268     if (ConditionPassed(opcode))
9269     {
9270         uint32_t d;
9271         uint32_t m;
9272         bool setflags;
9273         ARM_ShifterType shift_t;
9274         uint32_t shift_n;
9275 
9276         switch (encoding)
9277         {
9278             case eEncodingT1:
9279                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == ‘1’);
9280                 d = Bits32 (opcode, 11, 8);
9281                 m = Bits32 (opcode, 3, 0);
9282                 setflags = BitIsSet (opcode, 20);
9283 
9284                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9285                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9286 
9287                 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE;
9288                 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
9289                     return false;
9290 
9291                 // if d == 15 || BadReg(m) then UNPREDICTABLE;
9292                 if ((d == 15) || BadReg (m))
9293                     return false;
9294                 break;
9295 
9296             case eEncodingA1:
9297                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == ‘1’);
9298                 d = Bits32 (opcode, 15, 12);
9299                 m = Bits32 (opcode, 3, 0);
9300                 setflags = BitIsSet (opcode, 20);
9301 
9302                 // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions;
9303                 if (d == 15 && setflags)
9304                     EmulateSUBSPcLrEtc (opcode, encoding);
9305 
9306                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9307                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9308                 break;
9309 
9310             default:
9311                 return false;
9312         }
9313 
9314         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9315         uint32_t Rm = ReadCoreReg (m, &success);
9316         if (!success)
9317             return false;
9318 
9319         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C);
9320 
9321         // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), ‘1’);
9322         uint32_t sp_val = ReadCoreReg (SP_REG, &success);
9323         if (!success)
9324             return false;
9325 
9326         AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1);
9327 
9328         EmulateInstruction::Context context;
9329         context.type = eContextSubtraction;
9330         Register sp_reg;
9331         sp_reg.SetRegister (eRegisterKindDWARF, dwarf_sp);
9332         Register dwarf_reg;
9333         dwarf_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
9334         context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
9335 
9336         if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9337             return false;
9338     }
9339     return true;
9340 }
9341 
9342 
9343 // A8.6.7 ADD (register-shifted register)
9344 bool
9345 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding)
9346 {
9347 #if 0
9348     if ConditionPassed() then
9349         EncodingSpecificOperations();
9350         shift_n = UInt(R[s]<7:0>);
9351         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9352         (result, carry, overflow) = AddWithCarry(R[n], shifted, ‘0’);
9353         R[d] = result;
9354         if setflags then
9355             APSR.N = result<31>;
9356             APSR.Z = IsZeroBit(result);
9357             APSR.C = carry;
9358             APSR.V = overflow;
9359 #endif
9360 
9361     bool success = false;
9362 
9363     if (ConditionPassed(opcode))
9364     {
9365         uint32_t d;
9366         uint32_t n;
9367         uint32_t m;
9368         uint32_t s;
9369         bool setflags;
9370         ARM_ShifterType shift_t;
9371 
9372         switch (encoding)
9373         {
9374             case eEncodingA1:
9375                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
9376                 d = Bits32 (opcode, 15, 12);
9377                 n = Bits32 (opcode, 19, 16);
9378                 m = Bits32 (opcode, 3, 0);
9379                 s = Bits32 (opcode, 11, 8);
9380 
9381                 // setflags = (S == ‘1’); shift_t = DecodeRegShift(type);
9382                 setflags = BitIsSet (opcode, 20);
9383                 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5));
9384 
9385                 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
9386                 if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
9387                     return false;
9388                 break;
9389 
9390             default:
9391                 return false;
9392         }
9393 
9394         // shift_n = UInt(R[s]<7:0>);
9395         uint32_t Rs = ReadCoreReg (s, &success);
9396         if (!success)
9397             return false;
9398 
9399         uint32_t shift_n = Bits32 (Rs, 7, 0);
9400 
9401         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9402         uint32_t Rm = ReadCoreReg (m, &success);
9403         if (!success)
9404             return false;
9405 
9406         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C);
9407 
9408         // (result, carry, overflow) = AddWithCarry(R[n], shifted, ‘0’);
9409         uint32_t Rn = ReadCoreReg (n, &success);
9410         if (!success)
9411             return false;
9412 
9413         AddWithCarryResult res = AddWithCarry (Rn, shifted, 0);
9414 
9415         // R[d] = result;
9416         EmulateInstruction::Context context;
9417         context.type = eContextAddition;
9418         Register reg_n;
9419         reg_n.SetRegister (eRegisterKindDWARF, dwarf_r0 +n);
9420         Register reg_m;
9421         reg_m.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
9422 
9423         context.SetRegisterRegisterOperands (reg_n, reg_m);
9424 
9425         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result))
9426             return false;
9427 
9428         // if setflags then
9429             // APSR.N = result<31>;
9430             // APSR.Z = IsZeroBit(result);
9431             // APSR.C = carry;
9432             // APSR.V = overflow;
9433         if (setflags)
9434             return WriteFlags (context, res.result, res.carry_out, res.overflow);
9435     }
9436     return true;
9437 }
9438 
9439 // A8.6.213 SUB (register)
9440 bool
9441 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding)
9442 {
9443 #if 0
9444     if ConditionPassed() then
9445         EncodingSpecificOperations();
9446         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9447         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), ‘1’);
9448         if d == 15 then // Can only occur for ARM encoding
9449             ALUWritePC(result); // setflags is always FALSE here
9450         else
9451             R[d] = result;
9452             if setflags then
9453                 APSR.N = result<31>;
9454                 APSR.Z = IsZeroBit(result);
9455                 APSR.C = carry;
9456                 APSR.V = overflow;
9457 #endif
9458 
9459     bool success = false;
9460 
9461     if (ConditionPassed(opcode))
9462     {
9463         uint32_t d;
9464         uint32_t n;
9465         uint32_t m;
9466         bool setflags;
9467         ARM_ShifterType shift_t;
9468         uint32_t shift_n;
9469 
9470         switch (encoding)
9471         {
9472             case eEncodingT1:
9473                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
9474                 d = Bits32 (opcode, 2, 0);
9475                 n = Bits32 (opcode, 5, 3);
9476                 m = Bits32 (opcode, 8, 6);
9477                 setflags = !InITBlock();
9478 
9479                 // (shift_t, shift_n) = (SRType_LSL, 0);
9480                 shift_t = SRType_LSL;
9481                 shift_n = 0;
9482 
9483                 break;
9484 
9485             case eEncodingT2:
9486                 // if Rd == ‘1111’ && S == ‘1’ then SEE CMP (register);
9487                 // if Rn == ‘1101’ then SEE SUB (SP minus register);
9488                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == ‘1’);
9489                 d = Bits32 (opcode, 11, 8);
9490                 n = Bits32 (opcode, 19, 16);
9491                 m = Bits32 (opcode, 3, 0);
9492                 setflags = BitIsSet (opcode, 20);
9493 
9494                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9495                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9496 
9497                 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE;
9498                 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m))
9499                     return false;
9500 
9501                 break;
9502 
9503             case eEncodingA1:
9504                 // if Rn == ‘1101’ then SEE SUB (SP minus register);
9505                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == ‘1’);
9506                 d = Bits32 (opcode, 15, 12);
9507                 n = Bits32 (opcode, 19, 16);
9508                 m = Bits32 (opcode, 3, 0);
9509                 setflags = BitIsSet (opcode, 20);
9510 
9511                 // if Rd == ‘1111’ && S == ‘1’ then SEE SUBS PC, LR and related instructions;
9512                 if ((d == 15) && setflags)
9513                     EmulateSUBSPcLrEtc (opcode, encoding);
9514 
9515                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9516                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9517 
9518                 break;
9519 
9520             default:
9521                 return false;
9522         }
9523 
9524         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9525         uint32_t Rm = ReadCoreReg (m, &success);
9526         if (!success)
9527             return false;
9528 
9529         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C);
9530 
9531         // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), ‘1’);
9532         uint32_t Rn = ReadCoreReg (n, &success);
9533         if (!success)
9534             return false;
9535 
9536         AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1);
9537 
9538         // if d == 15 then // Can only occur for ARM encoding
9539             // ALUWritePC(result); // setflags is always FALSE here
9540         // else
9541             // R[d] = result;
9542             // if setflags then
9543                 // APSR.N = result<31>;
9544                 // APSR.Z = IsZeroBit(result);
9545                 // APSR.C = carry;
9546                 // APSR.V = overflow;
9547 
9548         EmulateInstruction::Context context;
9549         context.type = eContextSubtraction;
9550         Register reg_n;
9551         reg_n.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
9552         Register reg_m;
9553         reg_m.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
9554         context.SetRegisterRegisterOperands (reg_n, reg_m);
9555 
9556         if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9557             return false;
9558     }
9559     return true;
9560 }
9561 
9562 // A8.6.202 STREX
9563 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a
9564 // word from a register to memory if the executing processor has exclusive access to the memory addressed.
9565 bool
9566 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding)
9567 {
9568 #if 0
9569     if ConditionPassed() then
9570         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9571         address = R[n] + imm32;
9572         if ExclusiveMonitorsPass(address,4) then
9573             MemA[address,4] = R[t];
9574             R[d] = 0;
9575         else
9576             R[d] = 1;
9577 #endif
9578 
9579     bool success = false;
9580 
9581     if (ConditionPassed(opcode))
9582     {
9583         uint32_t d;
9584         uint32_t t;
9585         uint32_t n;
9586         uint32_t imm32;
9587         const uint32_t addr_byte_size = GetAddressByteSize();
9588 
9589         switch (encoding)
9590         {
9591             case eEncodingT1:
9592                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32);
9593                 d = Bits32 (opcode, 11, 8);
9594                 t = Bits32 (opcode, 15, 12);
9595                 n = Bits32 (opcode, 19, 16);
9596                 imm32 = Bits32 (opcode, 7, 0) << 2;
9597 
9598                 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
9599                 if (BadReg (d) || BadReg (t) || (n == 15))
9600                   return false;
9601 
9602                 // if d == n || d == t then UNPREDICTABLE;
9603                 if ((d == n) || (d == t))
9604                   return false;
9605 
9606                 break;
9607 
9608             case eEncodingA1:
9609                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset
9610                 d = Bits32 (opcode, 15, 12);
9611                 t = Bits32 (opcode, 3, 0);
9612                 n = Bits32 (opcode, 19, 16);
9613                 imm32 = 0;
9614 
9615                 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
9616                 if ((d == 15) || (t == 15) || (n == 15))
9617                     return false;
9618 
9619                 // if d == n || d == t then UNPREDICTABLE;
9620                 if ((d == n) || (d == t))
9621                     return false;
9622 
9623                 break;
9624 
9625             default:
9626                 return false;
9627         }
9628 
9629         // address = R[n] + imm32;
9630         uint32_t Rn = ReadCoreReg (n, &success);
9631         if (!success)
9632             return false;
9633 
9634         addr_t address = Rn + imm32;
9635 
9636         Register base_reg;
9637         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
9638         Register data_reg;
9639         data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
9640         EmulateInstruction::Context context;
9641         context.type = eContextRegisterStore;
9642         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32);
9643 
9644         // if ExclusiveMonitorsPass(address,4) then
9645         // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this
9646         //                                                         always return true.
9647         if (true)
9648         {
9649             // MemA[address,4] = R[t];
9650             uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
9651             if (!success)
9652                 return false;
9653 
9654             if (!MemAWrite (context, address, Rt, addr_byte_size))
9655                 return false;
9656 
9657             // R[d] = 0;
9658             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0))
9659                 return false;
9660         }
9661         else
9662         {
9663             // R[d] = 1;
9664             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
9665                 return false;
9666         }
9667     }
9668     return true;
9669 }
9670 
9671 // A8.6.197 STRB (immediate, ARM)
9672 bool
9673 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9674 {
9675 #if 0
9676     if ConditionPassed() then
9677         EncodingSpecificOperations();
9678         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9679         address = if index then offset_addr else R[n];
9680         MemU[address,1] = R[t]<7:0>;
9681         if wback then R[n] = offset_addr;
9682 #endif
9683 
9684     bool success = false;
9685 
9686     if (ConditionPassed(opcode))
9687     {
9688         uint32_t t;
9689         uint32_t n;
9690         uint32_t imm32;
9691         bool index;
9692         bool add;
9693         bool wback;
9694 
9695         switch (encoding)
9696         {
9697             case eEncodingA1:
9698                 // if P == ‘0’ && W == ‘1’ then SEE STRBT;
9699                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9700                 t = Bits32 (opcode, 15, 12);
9701                 n = Bits32 (opcode, 19, 16);
9702                 imm32 = Bits32 (opcode, 11, 0);
9703 
9704                 // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’);
9705                 index = BitIsSet (opcode, 24);
9706                 add = BitIsSet (opcode, 23);
9707                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9708 
9709                 // if t == 15 then UNPREDICTABLE;
9710                 if (t == 15)
9711                     return false;
9712 
9713                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9714                 if (wback && ((n == 15) || (n == t)))
9715                     return false;
9716 
9717                 break;
9718 
9719             default:
9720                 return false;
9721         }
9722 
9723         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9724         uint32_t Rn = ReadCoreReg (n, &success);
9725         if (!success)
9726             return false;
9727 
9728         addr_t offset_addr;
9729         if (add)
9730             offset_addr = Rn + imm32;
9731         else
9732             offset_addr = Rn - imm32;
9733 
9734         // address = if index then offset_addr else R[n];
9735         addr_t address;
9736         if (index)
9737             address = offset_addr;
9738         else
9739             address = Rn;
9740 
9741         // MemU[address,1] = R[t]<7:0>;
9742         uint32_t Rt = ReadCoreReg (t, &success);
9743         if (!success)
9744             return false;
9745 
9746         Register base_reg;
9747         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
9748         Register data_reg;
9749         data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
9750         EmulateInstruction::Context context;
9751         context.type = eContextRegisterStore;
9752         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
9753 
9754         if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1))
9755             return false;
9756 
9757         // if wback then R[n] = offset_addr;
9758         if (wback)
9759         {
9760             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
9761                 return false;
9762         }
9763     }
9764     return true;
9765 }
9766 
9767 // A8.6.194 STR (immediate, ARM)
9768 bool
9769 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding)
9770 {
9771 #if 0
9772     if ConditionPassed() then
9773         EncodingSpecificOperations();
9774         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9775         address = if index then offset_addr else R[n];
9776         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
9777         if wback then R[n] = offset_addr;
9778 #endif
9779 
9780     bool success = false;
9781 
9782     if (ConditionPassed(opcode))
9783     {
9784         uint32_t t;
9785         uint32_t n;
9786         uint32_t imm32;
9787         bool index;
9788         bool add;
9789         bool wback;
9790 
9791         const uint32_t addr_byte_size = GetAddressByteSize();
9792 
9793         switch (encoding)
9794         {
9795             case eEncodingA1:
9796                 // if P == ‘0’ && W == ‘1’ then SEE STRT;
9797                 // if Rn == ‘1101’ && P == ‘1’ && U == ‘0’ && W == ‘1’ && imm12 == ‘000000000100’ then SEE PUSH;
9798                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9799                 t = Bits32 (opcode, 15, 12);
9800                 n = Bits32 (opcode, 19, 16);
9801                 imm32 = Bits32 (opcode, 11, 0);
9802 
9803                 // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’);
9804                 index = BitIsSet (opcode, 24);
9805                 add = BitIsSet (opcode, 23);
9806                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9807 
9808                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9809                 if (wback && ((n == 15) || (n == t)))
9810                     return false;
9811 
9812                 break;
9813 
9814             default:
9815                 return false;
9816         }
9817 
9818         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9819         uint32_t Rn = ReadCoreReg (n, &success);
9820         if (!success)
9821             return false;
9822 
9823         addr_t offset_addr;
9824         if (add)
9825             offset_addr = Rn + imm32;
9826         else
9827             offset_addr = Rn - imm32;
9828 
9829         // address = if index then offset_addr else R[n];
9830         addr_t address;
9831         if (index)
9832             address = offset_addr;
9833         else
9834             address = Rn;
9835 
9836         Register base_reg;
9837         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
9838         Register data_reg;
9839         data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
9840         EmulateInstruction::Context context;
9841         context.type = eContextRegisterStore;
9842         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
9843 
9844         // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
9845         uint32_t Rt = ReadCoreReg (t, &success);
9846         if (!success)
9847             return false;
9848 
9849         if (t == 15)
9850         {
9851             uint32_t pc_value = ReadCoreReg (PC_REG, &success);
9852             if (!success)
9853                 return false;
9854 
9855             if (!MemUWrite (context, address, pc_value, addr_byte_size))
9856                 return false;
9857         }
9858         else
9859         {
9860             if (!MemUWrite (context, address, Rt, addr_byte_size))
9861                   return false;
9862         }
9863 
9864         // if wback then R[n] = offset_addr;
9865         if (wback)
9866         {
9867             context.type = eContextAdjustBaseRegister;
9868             context.SetImmediate (offset_addr);
9869 
9870             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
9871                 return false;
9872         }
9873     }
9874     return true;
9875 }
9876 
9877 // A8.6.66 LDRD (immediate)
9878 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two
9879 // words from memory, and writes them to two registers.  It can use offset, post-indexed, or pre-indexed addressing.
9880 bool
9881 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding)
9882 {
9883 #if 0
9884     if ConditionPassed() then
9885         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9886         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9887         address = if index then offset_addr else R[n];
9888         R[t] = MemA[address,4];
9889         R[t2] = MemA[address+4,4];
9890         if wback then R[n] = offset_addr;
9891 #endif
9892 
9893     bool success = false;
9894 
9895     if (ConditionPassed(opcode))
9896     {
9897         uint32_t t;
9898         uint32_t t2;
9899         uint32_t n;
9900         uint32_t imm32;
9901         bool index;
9902         bool add;
9903         bool wback;
9904 
9905         switch (encoding)
9906         {
9907             case eEncodingT1:
9908                 //if P == ‘0’ && W == ‘0’ then SEE “Related encodings”;
9909                 //if Rn == ‘1111’ then SEE LDRD (literal);
9910                 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32);
9911                 t = Bits32 (opcode, 15, 12);
9912                 t2 = Bits32 (opcode, 11, 8);
9913                 n = Bits32 (opcode, 19, 16);
9914                 imm32 = Bits32 (opcode, 7, 0) << 2;
9915 
9916                 //index = (P == ‘1’); add = (U == ‘1’); wback = (W == ‘1’);
9917                 index = BitIsSet (opcode, 24);
9918                 add = BitIsSet (opcode, 23);
9919                 wback = BitIsSet (opcode, 21);
9920 
9921                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
9922                 if (wback && ((n == t) || (n == t2)))
9923                     return false;
9924 
9925                 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
9926                 if (BadReg (t) || BadReg (t2) || (t == t2))
9927                     return false;
9928 
9929                 break;
9930 
9931             case eEncodingA1:
9932                 //if Rn == ‘1111’ then SEE LDRD (literal);
9933                 //if Rt<0> == ‘1’ then UNPREDICTABLE;
9934                 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
9935                 t = Bits32 (opcode, 15, 12);
9936                 if (BitIsSet (t, 0))
9937                     return false;
9938                 t2 = t + 1;
9939                 n = Bits32 (opcode, 19, 16);
9940                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
9941 
9942                 //index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’);
9943                 index = BitIsSet (opcode, 24);
9944                 add = BitIsSet (opcode, 23);
9945                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9946 
9947                 //if P == ‘0’ && W == ‘1’ then UNPREDICTABLE;
9948                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
9949                     return false;
9950 
9951                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
9952                 if (wback && ((n == t) || (n == t2)))
9953                     return false;
9954 
9955                 //if t2 == 15 then UNPREDICTABLE;
9956                 if (t2 == 15)
9957                     return false;
9958 
9959                 break;
9960 
9961             default:
9962                 return false;
9963         }
9964 
9965         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9966         uint32_t Rn = ReadCoreReg (n, &success);
9967         if (!success)
9968             return false;
9969 
9970         addr_t offset_addr;
9971         if (add)
9972                   offset_addr = Rn + imm32;
9973         else
9974             offset_addr = Rn - imm32;
9975 
9976         //address = if index then offset_addr else R[n];
9977         addr_t address;
9978         if (index)
9979             address = offset_addr;
9980         else
9981             address = Rn;
9982 
9983         //R[t] = MemA[address,4];
9984         Register base_reg;
9985         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
9986 
9987         EmulateInstruction::Context context;
9988         context.type = eContextRegisterLoad;
9989         context.SetRegisterPlusOffset (base_reg, address - Rn);
9990 
9991         const uint32_t addr_byte_size = GetAddressByteSize();
9992         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
9993         if (!success)
9994             return false;
9995 
9996         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
9997             return false;
9998 
9999         //R[t2] = MemA[address+4,4];
10000 
10001         context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10002         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10003         if (!success)
10004             return false;
10005 
10006         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10007             return false;
10008 
10009         //if wback then R[n] = offset_addr;
10010         if (wback)
10011         {
10012             context.type = eContextAdjustBaseRegister;
10013             context.SetAddress (offset_addr);
10014 
10015             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10016                 return false;
10017         }
10018     }
10019     return true;
10020 }
10021 
10022 // A8.6.68 LDRD (register)
10023 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two
10024 // words from memory, and writes them to two registers.  It can use offset, post-indexed or pre-indexed addressing.
10025 bool
10026 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding)
10027 {
10028 #if 0
10029     if ConditionPassed() then
10030         EncodingSpecificOperations();
10031         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10032         address = if index then offset_addr else R[n];
10033         R[t] = MemA[address,4];
10034         R[t2] = MemA[address+4,4];
10035         if wback then R[n] = offset_addr;
10036 #endif
10037 
10038     bool success = false;
10039 
10040     if (ConditionPassed(opcode))
10041     {
10042         uint32_t t;
10043         uint32_t t2;
10044         uint32_t n;
10045         uint32_t m;
10046         bool index;
10047         bool add;
10048         bool wback;
10049 
10050         switch (encoding)
10051         {
10052             case eEncodingA1:
10053                 // if Rt<0> == ‘1’ then UNPREDICTABLE;
10054                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10055                 t = Bits32 (opcode, 15, 12);
10056                 if (BitIsSet (t, 0))
10057                     return false;
10058                 t2 = t + 1;
10059                 n = Bits32 (opcode, 19, 16);
10060                 m = Bits32 (opcode, 3, 0);
10061 
10062                 // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’);
10063                 index = BitIsSet (opcode, 24);
10064                 add = BitIsSet (opcode, 23);
10065                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10066 
10067                 // if P == ‘0’ && W == ‘1’ then UNPREDICTABLE;
10068                   if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10069                   return false;
10070 
10071                 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10072                   if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10073                   return false;
10074 
10075                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10076                   if (wback && ((n == 15) || (n == t) || (n == t2)))
10077                   return false;
10078 
10079                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10080                 if ((ArchVersion() < 6) && wback && (m == n))
10081                   return false;
10082                 break;
10083 
10084             default:
10085                 return false;
10086         }
10087 
10088         uint32_t Rn = ReadCoreReg (n, &success);
10089         if (!success)
10090             return false;
10091         Register base_reg;
10092         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
10093 
10094         uint32_t Rm = ReadCoreReg (m, &success);
10095         if (!success)
10096             return false;
10097         Register offset_reg;
10098         offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
10099 
10100         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10101         addr_t offset_addr;
10102         if (add)
10103             offset_addr = Rn + Rm;
10104         else
10105             offset_addr = Rn - Rm;
10106 
10107         // address = if index then offset_addr else R[n];
10108         addr_t address;
10109         if (index)
10110             address = offset_addr;
10111         else
10112             address = Rn;
10113 
10114         EmulateInstruction::Context context;
10115         context.type = eContextRegisterLoad;
10116         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
10117 
10118         // R[t] = MemA[address,4];
10119         const uint32_t addr_byte_size = GetAddressByteSize();
10120         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10121         if (!success)
10122             return false;
10123 
10124         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10125             return false;
10126 
10127         // R[t2] = MemA[address+4,4];
10128 
10129         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10130         if (!success)
10131             return false;
10132 
10133         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10134             return false;
10135 
10136         // if wback then R[n] = offset_addr;
10137         if (wback)
10138         {
10139             context.type = eContextAdjustBaseRegister;
10140             context.SetAddress (offset_addr);
10141 
10142             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10143                 return false;
10144         }
10145     }
10146     return true;
10147 }
10148 
10149 // A8.6.200 STRD (immediate)
10150 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and
10151 // stores two words from two registers to memory.  It can use offset, post-indexed, or pre-indexed addressing.
10152 bool
10153 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding)
10154 {
10155 #if 0
10156     if ConditionPassed() then
10157         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10158         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10159         address = if index then offset_addr else R[n];
10160         MemA[address,4] = R[t];
10161         MemA[address+4,4] = R[t2];
10162         if wback then R[n] = offset_addr;
10163 #endif
10164 
10165     bool success = false;
10166 
10167     if (ConditionPassed(opcode))
10168     {
10169         uint32_t t;
10170         uint32_t t2;
10171         uint32_t n;
10172         uint32_t imm32;
10173         bool index;
10174         bool add;
10175         bool wback;
10176 
10177         switch (encoding)
10178         {
10179             case eEncodingT1:
10180                 // if P == ‘0’ && W == ‘0’ then SEE “Related encodings”;
10181                 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32);
10182                 t = Bits32 (opcode, 15, 12);
10183                 t2 = Bits32 (opcode, 11, 8);
10184                 n = Bits32 (opcode, 19, 16);
10185                 imm32 = Bits32 (opcode, 7, 0) << 2;
10186 
10187                 // index = (P == ‘1’); add = (U == ‘1’); wback = (W == ‘1’);
10188                 index = BitIsSet (opcode, 24);
10189                 add = BitIsSet (opcode, 23);
10190                 wback = BitIsSet (opcode, 21);
10191 
10192                 // if wback && (n == t || n == t2) then UNPREDICTABLE;
10193                 if (wback && ((n == t) || (n == t2)))
10194                     return false;
10195 
10196                 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10197                 if ((n == 15) || BadReg (t) || BadReg (t2))
10198                     return false;
10199 
10200                 break;
10201 
10202             case eEncodingA1:
10203                 // if Rt<0> == ‘1’ then UNPREDICTABLE;
10204                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10205                 t = Bits32 (opcode, 15, 12);
10206                 if (BitIsSet (t, 0))
10207                     return false;
10208 
10209                 t2 = t + 1;
10210                 n = Bits32 (opcode, 19, 16);
10211                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10212 
10213                 // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’);
10214                 index = BitIsSet (opcode, 24);
10215                 add = BitIsSet (opcode, 23);
10216                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10217 
10218                 // if P == ‘0’ && W == ‘1’ then UNPREDICTABLE;
10219                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10220                     return false;
10221 
10222                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10223                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10224                     return false;
10225 
10226                 // if t2 == 15 then UNPREDICTABLE;
10227                 if (t2 == 15)
10228                     return false;
10229 
10230                 break;
10231 
10232             default:
10233                 return false;
10234         }
10235 
10236         Register base_reg;
10237         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
10238 
10239         uint32_t Rn = ReadCoreReg (n, &success);
10240         if (!success)
10241             return false;
10242 
10243         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10244         addr_t offset_addr;
10245         if (add)
10246             offset_addr = Rn + imm32;
10247         else
10248             offset_addr = Rn - imm32;
10249 
10250         //address = if index then offset_addr else R[n];
10251         addr_t address;
10252         if (index)
10253             address = offset_addr;
10254         else
10255             address = Rn;
10256 
10257         //MemA[address,4] = R[t];
10258         Register data_reg;
10259         data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
10260 
10261         uint32_t data = ReadCoreReg (t, &success);
10262         if (!success)
10263             return false;
10264 
10265         EmulateInstruction::Context context;
10266         context.type = eContextRegisterStore;
10267         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10268 
10269         const uint32_t addr_byte_size = GetAddressByteSize();
10270 
10271         if (!MemAWrite (context, address, data, addr_byte_size))
10272             return false;
10273 
10274         //MemA[address+4,4] = R[t2];
10275         data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t2);
10276         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10277 
10278         data = ReadCoreReg (t2, &success);
10279         if (!success)
10280             return false;
10281 
10282         if (!MemAWrite (context, address + 4, data, addr_byte_size))
10283             return false;
10284 
10285         //if wback then R[n] = offset_addr;
10286         if (wback)
10287         {
10288             context.type = eContextAdjustBaseRegister;
10289             context.SetAddress (offset_addr);
10290 
10291             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10292                 return false;
10293         }
10294     }
10295     return true;
10296 }
10297 
10298 
10299 // A8.6.201 STRD (register)
10300 bool
10301 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding)
10302 {
10303 #if 0
10304     if ConditionPassed() then
10305         EncodingSpecificOperations();
10306         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10307         address = if index then offset_addr else R[n];
10308         MemA[address,4] = R[t];
10309         MemA[address+4,4] = R[t2];
10310         if wback then R[n] = offset_addr;
10311 #endif
10312 
10313     bool success = false;
10314 
10315     if (ConditionPassed(opcode))
10316     {
10317         uint32_t t;
10318         uint32_t t2;
10319         uint32_t n;
10320         uint32_t m;
10321         bool index;
10322         bool add;
10323         bool wback;
10324 
10325         switch (encoding)
10326         {
10327             case eEncodingA1:
10328                 // if Rt<0> == ‘1’ then UNPREDICTABLE;
10329                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10330                 t = Bits32 (opcode, 15, 12);
10331                 if (BitIsSet (t, 0))
10332                    return false;
10333 
10334                 t2 = t+1;
10335                 n = Bits32 (opcode, 19, 16);
10336                 m = Bits32 (opcode, 3, 0);
10337 
10338                 // index = (P == ‘1’); add = (U == ‘1’); wback = (P == ‘0’) || (W == ‘1’);
10339                 index = BitIsSet (opcode, 24);
10340                 add = BitIsSet (opcode, 23);
10341                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10342 
10343                 // if P == ‘0’ && W == ‘1’ then UNPREDICTABLE;
10344                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10345                    return false;
10346 
10347                 // if t2 == 15 || m == 15 then UNPREDICTABLE;
10348                 if ((t2 == 15) || (m == 15))
10349                    return false;
10350 
10351                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10352                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10353                    return false;
10354 
10355                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10356                 if ((ArchVersion() < 6) && wback && (m == n))
10357                    return false;
10358 
10359                 break;
10360 
10361             default:
10362                 return false;
10363         }
10364 
10365         Register base_reg;
10366         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
10367         Register offset_reg;
10368         offset_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + m);
10369         Register data_reg;
10370         data_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + t);
10371 
10372         uint32_t Rn = ReadCoreReg (n, &success);
10373         if (!success)
10374             return false;
10375 
10376         uint32_t Rm = ReadCoreReg (m, &success);
10377         if (!success)
10378             return false;
10379 
10380         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10381         addr_t offset_addr;
10382         if (add)
10383             offset_addr = Rn + Rm;
10384         else
10385             offset_addr = Rn - Rm;
10386 
10387         // address = if index then offset_addr else R[n];
10388         addr_t address;
10389         if (index)
10390             address = offset_addr;
10391         else
10392             address = Rn;
10393                           // MemA[address,4] = R[t];
10394         uint32_t Rt = ReadCoreReg (t, &success);
10395         if (!success)
10396             return false;
10397 
10398         EmulateInstruction::Context context;
10399         context.type = eContextRegisterStore;
10400         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10401 
10402         const uint32_t addr_byte_size = GetAddressByteSize();
10403 
10404         if (!MemAWrite (context, address, Rt, addr_byte_size))
10405             return false;
10406 
10407         // MemA[address+4,4] = R[t2];
10408         uint32_t Rt2 = ReadCoreReg (t2, &success);
10409         if (!success)
10410             return false;
10411 
10412         data_reg.num = dwarf_r0 + t2;
10413 
10414         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10415 
10416         if (!MemAWrite (context, address + 4, Rt2, addr_byte_size))
10417             return false;
10418 
10419         // if wback then R[n] = offset_addr;
10420         if (wback)
10421         {
10422             context.type = eContextAdjustBaseRegister;
10423             context.SetAddress (offset_addr);
10424 
10425             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10426                 return false;
10427 
10428         }
10429     }
10430     return true;
10431 }
10432 
10433 // A8.6.319 VLDM
10434 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from
10435 // an ARM core register.
10436 bool
10437 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding)
10438 {
10439 #if 0
10440     if ConditionPassed() then
10441         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10442         address = if add then R[n] else R[n]-imm32;
10443         if wback then R[n] = if add then R[n}+imm32 else R[n]-imm32;
10444         for r = 0 to regs-1
10445             if single_regs then
10446                 S[d+r] = MemA[address,4]; address = address+4;
10447             else
10448                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10449                 // Combine the word-aligned words in the correct order for current endianness.
10450                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10451 #endif
10452 
10453     bool success = false;
10454 
10455     if (ConditionPassed(opcode))
10456     {
10457         bool single_regs;
10458         bool add;
10459         bool wback;
10460         uint32_t d;
10461         uint32_t n;
10462         uint32_t imm32;
10463         uint32_t regs;
10464 
10465         switch (encoding)
10466         {
10467             case eEncodingT1:
10468             case eEncodingA1:
10469                 // if P == ‘0’ && U == ‘0’ && W == ‘0’ then SEE “Related encodings”;
10470                 // if P == ‘0’ && U == ‘1’ && W == ‘1’ && Rn == ‘1101’ then SEE VPOP;
10471                 // if P == ‘1’ && W == ‘0’ then SEE VLDR;
10472                 // if P == U && W == ‘1’ then UNDEFINED;
10473                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10474                     return false;
10475 
10476                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10477                 // single_regs = FALSE; add = (U == ‘1’); wback = (W == ‘1’);
10478                 single_regs = false;
10479                 add = BitIsSet (opcode, 23);
10480                 wback = BitIsSet (opcode, 21);
10481 
10482                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32);
10483                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10484                 n = Bits32 (opcode, 19, 16);
10485                 imm32 = Bits32 (opcode, 7, 0) << 2;
10486 
10487                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see “FLDMX”.
10488                 regs = Bits32 (opcode, 7, 0) / 2;
10489 
10490                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10491                 if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
10492                     return false;
10493 
10494                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10495                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10496                     return false;
10497 
10498                 break;
10499 
10500             case eEncodingT2:
10501             case eEncodingA2:
10502                 // if P == ‘0’ && U == ‘0’ && W == ‘0’ then SEE “Related encodings”;
10503                 // if P == ‘0’ && U == ‘1’ && W == ‘1’ && Rn == ‘1101’ then SEE VPOP;
10504                 // if P == ‘1’ && W == ‘0’ then SEE VLDR;
10505                 // if P == U && W == ‘1’ then UNDEFINED;
10506                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10507                     return false;
10508 
10509                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10510                 // single_regs = TRUE; add = (U == ‘1’); wback = (W == ‘1’); d = UInt(Vd:D); n = UInt(Rn);
10511                 single_regs = true;
10512                 add = BitIsSet (opcode, 23);
10513                 wback = BitIsSet (opcode, 21);
10514                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10515                 n = Bits32 (opcode, 19, 16);
10516 
10517                 // imm32 = ZeroExtend(imm8:’00’, 32); regs = UInt(imm8);
10518                 imm32 = Bits32 (opcode, 7, 0) << 2;
10519                 regs = Bits32 (opcode, 7, 0);
10520 
10521                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10522                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10523                     return false;
10524 
10525                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10526                 if ((regs == 0) || ((d + regs) > 32))
10527                     return false;
10528                 break;
10529 
10530             default:
10531                 return false;
10532         }
10533 
10534         Register base_reg;
10535         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
10536 
10537         uint32_t Rn = ReadCoreReg (n, &success);
10538         if (!success)
10539             return false;
10540 
10541         // address = if add then R[n] else R[n]-imm32;
10542         addr_t address;
10543         if (add)
10544             address = Rn;
10545         else
10546             address = Rn - imm32;
10547 
10548         // if wback then R[n] = if add then R[n}+imm32 else R[n]-imm32;
10549         EmulateInstruction::Context context;
10550 
10551         if (wback)
10552         {
10553             uint32_t value;
10554             if (add)
10555                 value = Rn + imm32;
10556             else
10557                 value = Rn - imm32;
10558 
10559             context.type = eContextAdjustBaseRegister;
10560             context.SetImmediateSigned (value - Rn);
10561             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10562                 return false;
10563 
10564         }
10565 
10566         const uint32_t addr_byte_size = GetAddressByteSize();
10567         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10568 
10569         context.type = eContextRegisterLoad;
10570 
10571         // for r = 0 to regs-1
10572         for (uint32_t r = 0; r < regs; ++r)
10573         {
10574             if (single_regs)
10575             {
10576                 // S[d+r] = MemA[address,4]; address = address+4;
10577                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10578 
10579                 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10580                 if (!success)
10581                     return false;
10582 
10583                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10584                     return false;
10585 
10586                 address = address + 4;
10587             }
10588             else
10589             {
10590                 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10591                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10592                 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10593                 if (!success)
10594                     return false;
10595 
10596                 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10597                 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10598                 if (!success)
10599                     return false;
10600 
10601                 address = address + 8;
10602                 // // Combine the word-aligned words in the correct order for current endianness.
10603                 // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10604                 uint64_t data;
10605                 if (m_byte_order == eByteOrderBig)
10606                 {
10607                     data = word1;
10608                     data = (data << 32) | word2;
10609                 }
10610                 else
10611                 {
10612                     data = word2;
10613                     data = (data << 32) | word1;
10614                 }
10615 
10616                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10617                     return false;
10618             }
10619         }
10620     }
10621     return true;
10622 }
10623 
10624 // A8.6.399 VSTM
10625 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an
10626 // ARM core register.
10627 bool
10628 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding)
10629 {
10630 #if 0
10631     if ConditionPassed() then
10632         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10633         address = if add then R[n] else R[n]-imm32;
10634         if wback then R[n] = if add then R[n}+imm32 else R[n]-imm32;
10635         for r = 0 to regs-1
10636             if single_regs then
10637                 MemA[address,4] = S[d+r]; address = address+4;
10638             else
10639                 // Store as two word-aligned words in the correct order for current endianness.
10640                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10641                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10642                 address = address+8;
10643 #endif
10644 
10645     bool success = false;
10646 
10647     if (ConditionPassed (opcode))
10648     {
10649         bool single_regs;
10650         bool add;
10651         bool wback;
10652         uint32_t d;
10653         uint32_t n;
10654         uint32_t imm32;
10655         uint32_t regs;
10656 
10657         switch (encoding)
10658         {
10659             case eEncodingT1:
10660             case eEncodingA1:
10661                 // if P == ‘0’ && U == ‘0’ && W == ‘0’ then SEE “Related encodings”;
10662                 // if P == ‘1’ && U == ‘0’ && W == ‘1’ && Rn == ‘1101’ then SEE VPUSH;
10663                 // if P == ‘1’ && W == ‘0’ then SEE VSTR;
10664                 // if P == U && W == ‘1’ then UNDEFINED;
10665                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10666                     return false;
10667 
10668                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10669                 // single_regs = FALSE; add = (U == ‘1’); wback = (W == ‘1’);
10670                 single_regs = false;
10671                 add = BitIsSet (opcode, 23);
10672                 wback = BitIsSet (opcode, 21);
10673 
10674                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:’00’, 32);
10675                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10676                 n = Bits32 (opcode, 19, 16);
10677                 imm32 = Bits32 (opcode, 7, 0) << 2;
10678 
10679                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see “FSTMX”.
10680                 regs = Bits32 (opcode, 7, 0) / 2;
10681 
10682                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10683                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10684                     return false;
10685 
10686                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10687                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10688                     return false;
10689 
10690                 break;
10691 
10692             case eEncodingT2:
10693             case eEncodingA2:
10694                 // if P == ‘0’ && U == ‘0’ && W == ‘0’ then SEE “Related encodings”;
10695                 // if P == ‘1’ && U == ‘0’ && W == ‘1’ && Rn == ‘1101’ then SEE VPUSH;
10696                 // if P == ‘1’ && W == ‘0’ then SEE VSTR;
10697                 // if P == U && W == ‘1’ then UNDEFINED;
10698                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10699                     return false;
10700 
10701                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10702                 // single_regs = TRUE; add = (U == ‘1’); wback = (W == ‘1’); d = UInt(Vd:D); n = UInt(Rn);
10703                 single_regs = true;
10704                 add = BitIsSet (opcode, 23);
10705                 wback = BitIsSet (opcode, 21);
10706                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10707                 n = Bits32 (opcode, 19, 16);
10708 
10709                 // imm32 = ZeroExtend(imm8:’00’, 32); regs = UInt(imm8);
10710                 imm32 = Bits32 (opcode, 7, 0) << 2;
10711                 regs = Bits32 (opcode, 7, 0);
10712 
10713                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10714                 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM)))
10715                     return false;
10716 
10717                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10718                 if ((regs == 0) || ((d + regs) > 32))
10719                     return false;
10720 
10721                 break;
10722 
10723             default:
10724                 return false;
10725         }
10726 
10727         Register base_reg;
10728         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
10729 
10730         uint32_t Rn = ReadCoreReg (n, &success);
10731         if (!success)
10732             return false;
10733 
10734         // address = if add then R[n] else R[n]-imm32;
10735         addr_t address;
10736         if (add)
10737             address = Rn;
10738         else
10739             address = Rn - imm32;
10740 
10741         EmulateInstruction::Context context;
10742         // if wback then R[n] = if add then R[n}+imm32 else R[n]-imm32;
10743         if (wback)
10744         {
10745             uint32_t value;
10746             if (add)
10747                 value = Rn + imm32;
10748             else
10749                 value = Rn - imm32;
10750 
10751             context.type = eContextAdjustBaseRegister;
10752             context.SetRegisterPlusOffset (base_reg, value - Rn);
10753 
10754             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10755                 return false;
10756         }
10757 
10758         const uint32_t addr_byte_size = GetAddressByteSize();
10759         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10760 
10761         context.type = eContextRegisterStore;
10762         // for r = 0 to regs-1
10763         for (int r = 0; r < regs; ++r)
10764         {
10765             Register data_reg;
10766             data_reg.SetRegister (eRegisterKindDWARF, 0);
10767             if (single_regs)
10768             {
10769                 // MemA[address,4] = S[d+r]; address = address+4;
10770                 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10771                 if (!success)
10772                     return false;
10773 
10774                 data_reg.num = start_reg + d + r;
10775                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10776                 if (!MemAWrite (context, address, data, addr_byte_size))
10777                     return false;
10778 
10779                 address = address + 4;
10780             }
10781             else
10782             {
10783                 // // Store as two word-aligned words in the correct order for current endianness.
10784                 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10785                 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10786                 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10787                 if (!success)
10788                     return false;
10789 
10790                 data_reg.num = start_reg + d + r;
10791 
10792                 if (m_byte_order == eByteOrderBig)
10793                 {
10794                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10795                     if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
10796                         return false;
10797 
10798                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10799                     if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size))
10800                         return false;
10801                 }
10802                 else
10803                 {
10804                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10805                     if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
10806                         return false;
10807 
10808                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10809                     if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
10810                         return false;
10811                 }
10812                 // address = address+8;
10813                 address = address + 8;
10814             }
10815         }
10816     }
10817     return true;
10818 }
10819 
10820 // A8.6.320
10821 // This instruciton loads a single extension register fronm memory, using an address from an ARM core register, with
10822 // an optional offset.
10823 bool
10824 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
10825 {
10826 #if 0
10827     if ConditionPassed() then
10828         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10829         base = if n == 15 then Align(PC,4) else R[n];
10830         address = if add then (base + imm32) else (base - imm32);
10831         if single_reg then
10832             S[d] = MemA[address,4];
10833         else
10834             word1 = MemA[address,4]; word2 = MemA[address+4,4];
10835             // Combine the word-aligned words in the correct order for current endianness.
10836             D[d] = if BigEndian() then word1:word2 else word2:word1;
10837 #endif
10838 
10839     bool success = false;
10840 
10841     if (ConditionPassed (opcode))
10842     {
10843         bool single_reg;
10844         bool add;
10845         uint32_t imm32;
10846         uint32_t d;
10847         uint32_t n;
10848 
10849         switch (encoding)
10850         {
10851             case eEncodingT1:
10852             case eEncodingA1:
10853                 // single_reg = FALSE; add = (U == ‘1’); imm32 = ZeroExtend(imm8:’00’, 32);
10854                 single_reg = false;
10855                 add = BitIsSet (opcode, 23);
10856                 imm32 = Bits32 (opcode, 7, 0) << 2;
10857 
10858                 // d = UInt(D:Vd); n = UInt(Rn);
10859                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10860                 n = Bits32 (opcode, 19, 16);
10861 
10862                 break;
10863 
10864             case eEncodingT2:
10865             case eEncodingA2:
10866                 // single_reg = TRUE; add = (U == ‘1’); imm32 = ZeroExtend(imm8:’00’, 32);
10867                 single_reg = true;
10868                 add = BitIsSet (opcode, 23);
10869                 imm32 = Bits32 (opcode, 7, 0) << 2;
10870 
10871                 // d = UInt(Vd:D); n = UInt(Rn);
10872                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10873                 n = Bits32 (opcode, 19, 16);
10874 
10875                 break;
10876 
10877             default:
10878                 return false;
10879         }
10880         Register base_reg;
10881         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
10882 
10883         uint32_t Rn = ReadCoreReg (n, &success);
10884         if (!success)
10885             return false;
10886 
10887         // base = if n == 15 then Align(PC,4) else R[n];
10888         uint32_t base;
10889         if (n == 15)
10890             base = AlignPC (Rn);
10891         else
10892             base = Rn;
10893 
10894         // address = if add then (base + imm32) else (base - imm32);
10895         addr_t address;
10896         if (add)
10897             address = base + imm32;
10898         else
10899             address = base - imm32;
10900 
10901         const uint32_t addr_byte_size = GetAddressByteSize();
10902         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
10903 
10904         EmulateInstruction::Context context;
10905         context.type = eContextRegisterLoad;
10906         context.SetRegisterPlusOffset (base_reg, address - base);
10907 
10908         if (single_reg)
10909         {
10910             // S[d] = MemA[address,4];
10911             uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10912             if (!success)
10913                 return false;
10914 
10915             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data))
10916                 return false;
10917         }
10918         else
10919         {
10920             // word1 = MemA[address,4]; word2 = MemA[address+4,4];
10921             uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10922             if (!success)
10923                 return false;
10924 
10925             context.SetRegisterPlusOffset (base_reg, (address + 4) - base);
10926             uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10927             if (!success)
10928                 return false;
10929             // // Combine the word-aligned words in the correct order for current endianness.
10930             // D[d] = if BigEndian() then word1:word2 else word2:word1;
10931             uint64_t data64;
10932             if (m_byte_order == eByteOrderBig)
10933             {
10934                 data64 = word1;
10935                 data64 = (data64 << 32) | word2;
10936             }
10937             else
10938             {
10939                 data64 = word2;
10940                 data64 = (data64 << 32) | word1;
10941             }
10942 
10943             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64))
10944                 return false;
10945         }
10946     }
10947     return true;
10948 }
10949 
10950 // A8.6.400 VSTR
10951 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an
10952 // optional offset.
10953 bool
10954 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
10955 {
10956 #if 0
10957     if ConditionPassed() then
10958         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10959         address = if add then (R[n] + imm32) else (R[n] - imm32);
10960         if single_reg then
10961             MemA[address,4] = S[d];
10962         else
10963             // Store as two word-aligned words in the correct order for current endianness.
10964             MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
10965             MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
10966 #endif
10967 
10968     bool success = false;
10969 
10970     if (ConditionPassed (opcode))
10971     {
10972         bool single_reg;
10973         bool add;
10974         uint32_t imm32;
10975         uint32_t d;
10976         uint32_t n;
10977 
10978         switch (encoding)
10979         {
10980             case eEncodingT1:
10981             case eEncodingA1:
10982                 // single_reg = FALSE; add = (U == ‘1’); imm32 = ZeroExtend(imm8:’00’, 32);
10983                 single_reg = false;
10984                 add = BitIsSet (opcode, 23);
10985                 imm32 = Bits32 (opcode, 7, 0) << 2;
10986 
10987                 // d = UInt(D:Vd); n = UInt(Rn);
10988                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10989                 n = Bits32 (opcode, 19, 16);
10990 
10991                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
10992                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
10993                     return false;
10994 
10995                 break;
10996 
10997             case eEncodingT2:
10998             case eEncodingA2:
10999                 // single_reg = TRUE; add = (U == ‘1’); imm32 = ZeroExtend(imm8:’00’, 32);
11000                 single_reg = true;
11001                 add = BitIsSet (opcode, 23);
11002                 imm32 = Bits32 (opcode, 7, 0) << 2;
11003 
11004                 // d = UInt(Vd:D); n = UInt(Rn);
11005                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11006                 n = Bits32 (opcode, 19, 16);
11007 
11008                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11009                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11010                     return false;
11011 
11012                 break;
11013 
11014             default:
11015                 return false;
11016         }
11017 
11018         Register base_reg;
11019         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
11020 
11021         uint32_t Rn = ReadCoreReg (n, &success);
11022         if (!success)
11023             return false;
11024 
11025         // address = if add then (R[n] + imm32) else (R[n] - imm32);
11026         addr_t address;
11027         if (add)
11028             address = Rn + imm32;
11029         else
11030             address = Rn - imm32;
11031 
11032         const uint32_t addr_byte_size = GetAddressByteSize();
11033         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11034 
11035         Register data_reg;
11036         data_reg.SetRegister (eRegisterKindDWARF, start_reg + d);
11037         EmulateInstruction::Context context;
11038         context.type = eContextRegisterStore;
11039         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11040 
11041         if (single_reg)
11042         {
11043             // MemA[address,4] = S[d];
11044             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11045             if (!success)
11046                 return false;
11047 
11048             if (!MemAWrite (context, address, data, addr_byte_size))
11049                 return false;
11050         }
11051         else
11052         {
11053             // // Store as two word-aligned words in the correct order for current endianness.
11054             // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11055             // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11056             uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11057             if (!success)
11058                 return false;
11059 
11060             if (m_byte_order == eByteOrderBig)
11061             {
11062                 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11063                     return false;
11064 
11065                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11066                 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size))
11067                     return false;
11068             }
11069             else
11070             {
11071                 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11072                     return false;
11073 
11074                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11075                 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11076                     return false;
11077             }
11078         }
11079     }
11080     return true;
11081 }
11082 
11083 // A8.6.307 VLDI1 (multiple single elements)
11084 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving.  Every
11085 // element of each register is loaded.
11086 bool
11087 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding)
11088 {
11089 #if 0
11090     if ConditionPassed() then
11091         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11092         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11093         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11094         for r = 0 to regs-1
11095             for e = 0 to elements-1
11096                 Elem[D[d+r],e,esize] = MemU[address,ebytes];
11097                 address = address + ebytes;
11098 #endif
11099 
11100     bool success = false;
11101 
11102     if (ConditionPassed (opcode))
11103     {
11104         uint32_t regs;
11105         uint32_t alignment;
11106         uint32_t ebytes;
11107         uint32_t esize;
11108         uint32_t elements;
11109         uint32_t d;
11110         uint32_t n;
11111         uint32_t m;
11112         bool wback;
11113         bool register_index;
11114 
11115         switch (encoding)
11116         {
11117             case eEncodingT1:
11118             case eEncodingA1:
11119             {
11120                 // case type of
11121                     // when ‘0111’
11122                         // regs = 1; if align<1> == ‘1’ then UNDEFINED;
11123                     // when ‘1010’
11124                         // regs = 2; if align == ‘11’ then UNDEFINED;
11125                     // when ‘0110’
11126                         // regs = 3; if align<1> == ‘1’ then UNDEFINED;
11127                     // when ‘0010’
11128                         // regs = 4;
11129                     // otherwise
11130                         // SEE “Related encodings”;
11131                 uint32_t type = Bits32 (opcode, 11, 8);
11132                 uint32_t align = Bits32 (opcode, 5, 4);
11133                 if (type == 7) // '0111'
11134                 {
11135                     regs = 1;
11136                     if (BitIsSet (align, 1))
11137                         return false;
11138                 }
11139                 else if (type == 10) // '1010'
11140                 {
11141                     regs = 2;
11142                     if (align == 3)
11143                         return false;
11144 
11145                 }
11146                 else if (type == 6) // '0110'
11147                 {
11148                     regs = 3;
11149                     if (BitIsSet (align, 1))
11150                         return false;
11151                 }
11152                 else if (type == 2) // '0010'
11153                 {
11154                     regs = 4;
11155                 }
11156                 else
11157                     return false;
11158 
11159                 // alignment = if align == ‘00’ then 1 else 4 << UInt(align);
11160                 if (align == 0)
11161                     alignment = 1;
11162                 else
11163                     alignment = 4 << align;
11164 
11165                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11166                 ebytes = 1 << Bits32 (opcode, 7, 6);
11167                 esize = 8 * ebytes;
11168                 elements = 8 / ebytes;
11169 
11170                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11171                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11172                 n = Bits32 (opcode, 19, 15);
11173                 m = Bits32 (opcode, 3, 0);
11174 
11175                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11176                 wback = (m != 15);
11177                 register_index = ((m != 15) && (m != 13));
11178 
11179                 // if d+regs > 32 then UNPREDICTABLE;
11180                 if ((d + regs) > 32)
11181                     return false;
11182             }
11183                 break;
11184 
11185             default:
11186                 return false;
11187         }
11188 
11189         Register base_reg;
11190         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
11191 
11192         uint32_t Rn = ReadCoreReg (n, &success);
11193         if (!success)
11194             return false;
11195 
11196         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11197         addr_t address = Rn;
11198         if ((address % alignment) != 0)
11199             return false;
11200 
11201         EmulateInstruction::Context context;
11202         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11203         if (wback)
11204         {
11205             uint32_t Rm = ReadCoreReg (m, &success);
11206             if (!success)
11207                 return false;
11208 
11209             uint32_t offset;
11210             if (register_index)
11211                 offset = Rm;
11212             else
11213                 offset = 8 * regs;
11214 
11215             uint32_t value = Rn + offset;
11216             context.type = eContextAdjustBaseRegister;
11217             context.SetRegisterPlusOffset (base_reg, offset);
11218 
11219             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11220                 return false;
11221 
11222         }
11223 
11224         // for r = 0 to regs-1
11225         for (int r = 0; r < regs; ++r)
11226         {
11227             // for e = 0 to elements-1
11228             uint64_t assembled_data = 0;
11229             for (int e = 0; e < elements; ++e)
11230             {
11231                 // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11232                 context.type = eContextRegisterLoad;
11233                 context.SetRegisterPlusOffset (base_reg, address - Rn);
11234                 uint64_t data = MemURead (context, address, ebytes, 0, &success);
11235                 if (!success)
11236                     return false;
11237 
11238                 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data
11239 
11240                 // address = address + ebytes;
11241                 address = address + ebytes;
11242             }
11243             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data))
11244                 return false;
11245         }
11246     }
11247     return true;
11248 }
11249 
11250 // A8.6.308 VLD1 (single element to one lane)
11251 //
11252 bool
11253 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding)
11254 {
11255 #if 0
11256     if ConditionPassed() then
11257         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11258         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11259         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11260         Elem[D[d],index,esize] = MemU[address,ebytes];
11261 #endif
11262 
11263     bool success = false;
11264 
11265     if (ConditionPassed (opcode))
11266     {
11267         uint32_t ebytes;
11268         uint32_t esize;
11269         uint32_t index;
11270         uint32_t alignment;
11271         uint32_t d;
11272         uint32_t n;
11273         uint32_t m;
11274         bool wback;
11275         bool register_index;
11276 
11277         switch (encoding)
11278         {
11279             case eEncodingT1:
11280             case eEncodingA1:
11281             {
11282                 uint32_t size = Bits32 (opcode, 11, 10);
11283                 uint32_t index_align = Bits32 (opcode, 7, 4);
11284                 // if size == ‘11’ then SEE VLD1 (single element to all lanes);
11285                 if (size == 3)
11286                    return EmulateVLD1SingleAll (opcode, encoding);
11287                 // case size of
11288                 if (size == 0) // when '00'
11289                 {
11290                     // if index_align<0> != ‘0’ then UNDEFINED;
11291                     if (BitIsClear (index_align, 0))
11292                         return false;
11293 
11294                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11295                     ebytes = 1;
11296                     esize = 8;
11297                     index = Bits32 (index_align, 3, 1);
11298                     alignment = 1;
11299                 }
11300                 else if (size == 1) // when ‘01’
11301                 {
11302                     // if index_align<1> != ‘0’ then UNDEFINED;
11303                     if (BitIsClear (index_align, 1))
11304                         return false;
11305 
11306                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11307                     ebytes = 2;
11308                     esize = 16;
11309                     index = Bits32 (index_align, 3, 2);
11310 
11311                     // alignment = if index_align<0> == ‘0’ then 1 else 2;
11312                     if (BitIsClear (index_align, 0))
11313                         alignment = 1;
11314                     else
11315                         alignment = 2;
11316                 }
11317                 else if (size == 2) // when ‘10’
11318                 {
11319                     // if index_align<2> != ‘0’ then UNDEFINED;
11320                     if (BitIsClear (index_align, 2))
11321                         return false;
11322 
11323                     // if index_align<1:0> != ‘00’ && index_align<1:0> != ‘11’ then UNDEFINED;
11324                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11325                         return false;
11326 
11327                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11328                     ebytes = 4;
11329                     esize = 32;
11330                     index = Bit32 (index_align, 3);
11331 
11332                     // alignment = if index_align<1:0> == ‘00’ then 1 else 4;
11333                     if (Bits32 (index_align, 1, 0) == 0)
11334                         alignment = 1;
11335                     else
11336                         alignment = 4;
11337                 }
11338                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11339                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11340                 n = Bits32 (opcode, 19, 16);
11341                 m = Bits32 (opcode, 3, 0);
11342 
11343                 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
11344                 wback = (m != 15);
11345                 register_index = ((m != 15) && (m != 13));
11346 
11347                 if (n == 15)
11348                     return false;
11349 
11350             }
11351                 break;
11352 
11353             default:
11354                 return false;
11355         }
11356 
11357         Register base_reg;
11358         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
11359 
11360         uint32_t Rn = ReadCoreReg (n, &success);
11361         if (!success)
11362             return false;
11363 
11364         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11365         addr_t address = Rn;
11366         if ((address % alignment) != 0)
11367             return false;
11368 
11369         EmulateInstruction::Context context;
11370         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11371         if (wback)
11372         {
11373             uint32_t Rm = ReadCoreReg (m, &success);
11374             if (!success)
11375                 return false;
11376 
11377             uint32_t offset;
11378             if (register_index)
11379                 offset = Rm;
11380             else
11381                 offset = ebytes;
11382 
11383             uint32_t value = Rn + offset;
11384 
11385             context.type = eContextAdjustBaseRegister;
11386             context.SetRegisterPlusOffset (base_reg, offset);
11387 
11388             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11389                 return false;
11390         }
11391 
11392         // Elem[D[d],index,esize] = MemU[address,ebytes];
11393         uint32_t element = MemURead (context, address, esize, 0, &success);
11394         if (!success)
11395             return false;
11396 
11397         element = element << (index * esize);
11398 
11399         uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11400         if (!success)
11401             return false;
11402 
11403         uint64_t all_ones = -1;
11404         uint64_t mask = all_ones << ((index+1) * esize);  // mask is all 1's to left of where 'element' goes, & all 0's
11405                                                           // at element & to the right of element.
11406         if (index > 0)
11407             mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes.
11408                                                                      // now mask should be 0's where element goes & 1's
11409                                                                      // everywhere else.
11410 
11411         uint64_t masked_reg = reg_data & mask;  // Take original reg value & zero out 'element' bits
11412         reg_data = masked_reg & element;        // Put 'element' into those bits in reg_data.
11413 
11414         context.type = eContextRegisterLoad;
11415         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data))
11416             return false;
11417     }
11418     return true;
11419 }
11420 
11421 // A8.6.391 VST1 (multiple single elements)
11422 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four regsiters, without
11423 // interleaving.  Every element of each register is stored.
11424 bool
11425 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding)
11426 {
11427 #if 0
11428     if ConditionPassed() then
11429         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11430         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11431         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11432         for r = 0 to regs-1
11433             for e = 0 to elements-1
11434                 MemU[address,ebytes] = Elem[D[d+r],e,esize];
11435                 address = address + ebytes;
11436 #endif
11437 
11438     bool success = false;
11439 
11440     if (ConditionPassed (opcode))
11441     {
11442         uint32_t regs;
11443         uint32_t alignment;
11444         uint32_t ebytes;
11445         uint32_t esize;
11446         uint32_t elements;
11447         uint32_t d;
11448         uint32_t n;
11449         uint32_t m;
11450         bool wback;
11451         bool register_index;
11452 
11453         switch (encoding)
11454         {
11455             case eEncodingT1:
11456             case eEncodingA1:
11457             {
11458                 uint32_t type = Bits32 (opcode, 11, 8);
11459                 uint32_t align = Bits32 (opcode, 5, 4);
11460 
11461                 // case type of
11462                 if (type == 7)    // when ‘0111’
11463                 {
11464                     // regs = 1; if align<1> == ‘1’ then UNDEFINED;
11465                     regs = 1;
11466                     if (BitIsSet (align, 1))
11467                         return false;
11468                 }
11469                 else if (type == 10) // when ‘1010’
11470                 {
11471                     // regs = 2; if align == ‘11’ then UNDEFINED;
11472                     regs = 2;
11473                     if (align == 3)
11474                         return false;
11475                 }
11476                 else if (type == 6) // when ‘0110’
11477                 {
11478                     // regs = 3; if align<1> == ‘1’ then UNDEFINED;
11479                     regs = 3;
11480                     if (BitIsSet (align, 1))
11481                         return false;
11482                 }
11483                 else if (type == 2) // when ‘0010’
11484                     // regs = 4;
11485                     regs = 4;
11486                 else // otherwise
11487                     // SEE “Related encodings”;
11488                     return false;
11489 
11490                 // alignment = if align == ‘00’ then 1 else 4 << UInt(align);
11491                 if (align == 0)
11492                     alignment = 0;
11493                 else
11494                     alignment = 4 << align;
11495 
11496                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11497                 ebytes = 1 << Bits32 (opcode,7, 6);
11498                 esize = 8 * ebytes;
11499                 elements = 8 / ebytes;
11500 
11501                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11502                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11503                 n = Bits32 (opcode, 19, 16);
11504                 m = Bits32 (opcode, 3, 0);
11505 
11506                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11507                 wback = (m != 15);
11508                 register_index = ((m != 15) && (m != 13));
11509 
11510                 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11511                 if ((d + regs) > 32)
11512                     return false;
11513 
11514                 if (n == 15)
11515                     return false;
11516 
11517             }
11518                 break;
11519 
11520             default:
11521                 return false;
11522         }
11523 
11524         Register base_reg;
11525         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
11526 
11527         uint32_t Rn = ReadCoreReg (n, &success);
11528         if (!success)
11529             return false;
11530 
11531         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11532         addr_t address = Rn;
11533         if ((address % alignment) != 0)
11534             return false;
11535 
11536         EmulateInstruction::Context context;
11537         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11538         if (wback)
11539         {
11540             uint32_t Rm = ReadCoreReg (m, &success);
11541             if (!success)
11542                 return false;
11543 
11544             uint32_t offset;
11545             if (register_index)
11546                 offset = Rm;
11547             else
11548                 offset = 8 * regs;
11549 
11550             context.type = eContextAdjustBaseRegister;
11551             context.SetRegisterPlusOffset (base_reg, offset);
11552 
11553             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11554                 return false;
11555         }
11556 
11557         context.type = eContextRegisterStore;
11558         Register data_reg;
11559         data_reg.SetRegister (eRegisterKindDWARF, 0);
11560         // for r = 0 to regs-1
11561         for (int r = 0; r < regs; ++r)
11562         {
11563             data_reg.num = dwarf_d0 + d + r;
11564             uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
11565             if (!success)
11566                 return false;
11567 
11568              // for e = 0 to elements-1
11569             for (int e = 0; e < elements; ++e)
11570             {
11571                 // MemU[address,ebytes] = Elem[D[d+r],e,esize];
11572                 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize);
11573 
11574                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11575                 if (!MemUWrite (context, address, word, ebytes))
11576                     return false;
11577 
11578                 // address = address + ebytes;
11579                 address = address + ebytes;
11580             }
11581         }
11582     }
11583     return true;
11584 }
11585 
11586 // A8.6.392 VST1 (single element from one lane)
11587 // This instruction stores one element to memory from one element of a register.
11588 bool
11589 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding)
11590 {
11591 #if 0
11592     if ConditionPassed() then
11593         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11594         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11595         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11596         MemU[address,ebytes] = Elem[D[d],index,esize];
11597 #endif
11598 
11599     bool success = false;
11600 
11601     if (ConditionPassed (opcode))
11602     {
11603         uint32_t ebytes;
11604         uint32_t esize;
11605         uint32_t index;
11606         uint32_t alignment;
11607         uint32_t d;
11608         uint32_t n;
11609         uint32_t m;
11610         bool wback;
11611         bool register_index;
11612 
11613         switch (encoding)
11614         {
11615             case eEncodingT1:
11616             case eEncodingA1:
11617             {
11618                 uint32_t size = Bits32 (opcode, 11, 10);
11619                 uint32_t index_align = Bits32 (opcode, 7, 4);
11620 
11621                 // if size == ‘11’ then UNDEFINED;
11622                 if (size == 3)
11623                     return false;
11624 
11625                 // case size of
11626                 if (size == 0) // when ‘00’
11627                 {
11628                     // if index_align<0> != ‘0’ then UNDEFINED;
11629                     if (BitIsClear (index_align, 0))
11630                         return false;
11631                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11632                     ebytes = 1;
11633                     esize = 8;
11634                     index = Bits32 (index_align, 3, 1);
11635                     alignment = 1;
11636                 }
11637                 else if (size == 1) // when ‘01’
11638                 {
11639                     // if index_align<1> != ‘0’ then UNDEFINED;
11640                     if (BitIsClear (index_align, 1))
11641                         return false;
11642 
11643                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11644                     ebytes = 2;
11645                     esize = 16;
11646                     index = Bits32 (index_align, 3, 2);
11647 
11648                     // alignment = if index_align<0> == ‘0’ then 1 else 2;
11649                     if (BitIsClear (index_align, 0))
11650                         alignment = 1;
11651                     else
11652                         alignment = 2;
11653                 }
11654                 else if (size == 2) // when ‘10’
11655                 {
11656                     // if index_align<2> != ‘0’ then UNDEFINED;
11657                     if (BitIsClear (index_align, 2))
11658                         return false;
11659 
11660                     // if index_align<1:0> != ‘00’ && index_align<1:0> != ‘11’ then UNDEFINED;
11661                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11662                         return false;
11663 
11664                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11665                     ebytes = 4;
11666                     esize = 32;
11667                     index = Bit32 (index_align, 3);
11668 
11669                     // alignment = if index_align<1:0> == ‘00’ then 1 else 4;
11670                     if (Bits32 (index_align, 1, 0) == 0)
11671                         alignment = 1;
11672                     else
11673                         alignment = 4;
11674                 }
11675                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11676                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11677                 n = Bits32 (opcode, 19, 16);
11678                 m = Bits32 (opcode, 3, 0);
11679 
11680                 // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15 then UNPREDICTABLE;
11681                 wback = (m != 15);
11682                 register_index = ((m != 15) && (m != 13));
11683 
11684                 if (n == 15)
11685                     return false;
11686             }
11687                 break;
11688 
11689             default:
11690                 return false;
11691         }
11692 
11693         Register base_reg;
11694         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 + n);
11695 
11696         uint32_t Rn = ReadCoreReg (n, &success);
11697         if (!success)
11698             return false;
11699 
11700         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11701         addr_t address = Rn;
11702         if ((address % alignment) != 0)
11703             return false;
11704 
11705         EmulateInstruction::Context context;
11706         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11707         if (wback)
11708         {
11709             uint32_t Rm = ReadCoreReg (m, &success);
11710             if (!success)
11711                 return false;
11712 
11713             uint32_t offset;
11714             if (register_index)
11715                 offset = Rm;
11716             else
11717                 offset = ebytes;
11718 
11719             context.type = eContextAdjustBaseRegister;
11720             context.SetRegisterPlusOffset (base_reg, offset);
11721 
11722             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11723                 return false;
11724         }
11725 
11726         // MemU[address,ebytes] = Elem[D[d],index,esize];
11727         uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11728         if (!success)
11729             return false;
11730 
11731         uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1,  index * esize);
11732 
11733         Register data_reg;
11734         data_reg.SetRegister (eRegisterKindDWARF, dwarf_d0 + d);
11735         context.type = eContextRegisterStore;
11736         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11737 
11738         if (!MemUWrite (context, address, word, ebytes))
11739             return false;
11740     }
11741     return true;
11742 }
11743 
11744 // A8.6.309 VLD1 (single element to all lanes)
11745 // This instruction loads one element from memory into every element of one or two vectors.
11746 bool
11747 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding)
11748 {
11749 #if 0
11750     if ConditionPassed() then
11751         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11752         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11753         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11754         replicated_element = Replicate(MemU[address,ebytes], elements);
11755         for r = 0 to regs-1
11756             D[d+r] = replicated_element;
11757 #endif
11758 
11759     bool success = false;
11760 
11761     if (ConditionPassed (opcode))
11762     {
11763         uint32_t ebytes;
11764         uint32_t elements;
11765         uint32_t regs;
11766         uint32_t alignment;
11767         uint32_t d;
11768         uint32_t n;
11769         uint32_t m;
11770         bool wback;
11771         bool register_index;
11772 
11773         switch (encoding)
11774         {
11775             case eEncodingT1:
11776             case eEncodingA1:
11777             {
11778                 //if size == ‘11’ || (size == ‘00’ && a == ‘1’) then UNDEFINED;
11779                 uint32_t size = Bits32 (opcode, 7, 6);
11780                 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4)))
11781                     return false;
11782 
11783                 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == ‘0’ then 1 else 2;
11784                 ebytes = 1 << size;
11785                 elements = 8 / ebytes;
11786                 if (BitIsClear (opcode, 5))
11787                     regs = 1;
11788                 else
11789                     regs = 2;
11790 
11791                 //alignment = if a == ‘0’ then 1 else ebytes;
11792                 if (BitIsClear (opcode, 4))
11793                     alignment = 1;
11794                 else
11795                     alignment = ebytes;
11796 
11797                 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11798                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11799                 n = Bits32 (opcode, 19, 16);
11800                 m = Bits32 (opcode, 3, 0);
11801 
11802                 //wback = (m != 15); register_index = (m != 15 && m != 13);
11803                 wback = (m != 15);
11804                 register_index = ((m != 15) && (m != 13));
11805 
11806                 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11807                 if ((d + regs) > 32)
11808                     return false;
11809 
11810                 if (n == 15)
11811                     return false;
11812             }
11813                 break;
11814 
11815             default:
11816                 break;
11817         }
11818 
11819         Register base_reg;
11820         base_reg.SetRegister (eRegisterKindDWARF, dwarf_r0 +n);
11821 
11822         uint32_t Rn = ReadCoreReg (n, &success);
11823         if (!success)
11824             return false;
11825 
11826         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11827         addr_t address = Rn;
11828         if ((address % alignment) != 0)
11829             return false;
11830 
11831         EmulateInstruction::Context context;
11832         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11833         if (wback)
11834         {
11835             uint32_t Rm = ReadCoreReg (m, &success);
11836             if (!success)
11837                 return false;
11838 
11839             uint32_t offset;
11840             if (register_index)
11841                 offset = Rm;
11842             else
11843                 offset = ebytes;
11844 
11845             context.type = eContextAdjustBaseRegister;
11846             context.SetRegisterPlusOffset (base_reg, offset);
11847 
11848             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11849                 return false;
11850         }
11851 
11852         // replicated_element = Replicate(MemU[address,ebytes], elements);
11853 
11854         context.type = eContextRegisterLoad;
11855         uint64_t word = MemURead (context, address, ebytes, 0, &success);
11856         if (!success)
11857             return false;
11858 
11859         uint64_t replicated_element;
11860         uint32_t esize = ebytes * 8;
11861         for (int e = 0; e < elements; ++e)
11862             replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0);
11863 
11864         // for r = 0 to regs-1
11865         for (int r = 0; r < regs; ++r)
11866         {
11867             // D[d+r] = replicated_element;
11868             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element))
11869                 return false;
11870         }
11871     }
11872     return true;
11873 }
11874 
11875 // B6.2.13 SUBS PC, LR and related instructions
11876 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack.  It subtracts the
11877 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR.
11878 bool
11879 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding)
11880 {
11881 #if 0
11882     if ConditionPassed() then
11883         EncodingSpecificOperations();
11884         if CurrentInstrSet() == InstrSet_ThumbEE then
11885             UNPREDICTABLE;
11886         operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
11887         case opcode of
11888             when0000result = R[n] AND operand2; // AND
11889             when0001result = R[n] EOR operand2; // EOR
11890             when0010’ (result, -, -) = AddWithCarry(R[n], NOT(operand2), ‘1’); // SUB
11891             when0011’ (result, -, -) = AddWithCarry(NOT(R[n]), operand2, ‘1’); // RSB
11892             when0100’ (result, -, -) = AddWithCarry(R[n], operand2, ‘0’); // ADD
11893             when0101’ (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
11894             when0110’ (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
11895             when0111’ (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
11896             when1100result = R[n] OR operand2; // ORR
11897             when1101result = operand2; // MOV
11898             when1110result = R[n] AND NOT(operand2); // BIC
11899             when1111result = NOT(operand2); // MVN
11900         CPSRWriteByInstr(SPSR[], ‘1111’, TRUE);
11901         BranchWritePC(result);
11902 #endif
11903 
11904     bool success = false;
11905 
11906     if (ConditionPassed (opcode))
11907     {
11908         uint32_t n;
11909         uint32_t m;
11910         uint32_t imm32;
11911         bool register_form;
11912         ARM_ShifterType shift_t;
11913         uint32_t shift_n;
11914         uint32_t code;
11915 
11916         switch (encoding)
11917         {
11918             case eEncodingT1:
11919                 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
11920                 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = ‘0010’; // = SUB
11921                 n = 14;
11922                 imm32 = Bits32 (opcode, 7, 0);
11923                 register_form = false;
11924                 code = 2;
11925 
11926                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
11927                 if (InITBlock() && !LastInITBlock())
11928                     return false;
11929 
11930                 break;
11931 
11932             case eEncodingA1:
11933                 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
11934                 n = Bits32 (opcode, 19, 16);
11935                 imm32 = ARMExpandImm (opcode);
11936                 register_form = false;
11937                 code = Bits32 (opcode, 24, 21);
11938 
11939                 break;
11940 
11941             case eEncodingA2:
11942                 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
11943                 n = Bits32 (opcode, 19, 16);
11944                 m = Bits32 (opcode, 3, 0);
11945                 register_form = true;
11946 
11947                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
11948                 shift_n = DecodeImmShiftARM (opcode, shift_t);
11949 
11950                 break;
11951 
11952             default:
11953                 return false;
11954         }
11955 
11956         // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
11957         uint32_t operand2;
11958         if (register_form)
11959         {
11960             uint32_t Rm = ReadCoreReg (m, &success);
11961             if (!success)
11962                 return false;
11963 
11964             operand2 = Shift (Rm, shift_t, shift_n, APSR_C);
11965 
11966         }
11967         else
11968         {
11969             operand2 = imm32;
11970         }
11971 
11972         uint32_t Rn = ReadCoreReg (n, &success);
11973         if (!success)
11974             return false;
11975 
11976         AddWithCarryResult result;
11977 
11978         // case opcode of
11979         switch (code)
11980         {
11981             case 0: // when ‘0000’
11982                 // result = R[n] AND operand2; // AND
11983                 result.result = Rn & operand2;
11984                 break;
11985 
11986             case 1: // when ‘0001’
11987                 // result = R[n] EOR operand2; // EOR
11988                 result.result = Rn ^ operand2;
11989                 break;
11990 
11991             case 2: // when ‘0010’
11992                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), ‘1’); // SUB
11993                 result = AddWithCarry (Rn, ~(operand2), 1);
11994                 break;
11995 
11996             case 3: // when ‘0011’
11997                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, ‘1’); // RSB
11998                 result = AddWithCarry (~(Rn), operand2, 1);
11999                 break;
12000 
12001             case 4: // when ‘0100’
12002                 // (result, -, -) = AddWithCarry(R[n], operand2, ‘0’); // ADD
12003                 result = AddWithCarry (Rn, operand2, 0);
12004                 break;
12005 
12006             case 5: // when ‘0101’
12007                 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12008                 result = AddWithCarry (Rn, operand2, APSR_C);
12009                 break;
12010 
12011             case 6: // when ‘0110’
12012                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12013                 result = AddWithCarry (Rn, ~(operand2), APSR_C);
12014                 break;
12015 
12016             case 7: // when ‘0111’
12017                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12018                 result = AddWithCarry (~(Rn), operand2, APSR_C);
12019                 break;
12020 
12021             case 10: // when ‘1100’
12022                 // result = R[n] OR operand2; // ORR
12023                 result.result = Rn | operand2;
12024                 break;
12025 
12026             case 11: // when ‘1101’
12027                 // result = operand2; // MOV
12028                 result.result = operand2;
12029                 break;
12030 
12031             case 12: // when ‘1110’
12032                 // result = R[n] AND NOT(operand2); // BIC
12033                 result.result = Rn & ~(operand2);
12034                 break;
12035 
12036             case 15: // when ‘1111’
12037                 // result = NOT(operand2); // MVN
12038                 result.result = ~(operand2);
12039                 break;
12040 
12041             default:
12042                 return false;
12043         }
12044         // CPSRWriteByInstr(SPSR[], ‘1111’, TRUE);
12045 
12046         // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for
12047         // the best.
12048         uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12049         if (!success)
12050             return false;
12051 
12052         CPSRWriteByInstr (spsr, 15, true);
12053 
12054         // BranchWritePC(result);
12055         EmulateInstruction::Context context;
12056         context.type = eContextAdjustPC;
12057         context.SetImmediate (result.result);
12058 
12059         BranchWritePC (context, result.result);
12060     }
12061     return true;
12062 }
12063 
12064 EmulateInstructionARM::ARMOpcode*
12065 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode)
12066 {
12067     static ARMOpcode
12068     g_arm_opcodes[] =
12069     {
12070         //----------------------------------------------------------------------
12071         // Prologue instructions
12072         //----------------------------------------------------------------------
12073 
12074         // push register(s)
12075         { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12076         { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
12077 
12078         // set r7 to point to a stack offset
12079         { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
12080         { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12081         // copy the stack pointer to ip
12082         { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
12083         { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
12084         { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12085 
12086         // adjust the stack pointer
12087         { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12088         { 0x0fef0010, 0x004d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12089 
12090         // push one register
12091         // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12092         { 0x0e5f0000, 0x040d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
12093 
12094         // vector push consecutive extension register(s)
12095         { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12096         { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12097 
12098         //----------------------------------------------------------------------
12099         // Epilogue instructions
12100         //----------------------------------------------------------------------
12101 
12102         { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12103         { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12104         { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12105         { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12106 
12107         //----------------------------------------------------------------------
12108         // Supervisor Call (previously Software Interrupt)
12109         //----------------------------------------------------------------------
12110         { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12111 
12112         //----------------------------------------------------------------------
12113         // Branch instructions
12114         //----------------------------------------------------------------------
12115         { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
12116         // To resolve ambiguity, "blx <label>" should come before "bl <label>".
12117         { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12118         { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12119         { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12120         // for example, "bx lr"
12121         { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12122         // bxj
12123         { 0x0ffffff0, 0x012fff20, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12124 
12125         //----------------------------------------------------------------------
12126         // Data-processing instructions
12127         //----------------------------------------------------------------------
12128         // adc (immediate)
12129         { 0x0fe00000, 0x02a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12130         // adc (register)
12131         { 0x0fe00010, 0x00a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12132         // add (immediate)
12133         { 0x0fe00000, 0x02800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
12134         // add (register)
12135         { 0x0fe00010, 0x00800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12136         // add (register-shifted register)
12137         { 0x0fe00090, 0x00800010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12138         // adr
12139         { 0x0fff0000, 0x028f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12140         { 0x0fff0000, 0x024f0000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12141         // and (immediate)
12142         { 0x0fe00000, 0x02000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12143         // and (register)
12144         { 0x0fe00010, 0x00000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12145         // bic (immediate)
12146         { 0x0fe00000, 0x03c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12147         // bic (register)
12148         { 0x0fe00010, 0x01c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12149         // eor (immediate)
12150         { 0x0fe00000, 0x02200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12151         // eor (register)
12152         { 0x0fe00010, 0x00200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12153         // orr (immediate)
12154         { 0x0fe00000, 0x03800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12155         // orr (register)
12156         { 0x0fe00010, 0x01800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12157         // rsb (immediate)
12158         { 0x0fe00000, 0x02600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12159         // rsb (register)
12160         { 0x0fe00010, 0x00600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12161         // rsc (immediate)
12162         { 0x0fe00000, 0x02e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12163         // rsc (register)
12164         { 0x0fe00010, 0x00e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12165         // sbc (immediate)
12166         { 0x0fe00000, 0x02c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12167         // sbc (register)
12168         { 0x0fe00010, 0x00c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12169         // sub (immediate, ARM)
12170         { 0x0fe00000, 0x02400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
12171         // sub (sp minus immediate)
12172         { 0x0fef0000, 0x024d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12173         // sub (register)
12174         { 0x0fe00010, 0x00400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12175         // teq (immediate)
12176         { 0x0ff0f000, 0x03300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12177         // teq (register)
12178         { 0x0ff0f010, 0x01300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12179         // tst (immediate)
12180         { 0x0ff0f000, 0x03100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12181         // tst (register)
12182         { 0x0ff0f010, 0x01100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12183 
12184         // mov (immediate)
12185         { 0x0fef0000, 0x03a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12186         { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
12187         // mov (register)
12188         { 0x0fef0ff0, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12189         // mvn (immediate)
12190         { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12191         // mvn (register)
12192         { 0x0fef0010, 0x01e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12193         // cmn (immediate)
12194         { 0x0ff0f000, 0x03700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12195         // cmn (register)
12196         { 0x0ff0f010, 0x01700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12197         // cmp (immediate)
12198         { 0x0ff0f000, 0x03500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
12199         // cmp (register)
12200         { 0x0ff0f010, 0x01500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
12201         // asr (immediate)
12202         { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
12203         // asr (register)
12204         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
12205         // lsl (immediate)
12206         { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
12207         // lsl (register)
12208         { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
12209         // lsr (immediate)
12210         { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
12211         // lsr (register)
12212         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
12213         // rrx is a special case encoding of ror (immediate)
12214         { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
12215         // ror (immediate)
12216         { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
12217         // ror (register)
12218         { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
12219         // mul
12220         { 0x0fe000f0, 0x00000090, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
12221         { 0x0e10f000, 0x0210f000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" },
12222         { 0x0e10f010, 0x0010f000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" },
12223 
12224         //----------------------------------------------------------------------
12225         // Load instructions
12226         //----------------------------------------------------------------------
12227         { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12228         { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
12229         { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12230         { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
12231         { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
12232         { 0x0e500010, 0x06100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
12233         { 0x0e5f0000, 0x045f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
12234         { 0xfe500010, 0x06500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
12235         { 0x0e5f00f0, 0x005f00b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12236         { 0x0e5000f0, 0x001000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"  },
12237         { 0x0e5000f0, 0x005000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
12238         { 0x0e5f00f0, 0x005f00d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
12239         { 0x0e5000f0, 0x001000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12240         { 0x0e5000f0, 0x005000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
12241         { 0x0e5f00f0, 0x005f00f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12242         { 0x0e5000f0, 0x001000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12243         { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
12244         { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12245         { 0x0e100f00, 0x0c100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12246         { 0x0e100f00, 0x0c100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12247         { 0x0f300f00, 0x0d100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12248         { 0x0f300f00, 0x0d100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12249         { 0xffb00000, 0xf4200000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12250         { 0xffb00300, 0xf4a00000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12251         { 0xffb00f00, 0xf4a00c00, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12252 
12253         //----------------------------------------------------------------------
12254         // Store instructions
12255         //----------------------------------------------------------------------
12256         { 0x0fd00000, 0x08800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12257         { 0x0fd00000, 0x08000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
12258         { 0x0fd00000, 0x09000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12259         { 0x0fd00000, 0x09800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
12260         { 0x0e500010, 0x06000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
12261         { 0x0e5000f0, 0x000000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
12262         { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
12263         { 0x0e500000, 0x04400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12264         { 0x0e500000, 0x04000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12265         { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
12266         { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12267         { 0x0e100f00, 0x0c000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12268         { 0x0e100f00, 0x0c000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12269         { 0x0f300f00, 0x0d000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
12270         { 0x0f300f00, 0x0d000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
12271         { 0xffb00000, 0xf4000000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12272         { 0xffb00300, 0xf4800000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12273 
12274         //----------------------------------------------------------------------
12275         // Other instructions
12276         //----------------------------------------------------------------------
12277         { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
12278         { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
12279         { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
12280         { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
12281         { 0xfe500000, 0xf8100000, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
12282 
12283     };
12284     static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode);
12285 
12286     for (size_t i=0; i<k_num_arm_opcodes; ++i)
12287     {
12288         if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value)
12289             return &g_arm_opcodes[i];
12290     }
12291     return NULL;
12292 }
12293 
12294 
12295 EmulateInstructionARM::ARMOpcode*
12296 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode)
12297 {
12298 
12299     static ARMOpcode
12300     g_thumb_opcodes[] =
12301     {
12302         //----------------------------------------------------------------------
12303         // Prologue instructions
12304         //----------------------------------------------------------------------
12305 
12306         // push register(s)
12307         { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12308         { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
12309         { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
12310 
12311         // set r7 to point to a stack offset
12312         { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
12313         // copy the stack pointer to r7
12314         { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
12315         // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
12316         { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
12317 
12318         // PC-relative load into register (see also EmulateADDSPRm)
12319         { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
12320 
12321         // adjust the stack pointer
12322         { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
12323         { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
12324         { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
12325         { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
12326         { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12327 
12328         // vector push consecutive extension register(s)
12329         { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12330         { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12331 
12332         //----------------------------------------------------------------------
12333         // Epilogue instructions
12334         //----------------------------------------------------------------------
12335 
12336         { 0xfffff800, 0x0000a800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
12337         { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
12338         { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12339         { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
12340         { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
12341         { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12342         { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12343 
12344         //----------------------------------------------------------------------
12345         // Supervisor Call (previously Software Interrupt)
12346         //----------------------------------------------------------------------
12347         { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
12348 
12349         //----------------------------------------------------------------------
12350         // If Then makes up to four following instructions conditional.
12351         //----------------------------------------------------------------------
12352         { 0xffffff00, 0x0000bf00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
12353 
12354         //----------------------------------------------------------------------
12355         // Branch instructions
12356         //----------------------------------------------------------------------
12357         // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
12358         { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
12359         { 0xfffff800, 0x0000e000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
12360         { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
12361         { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
12362         // J1 == J2 == 1
12363         { 0xf800d000, 0xf000d000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12364         // J1 == J2 == 1
12365         { 0xf800d001, 0xf000c000, ARMV5_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12366         { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12367         // for example, "bx lr"
12368         { 0xffffff87, 0x00004700, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12369         // bxj
12370         { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12371         // compare and branch
12372         { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
12373         // table branch byte
12374         { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
12375         // table branch halfword
12376         { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
12377 
12378         //----------------------------------------------------------------------
12379         // Data-processing instructions
12380         //----------------------------------------------------------------------
12381         // adc (immediate)
12382         { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
12383         // adc (register)
12384         { 0xffffffc0, 0x00004140, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
12385         { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12386         // add (register)
12387         { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
12388         // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
12389         { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
12390         // adr
12391         { 0xfffff800, 0x0000a000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12392         { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12393         { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12394         // and (immediate)
12395         { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
12396         // and (register)
12397         { 0xffffffc0, 0x00004000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
12398         { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12399         // bic (immediate)
12400         { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
12401         // bic (register)
12402         { 0xffffffc0, 0x00004380, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
12403         { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12404         // eor (immediate)
12405         { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
12406         // eor (register)
12407         { 0xffffffc0, 0x00004040, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
12408         { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12409         // orr (immediate)
12410         { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
12411         // orr (register)
12412         { 0xffffffc0, 0x00004300, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
12413         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12414         // rsb (immediate)
12415         { 0xffffffc0, 0x00004240, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
12416         { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
12417         // rsb (register)
12418         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12419         // sbc (immediate)
12420         { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12421         // sbc (register)
12422         { 0xffffffc0, 0x00004180, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
12423         { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12424         // add (immediate, Thumb)
12425         { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
12426         { 0xfffff800, 0x00003000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
12427         { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
12428         { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
12429         // sub (immediate, Thumb)
12430         { 0xfffffe00, 0x00001e00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
12431         { 0xfffff800, 0x00003800, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
12432         { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
12433         { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
12434         // sub (sp minus immediate)
12435         { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
12436         { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
12437         // sub (register)
12438         { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
12439         { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
12440         // teq (immediate)
12441         { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
12442         // teq (register)
12443         { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12444         // tst (immediate)
12445         { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
12446         // tst (register)
12447         { 0xffffffc0, 0x00004200, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
12448         { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
12449 
12450 
12451         // move from high register to high register
12452         { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
12453         // move from low register to low register
12454         { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
12455         // mov{s}<c>.w <Rd>, <Rm>
12456         { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
12457         // move immediate
12458         { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
12459         { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
12460         { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
12461         // mvn (immediate)
12462         { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
12463         // mvn (register)
12464         { 0xffffffc0, 0x000043c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
12465         { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
12466         // cmn (immediate)
12467         { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12468         // cmn (register)
12469         { 0xffffffc0, 0x000042c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
12470         { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12471         // cmp (immediate)
12472         { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
12473         { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
12474         // cmp (register) (Rn and Rm both from r0-r7)
12475         { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12476         // cmp (register) (Rn and Rm not both from r0-r7)
12477         { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12478         // asr (immediate)
12479         { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
12480         { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
12481         // asr (register)
12482         { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
12483         { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12484         // lsl (immediate)
12485         { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
12486         { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
12487         // lsl (register)
12488         { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
12489         { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
12490         // lsr (immediate)
12491         { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
12492         { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
12493         // lsr (register)
12494         { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
12495         { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12496         // rrx is a special case encoding of ror (immediate)
12497         { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
12498         // ror (immediate)
12499         { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
12500         // ror (register)
12501         { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
12502         { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
12503         // mul
12504         { 0xffffffc0, 0x00004340, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
12505         // mul
12506         { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
12507         { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" },
12508 
12509 
12510         //----------------------------------------------------------------------
12511         // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table;
12512         // otherwise the wrong instructions will be selected.
12513         //----------------------------------------------------------------------
12514 
12515         { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
12516         { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
12517 
12518         //----------------------------------------------------------------------
12519         // Load instructions
12520         //----------------------------------------------------------------------
12521         { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12522         { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
12523         { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12524         { 0xfffff800, 0x00006800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
12525         { 0xfffff800, 0x00009800, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
12526         { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
12527         { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
12528                   // Thumb2 PC-relative load into register
12529         { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
12530         { 0xfffffe00, 0x00005800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
12531         { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
12532         { 0xfffff800, 0x00007800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
12533         { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12534         { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" },
12535         { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
12536         { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
12537         { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
12538         { 0xfffff800, 0x00008800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"  },
12539         { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12540         { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"  },
12541         { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12542         { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
12543         { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12544         { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
12545         { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12546         { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
12547         { 0xfffffe00, 0x00005600, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
12548         { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"  },
12549         { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
12550         { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12551         { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12552         { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
12553         { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12554         { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
12555         { 0xfe100f00, 0xec100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12556         { 0xfe100f00, 0xec100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
12557         { 0xffe00f00, 0xed100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12558         { 0xff300f00, 0xed100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
12559         { 0xffb00000, 0xf9200000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12560         { 0xffb00300, 0xf9a00000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12561         { 0xffb00f00, 0xf9a00c00, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12562 
12563         //----------------------------------------------------------------------
12564         // Store instructions
12565         //----------------------------------------------------------------------
12566         { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12567         { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
12568         { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12569         { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
12570         { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
12571         { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
12572         { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
12573         { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
12574         { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
12575         { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
12576         { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
12577         { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
12578         { 0xfffffe00, 0x00005200, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
12579         { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12580         { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
12581         { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
12582         { 0xfe100f00, 0xec000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12583         { 0xfea00f00, 0xec000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12584         { 0xff300f00, 0xed000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12585         { 0xff300f00, 0xed000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12586         { 0xffb00000, 0xfa000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12587         { 0xffb00300, 0xf9800000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12588 
12589         //----------------------------------------------------------------------
12590         // Other instructions
12591         //----------------------------------------------------------------------
12592         { 0xffffffc0, 0x0000b240, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
12593         { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12594         { 0xffffffc0, 0x0000b200, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
12595         { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12596         { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
12597         { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12598         { 0xffffffc0, 0x0000b280, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
12599         { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12600     };
12601 
12602     const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode);
12603     for (size_t i=0; i<k_num_thumb_opcodes; ++i)
12604     {
12605         if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value)
12606             return &g_thumb_opcodes[i];
12607     }
12608     return NULL;
12609 }
12610 
12611 bool
12612 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
12613 {
12614     m_arch = arch;
12615     m_arm_isa = 0;
12616     const char *arch_cstr = arch.GetArchitectureName ();
12617     if (arch_cstr)
12618     {
12619         if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
12620         else if (0 == ::strcasecmp(arch_cstr, "armv4"))     m_arm_isa = ARMv4;
12621         else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
12622         else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
12623         else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
12624         else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
12625         else if (0 == ::strcasecmp(arch_cstr, "armv6"))     m_arm_isa = ARMv6;
12626         else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
12627         else if (0 == ::strcasecmp(arch_cstr, "armv7"))     m_arm_isa = ARMv7;
12628         else if (0 == ::strcasecmp(arch_cstr, "armv8"))     m_arm_isa = ARMv8;
12629     }
12630     return m_arm_isa != 0;
12631 }
12632 
12633 bool
12634 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr)
12635 {
12636     m_opcode = insn_opcode;
12637 
12638     if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
12639         m_opcode_mode = eModeThumb;
12640 	else
12641 	{
12642 		AddressClass addr_class = inst_addr.GetAddressClass();
12643 
12644     	if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
12645         	m_opcode_mode = eModeARM;
12646     	else if (addr_class == eAddressClassCodeAlternateISA)
12647         	m_opcode_mode = eModeThumb;
12648     	else
12649         	return false;
12650 	}
12651     return true;
12652 }
12653 
12654 bool
12655 EmulateInstructionARM::ReadInstruction ()
12656 {
12657     bool success = false;
12658     m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
12659     if (success)
12660     {
12661         addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
12662         if (success)
12663         {
12664             Context read_inst_context;
12665             read_inst_context.type = eContextReadOpcode;
12666             read_inst_context.SetNoArgs ();
12667 
12668             if (m_opcode_cpsr & MASK_CPSR_T)
12669             {
12670                 m_opcode_mode = eModeThumb;
12671                 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
12672 
12673                 if (success)
12674                 {
12675                     if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
12676                     {
12677                         m_opcode.SetOpcode16 (thumb_opcode);
12678                     }
12679                     else
12680                     {
12681                         m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success));
12682                     }
12683                 }
12684             }
12685             else
12686             {
12687                 m_opcode_mode = eModeARM;
12688                 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success));
12689             }
12690         }
12691     }
12692     if (!success)
12693     {
12694         m_opcode_mode = eModeInvalid;
12695         m_opcode_pc = LLDB_INVALID_ADDRESS;
12696     }
12697     return success;
12698 }
12699 
12700 uint32_t
12701 EmulateInstructionARM::ArchVersion ()
12702 {
12703     return m_arm_isa;
12704 }
12705 
12706 bool
12707 EmulateInstructionARM::ConditionPassed (const uint32_t opcode)
12708 {
12709 
12710     const uint32_t cond = CurrentCond (opcode);
12711 
12712     if (cond == UINT32_MAX)
12713         return false;
12714 
12715     bool result = false;
12716     switch (UnsignedBits(cond, 3, 1))
12717     {
12718     case 0:
12719 		if (m_opcode_cpsr == 0)
12720 			return true;
12721 		result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
12722 		break;
12723     case 1:
12724  		if (m_opcode_cpsr == 0)
12725 			return true;
12726 		result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
12727 		break;
12728     case 2:
12729  		if (m_opcode_cpsr == 0)
12730 			return true;
12731 		result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
12732 		break;
12733     case 3:
12734  		if (m_opcode_cpsr == 0)
12735 			return true;
12736 		result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
12737 		break;
12738     case 4:
12739  		if (m_opcode_cpsr == 0)
12740 			return true;
12741 		result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12742 		break;
12743     case 5:
12744   		if (m_opcode_cpsr == 0)
12745 			return true;
12746        	else
12747 		{
12748             bool n = (m_opcode_cpsr & MASK_CPSR_N);
12749             bool v = (m_opcode_cpsr & MASK_CPSR_V);
12750             result = n == v;
12751         }
12752         break;
12753     case 6:
12754   		if (m_opcode_cpsr == 0)
12755 			return true;
12756        	else
12757 		{
12758             bool n = (m_opcode_cpsr & MASK_CPSR_N);
12759             bool v = (m_opcode_cpsr & MASK_CPSR_V);
12760             result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12761         }
12762         break;
12763     case 7:
12764         result = true;
12765         break;
12766     }
12767 
12768     if (cond & 1)
12769         result = !result;
12770     return result;
12771 }
12772 
12773 uint32_t
12774 EmulateInstructionARM::CurrentCond (const uint32_t opcode)
12775 {
12776     switch (m_opcode_mode)
12777     {
12778     default:
12779     case eModeInvalid:
12780         break;
12781 
12782     case eModeARM:
12783         return UnsignedBits(opcode, 31, 28);
12784 
12785     case eModeThumb:
12786         // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
12787         // 'cond' field of the encoding.
12788         {
12789             const uint32_t byte_size = m_opcode.GetByteSize();
12790             if (byte_size == 2)
12791             {
12792                 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f)
12793                     return Bits32(opcode, 11, 7);
12794             }
12795             else
12796             {
12797                 assert (byte_size == 4);
12798                 if (Bits32(opcode, 31, 27) == 0x1e &&
12799                     Bits32(opcode, 15, 14) == 0x02 &&
12800                     Bits32(opcode, 12, 12) == 0x00 &&
12801                     Bits32(opcode, 25, 22) <= 0x0d)
12802                 {
12803                     return Bits32(opcode, 25, 22);
12804                 }
12805             }
12806 
12807             return m_it_session.GetCond();
12808         }
12809     }
12810     return UINT32_MAX;  // Return invalid value
12811 }
12812 
12813 bool
12814 EmulateInstructionARM::InITBlock()
12815 {
12816     return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
12817 }
12818 
12819 bool
12820 EmulateInstructionARM::LastInITBlock()
12821 {
12822     return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
12823 }
12824 
12825 bool
12826 EmulateInstructionARM::BadMode (uint32_t mode)
12827 {
12828 
12829     switch (mode)
12830     {
12831         case 16: return false; // '10000'
12832         case 17: return false; // '10001'
12833         case 18: return false; // '10010'
12834         case 19: return false; // '10011'
12835         case 22: return false; // '10110'
12836         case 23: return false; // '10111'
12837         case 27: return false; // '11011'
12838         case 31: return false; // '11111'
12839         default: return true;
12840     }
12841     return true;
12842 }
12843 
12844 bool
12845 EmulateInstructionARM::CurrentModeIsPrivileged ()
12846 {
12847     uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
12848 
12849     if (BadMode (mode))
12850         return false;
12851 
12852     if (mode == 16)
12853                   return false;
12854 
12855     return true;
12856 }
12857 
12858 void
12859 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
12860 {
12861     bool privileged = CurrentModeIsPrivileged();
12862 
12863     uint32_t tmp_cpsr = 0;
12864 
12865     tmp_cpsr = tmp_cpsr | (Bits32 (m_opcode_cpsr, 23, 20) << 20);
12866 
12867     if (BitIsSet (bytemask, 3))
12868     {
12869         tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
12870         if (affect_execstate)
12871             tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
12872     }
12873 
12874     if (BitIsSet (bytemask, 2))
12875     {
12876         tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
12877     }
12878 
12879     if (BitIsSet (bytemask, 1))
12880     {
12881         if (affect_execstate)
12882             tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
12883         tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
12884         if (privileged)
12885             tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
12886     }
12887 
12888     if (BitIsSet (bytemask, 0))
12889     {
12890         if (privileged)
12891             tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
12892         if (affect_execstate)
12893             tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
12894         if (privileged)
12895             tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
12896     }
12897 
12898     m_opcode_cpsr = tmp_cpsr;
12899 }
12900 
12901 
12902 bool
12903 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
12904 {
12905     addr_t target;
12906 
12907     // Check the current instruction set.
12908     if (CurrentInstrSet() == eModeARM)
12909         target = addr & 0xfffffffc;
12910     else
12911         target = addr & 0xfffffffe;
12912 
12913     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
12914         return false;
12915 
12916     return true;
12917 }
12918 
12919 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
12920 bool
12921 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
12922 {
12923     addr_t target;
12924     // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
12925     // we want to record it and issue a WriteRegister callback so the clients
12926     // can track the mode changes accordingly.
12927     bool cpsr_changed = false;
12928 
12929     if (BitIsSet(addr, 0))
12930     {
12931         if (CurrentInstrSet() != eModeThumb)
12932         {
12933             SelectInstrSet(eModeThumb);
12934             cpsr_changed = true;
12935         }
12936         target = addr & 0xfffffffe;
12937         context.SetMode (eModeThumb);
12938     }
12939     else if (BitIsClear(addr, 1))
12940     {
12941         if (CurrentInstrSet() != eModeARM)
12942         {
12943             SelectInstrSet(eModeARM);
12944             cpsr_changed = true;
12945         }
12946         target = addr & 0xfffffffc;
12947         context.SetMode (eModeARM);
12948     }
12949     else
12950         return false; // address<1:0> == '10' => UNPREDICTABLE
12951 
12952     if (cpsr_changed)
12953     {
12954         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
12955             return false;
12956     }
12957     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
12958         return false;
12959 
12960     return true;
12961 }
12962 
12963 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
12964 bool
12965 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
12966 {
12967     if (ArchVersion() >= ARMv5T)
12968         return BXWritePC(context, addr);
12969     else
12970         return BranchWritePC((const Context)context, addr);
12971 }
12972 
12973 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
12974 bool
12975 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
12976 {
12977     if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
12978         return BXWritePC(context, addr);
12979     else
12980         return BranchWritePC((const Context)context, addr);
12981 }
12982 
12983 EmulateInstructionARM::Mode
12984 EmulateInstructionARM::CurrentInstrSet ()
12985 {
12986     return m_opcode_mode;
12987 }
12988 
12989 // Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
12990 // ReadInstruction() is performed.  This function has a side effect of updating
12991 // the m_new_inst_cpsr member variable if necessary.
12992 bool
12993 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
12994 {
12995     m_new_inst_cpsr = m_opcode_cpsr;
12996     switch (arm_or_thumb)
12997     {
12998     default:
12999         return false;
13000     eModeARM:
13001         // Clear the T bit.
13002         m_new_inst_cpsr &= ~MASK_CPSR_T;
13003         break;
13004     eModeThumb:
13005         // Set the T bit.
13006         m_new_inst_cpsr |= MASK_CPSR_T;
13007         break;
13008     }
13009     return true;
13010 }
13011 
13012 // This function returns TRUE if the processor currently provides support for
13013 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
13014 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
13015 bool
13016 EmulateInstructionARM::UnalignedSupport()
13017 {
13018     return (ArchVersion() >= ARMv7);
13019 }
13020 
13021 // The main addition and subtraction instructions can produce status information
13022 // about both unsigned carry and signed overflow conditions.  This status
13023 // information can be used to synthesize multi-word additions and subtractions.
13024 EmulateInstructionARM::AddWithCarryResult
13025 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
13026 {
13027     uint32_t result;
13028     uint8_t carry_out;
13029     uint8_t overflow;
13030 
13031     uint64_t unsigned_sum = x + y + carry_in;
13032     int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
13033 
13034     result = UnsignedBits(unsigned_sum, 31, 0);
13035 //    carry_out = (result == unsigned_sum ? 0 : 1);
13036     overflow = ((int32_t)result == signed_sum ? 0 : 1);
13037 
13038     if (carry_in)
13039         carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0;
13040     else
13041         carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0;
13042 
13043     AddWithCarryResult res = { result, carry_out, overflow };
13044     return res;
13045 }
13046 
13047 uint32_t
13048 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
13049 {
13050     uint32_t reg_kind, reg_num;
13051     switch (num)
13052     {
13053     case SP_REG:
13054         reg_kind = eRegisterKindGeneric;
13055         reg_num  = LLDB_REGNUM_GENERIC_SP;
13056         break;
13057     case LR_REG:
13058         reg_kind = eRegisterKindGeneric;
13059         reg_num  = LLDB_REGNUM_GENERIC_RA;
13060         break;
13061     case PC_REG:
13062         reg_kind = eRegisterKindGeneric;
13063         reg_num  = LLDB_REGNUM_GENERIC_PC;
13064         break;
13065     default:
13066         if (num < SP_REG)
13067         {
13068             reg_kind = eRegisterKindDWARF;
13069             reg_num  = dwarf_r0 + num;
13070         }
13071         else
13072         {
13073             assert(0 && "Invalid register number");
13074             *success = false;
13075             return UINT32_MAX;
13076         }
13077         break;
13078     }
13079 
13080     // Read our register.
13081     uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
13082 
13083     // When executing an ARM instruction , PC reads as the address of the current
13084     // instruction plus 8.
13085     // When executing a Thumb instruction , PC reads as the address of the current
13086     // instruction plus 4.
13087     if (num == 15)
13088     {
13089         if (CurrentInstrSet() == eModeARM)
13090             val += 8;
13091         else
13092             val += 4;
13093     }
13094 
13095     return val;
13096 }
13097 
13098 // Write the result to the ARM core register Rd, and optionally update the
13099 // condition flags based on the result.
13100 //
13101 // This helper method tries to encapsulate the following pseudocode from the
13102 // ARM Architecture Reference Manual:
13103 //
13104 // if d == 15 then         // Can only occur for encoding A1
13105 //     ALUWritePC(result); // setflags is always FALSE here
13106 // else
13107 //     R[d] = result;
13108 //     if setflags then
13109 //         APSR.N = result<31>;
13110 //         APSR.Z = IsZeroBit(result);
13111 //         APSR.C = carry;
13112 //         // APSR.V unchanged
13113 //
13114 // In the above case, the API client does not pass in the overflow arg, which
13115 // defaults to ~0u.
13116 bool
13117 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
13118                                                   const uint32_t result,
13119                                                   const uint32_t Rd,
13120                                                   bool setflags,
13121                                                   const uint32_t carry,
13122                                                   const uint32_t overflow)
13123 {
13124     if (Rd == 15)
13125     {
13126         if (!ALUWritePC (context, result))
13127             return false;
13128     }
13129     else
13130     {
13131         uint32_t reg_kind, reg_num;
13132         switch (Rd)
13133         {
13134         case SP_REG:
13135             reg_kind = eRegisterKindGeneric;
13136             reg_num  = LLDB_REGNUM_GENERIC_SP;
13137             break;
13138         case LR_REG:
13139             reg_kind = eRegisterKindGeneric;
13140             reg_num  = LLDB_REGNUM_GENERIC_RA;
13141             break;
13142         default:
13143             reg_kind = eRegisterKindDWARF;
13144             reg_num  = dwarf_r0 + Rd;
13145         }
13146         if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
13147             return false;
13148         if (setflags)
13149             return WriteFlags (context, result, carry, overflow);
13150     }
13151     return true;
13152 }
13153 
13154 // This helper method tries to encapsulate the following pseudocode from the
13155 // ARM Architecture Reference Manual:
13156 //
13157 // APSR.N = result<31>;
13158 // APSR.Z = IsZeroBit(result);
13159 // APSR.C = carry;
13160 // APSR.V = overflow
13161 //
13162 // Default arguments can be specified for carry and overflow parameters, which means
13163 // not to update the respective flags.
13164 bool
13165 EmulateInstructionARM::WriteFlags (Context &context,
13166                                    const uint32_t result,
13167                                    const uint32_t carry,
13168                                    const uint32_t overflow)
13169 {
13170     m_new_inst_cpsr = m_opcode_cpsr;
13171     SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
13172     SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
13173     if (carry != ~0u)
13174         SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
13175     if (overflow != ~0u)
13176         SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
13177     if (m_new_inst_cpsr != m_opcode_cpsr)
13178     {
13179         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13180             return false;
13181     }
13182     return true;
13183 }
13184 
13185 bool
13186 EmulateInstructionARM::EvaluateInstruction ()
13187 {
13188     // Advance the ITSTATE bits to their values for the next instruction.
13189     if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
13190         m_it_session.ITAdvance();
13191 
13192 
13193     ARMOpcode *opcode_data;
13194 
13195     if (m_opcode_mode == eModeThumb)
13196     {
13197         if (m_opcode.GetType() == Opcode::eType32)
13198         {
13199             uint16_t upper_bits = Bits32 (m_opcode.GetOpcode32(), 31, 16);
13200             uint16_t lower_bits = Bits32 (m_opcode.GetOpcode32(), 15, 0);
13201             uint32_t swapped = (lower_bits << 16) | upper_bits;
13202             m_opcode.SetOpcode32 (swapped);
13203         }
13204         opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32());
13205     }
13206     else if (m_opcode_mode == eModeARM)
13207         opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32());
13208     else
13209         return false;
13210 
13211     if (!opcode_data)
13212         return false;
13213     // Verify that we're the right arch for this opcode
13214 
13215     switch (m_arm_isa)
13216     {
13217     case ARMv4:
13218         if (opcode_data->variants != ARMvAll)
13219             return false;
13220         break;
13221 
13222     case ARMv4T:
13223         if ((opcode_data->variants!= ARMvAll)
13224             && (opcode_data->variants != ARMV4T_ABOVE))
13225             return false;
13226         break;
13227 
13228     case ARMv5T:
13229     case ARMv5TE:
13230         if ((opcode_data->variants != ARMvAll)
13231             && (opcode_data->variants != ARMV4T_ABOVE)
13232             && (opcode_data->variants != ARMV5_ABOVE))
13233             return false;
13234         break;
13235 
13236     case ARMv5TEJ:
13237         if ((opcode_data->variants != ARMvAll)
13238             && (opcode_data->variants != ARMV4T_ABOVE)
13239             && (opcode_data->variants != ARMV5_ABOVE)
13240             && (opcode_data->variants != ARMV5J_ABOVE))
13241             return false;
13242         break;
13243 
13244     case ARMv6:
13245     case ARMv6K:
13246         if ((opcode_data->variants != ARMvAll)
13247             && (opcode_data->variants != ARMV4T_ABOVE)
13248             && (opcode_data->variants != ARMV5_ABOVE)
13249             && (opcode_data->variants != ARMV5J_ABOVE)
13250             && (opcode_data->variants != ARMV6_ABOVE))
13251             return false;
13252         break;
13253 
13254     case ARMv6T2:
13255     case ARMv7:
13256     case ARMv8:
13257         if ((opcode_data->variants != ARMvAll)
13258             && (opcode_data->variants != ARMV4T_ABOVE)
13259             && (opcode_data->variants != ARMV5_ABOVE)
13260             && (opcode_data->variants != ARMV5J_ABOVE)
13261             && (opcode_data->variants != ARMV6_ABOVE)
13262             && (opcode_data->variants != ARMV6T2_ABOVE))
13263             return false;
13264         break;
13265 
13266     default:
13267 //            if (opcode_data->variants != ARMvAll)
13268 //                return false;
13269         break;
13270     }
13271 
13272     // Just for now, for testing purposes.
13273     if (m_baton == NULL)
13274         fprintf (stdout, "\nEvaluateInstruction, opcode (0x%x), found = '%s'\n", m_opcode.GetOpcode32(),
13275                  opcode_data->name);
13276 
13277     bool success;
13278     if (m_baton)
13279     {
13280         uint32_t cpsr_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
13281         if (success)
13282             m_opcode_cpsr = cpsr_value;
13283     }
13284 
13285     uint32_t orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13286     if (!success)
13287         return false;
13288 
13289     success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);  // Call the Emulate... function.
13290     if (!success)
13291         return false;
13292 
13293     uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13294     if (!success)
13295         return false;
13296 
13297     if (m_advance_pc && (after_pc_value == orig_pc_value))
13298     {
13299         if (opcode_data->size == eSize32)
13300             after_pc_value += 4;
13301         else if (opcode_data->size == eSize16)
13302             after_pc_value += 2;
13303 
13304         EmulateInstruction::Context context;
13305         context.type = eContextAdvancePC;
13306         context.SetNoArgs();
13307         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
13308             return false;
13309 
13310     }
13311 
13312     return true;
13313 }
13314