1 //===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include <stdlib.h>
11 
12 #include "EmulateInstructionARM.h"
13 #include "EmulationStateARM.h"
14 #include "lldb/Core/ArchSpec.h"
15 #include "lldb/Core/Address.h"
16 #include "lldb/Core/ConstString.h"
17 #include "lldb/Core/PluginManager.h"
18 #include "lldb/Core/Stream.h"
19 #include "lldb/Interpreter/OptionValueArray.h"
20 #include "lldb/Interpreter/OptionValueDictionary.h"
21 #include "lldb/Symbol/UnwindPlan.h"
22 
23 #include "Plugins/Process/Utility/ARMDefines.h"
24 #include "Plugins/Process/Utility/ARMUtils.h"
25 #include "Utility/ARM_DWARF_Registers.h"
26 
27 #include "llvm/Support/MathExtras.h" // for SignExtend32 template function
28                                      // and countTrailingZeros function
29 
30 using namespace lldb;
31 using namespace lldb_private;
32 
33 // Convenient macro definitions.
34 #define APSR_C Bit32(m_opcode_cpsr, CPSR_C_POS)
35 #define APSR_V Bit32(m_opcode_cpsr, CPSR_V_POS)
36 
37 #define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
38 
39 //----------------------------------------------------------------------
40 //
41 // ITSession implementation
42 //
43 //----------------------------------------------------------------------
44 
45 // A8.6.50
46 // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition.
47 static uint32_t
CountITSize(uint32_t ITMask)48 CountITSize (uint32_t ITMask) {
49     // First count the trailing zeros of the IT mask.
50     uint32_t TZ = llvm::countTrailingZeros(ITMask);
51     if (TZ > 3)
52     {
53 #ifdef LLDB_CONFIGURATION_DEBUG
54         printf("Encoding error: IT Mask '0000'\n");
55 #endif
56         return 0;
57     }
58     return (4 - TZ);
59 }
60 
61 // Init ITState.  Note that at least one bit is always 1 in mask.
InitIT(uint32_t bits7_0)62 bool ITSession::InitIT(uint32_t bits7_0)
63 {
64     ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
65     if (ITCounter == 0)
66         return false;
67 
68     // A8.6.50 IT
69     unsigned short FirstCond = Bits32(bits7_0, 7, 4);
70     if (FirstCond == 0xF)
71     {
72 #ifdef LLDB_CONFIGURATION_DEBUG
73         printf("Encoding error: IT FirstCond '1111'\n");
74 #endif
75         return false;
76     }
77     if (FirstCond == 0xE && ITCounter != 1)
78     {
79 #ifdef LLDB_CONFIGURATION_DEBUG
80         printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
81 #endif
82         return false;
83     }
84 
85     ITState = bits7_0;
86     return true;
87 }
88 
89 // Update ITState if necessary.
ITAdvance()90 void ITSession::ITAdvance()
91 {
92     //assert(ITCounter);
93     --ITCounter;
94     if (ITCounter == 0)
95         ITState = 0;
96     else
97     {
98         unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
99         SetBits32(ITState, 4, 0, NewITState4_0);
100     }
101 }
102 
103 // Return true if we're inside an IT Block.
InITBlock()104 bool ITSession::InITBlock()
105 {
106     return ITCounter != 0;
107 }
108 
109 // Return true if we're the last instruction inside an IT Block.
LastInITBlock()110 bool ITSession::LastInITBlock()
111 {
112     return ITCounter == 1;
113 }
114 
115 // Get condition bits for the current thumb instruction.
GetCond()116 uint32_t ITSession::GetCond()
117 {
118     if (InITBlock())
119         return Bits32(ITState, 7, 4);
120     else
121         return COND_AL;
122 }
123 
124 // ARM constants used during decoding
125 #define REG_RD          0
126 #define LDM_REGLIST     1
127 #define SP_REG          13
128 #define LR_REG          14
129 #define PC_REG          15
130 #define PC_REGLIST_BIT  0x8000
131 
132 #define ARMv4     (1u << 0)
133 #define ARMv4T    (1u << 1)
134 #define ARMv5T    (1u << 2)
135 #define ARMv5TE   (1u << 3)
136 #define ARMv5TEJ  (1u << 4)
137 #define ARMv6     (1u << 5)
138 #define ARMv6K    (1u << 6)
139 #define ARMv6T2   (1u << 7)
140 #define ARMv7     (1u << 8)
141 #define ARMv7S    (1u << 9)
142 #define ARMv8     (1u << 10)
143 #define ARMvAll   (0xffffffffu)
144 
145 #define ARMV4T_ABOVE  (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
146 #define ARMV5_ABOVE   (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
147 #define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
148 #define ARMV5J_ABOVE  (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
149 #define ARMV6_ABOVE   (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
150 #define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv7S|ARMv8)
151 #define ARMV7_ABOVE   (ARMv7|ARMv7S|ARMv8)
152 
153 #define No_VFP  0
154 #define VFPv1   (1u << 1)
155 #define VFPv2   (1u << 2)
156 #define VFPv3   (1u << 3)
157 #define AdvancedSIMD (1u << 4)
158 
159 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
160 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
161 #define VFPv2v3     (VFPv2 | VFPv3)
162 
163 //----------------------------------------------------------------------
164 //
165 // EmulateInstructionARM implementation
166 //
167 //----------------------------------------------------------------------
168 
169 void
Initialize()170 EmulateInstructionARM::Initialize ()
171 {
172     PluginManager::RegisterPlugin (GetPluginNameStatic (),
173                                    GetPluginDescriptionStatic (),
174                                    CreateInstance);
175 }
176 
177 void
Terminate()178 EmulateInstructionARM::Terminate ()
179 {
180     PluginManager::UnregisterPlugin (CreateInstance);
181 }
182 
183 ConstString
GetPluginNameStatic()184 EmulateInstructionARM::GetPluginNameStatic ()
185 {
186     static ConstString g_name("arm");
187     return g_name;
188 }
189 
190 const char *
GetPluginDescriptionStatic()191 EmulateInstructionARM::GetPluginDescriptionStatic ()
192 {
193     return "Emulate instructions for the ARM architecture.";
194 }
195 
196 EmulateInstruction *
CreateInstance(const ArchSpec & arch,InstructionType inst_type)197 EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type)
198 {
199     if (EmulateInstructionARM::SupportsEmulatingIntructionsOfTypeStatic(inst_type))
200     {
201         if (arch.GetTriple().getArch() == llvm::Triple::arm)
202         {
203             std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
204 
205             if (emulate_insn_ap.get())
206                 return emulate_insn_ap.release();
207         }
208         else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
209         {
210             std::unique_ptr<EmulateInstructionARM> emulate_insn_ap (new EmulateInstructionARM (arch));
211 
212             if (emulate_insn_ap.get())
213                 return emulate_insn_ap.release();
214         }
215     }
216 
217     return NULL;
218 }
219 
220 bool
SetTargetTriple(const ArchSpec & arch)221 EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch)
222 {
223     if (arch.GetTriple().getArch () == llvm::Triple::arm)
224         return true;
225     else if (arch.GetTriple().getArch () == llvm::Triple::thumb)
226         return true;
227 
228     return false;
229 }
230 
231 // Write "bits (32) UNKNOWN" to memory address "address".  Helper function for many ARM instructions.
232 bool
WriteBits32UnknownToMemory(addr_t address)233 EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address)
234 {
235     EmulateInstruction::Context context;
236     context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
237     context.SetNoArgs ();
238 
239     uint32_t random_data = rand ();
240     const uint32_t addr_byte_size = GetAddressByteSize();
241 
242     if (!MemAWrite (context, address, random_data, addr_byte_size))
243         return false;
244 
245     return true;
246 }
247 
248 // Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM instructions.
249 bool
WriteBits32Unknown(int n)250 EmulateInstructionARM::WriteBits32Unknown (int n)
251 {
252     EmulateInstruction::Context context;
253     context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
254     context.SetNoArgs ();
255 
256     bool success;
257     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
258 
259     if (!success)
260         return false;
261 
262     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
263         return false;
264 
265     return true;
266 }
267 
268 bool
GetRegisterInfo(uint32_t reg_kind,uint32_t reg_num,RegisterInfo & reg_info)269 EmulateInstructionARM::GetRegisterInfo (uint32_t reg_kind, uint32_t reg_num, RegisterInfo &reg_info)
270 {
271     if (reg_kind == eRegisterKindGeneric)
272     {
273         switch (reg_num)
274         {
275             case LLDB_REGNUM_GENERIC_PC:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break;
276             case LLDB_REGNUM_GENERIC_SP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break;
277             case LLDB_REGNUM_GENERIC_FP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break;
278             case LLDB_REGNUM_GENERIC_RA:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break;
279             case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break;
280             default: return false;
281         }
282     }
283 
284     if (reg_kind == eRegisterKindDWARF)
285         return GetARMDWARFRegisterInfo(reg_num, reg_info);
286     return false;
287 }
288 
289 uint32_t
GetFramePointerRegisterNumber() const290 EmulateInstructionARM::GetFramePointerRegisterNumber () const
291 {
292     if (m_opcode_mode == eModeThumb)
293     {
294         switch (m_arch.GetTriple().getOS())
295         {
296             case llvm::Triple::Darwin:
297             case llvm::Triple::MacOSX:
298             case llvm::Triple::IOS:
299                 return 7;
300             default:
301                 break;
302         }
303     }
304     return 11;
305 }
306 
307 uint32_t
GetFramePointerDWARFRegisterNumber() const308 EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const
309 {
310     if (m_opcode_mode == eModeThumb)
311     {
312         switch (m_arch.GetTriple().getOS())
313         {
314             case llvm::Triple::Darwin:
315             case llvm::Triple::MacOSX:
316             case llvm::Triple::IOS:
317                 return dwarf_r7;
318             default:
319                 break;
320         }
321     }
322     return dwarf_r11;
323 }
324 
325 // Push Multiple Registers stores multiple registers to the stack, storing to
326 // consecutive memory locations ending just below the address in SP, and updates
327 // SP to point to the start of the stored data.
328 bool
EmulatePUSH(const uint32_t opcode,const ARMEncoding encoding)329 EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding)
330 {
331 #if 0
332     // ARM pseudo code...
333     if (ConditionPassed())
334     {
335         EncodingSpecificOperations();
336         NullCheckIfThumbEE(13);
337         address = SP - 4*BitCount(registers);
338 
339         for (i = 0 to 14)
340         {
341             if (registers<i> == '1')
342             {
343                 if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
344                     MemA[address,4] = bits(32) UNKNOWN;
345                 else
346                     MemA[address,4] = R[i];
347                 address = address + 4;
348             }
349         }
350 
351         if (registers<15> == '1') // Only possible for encoding A1 or A2
352             MemA[address,4] = PCStoreValue();
353 
354         SP = SP - 4*BitCount(registers);
355     }
356 #endif
357 
358     bool conditional = false;
359     bool success = false;
360     if (ConditionPassed(opcode, &conditional))
361     {
362         const uint32_t addr_byte_size = GetAddressByteSize();
363         const addr_t sp = ReadCoreReg (SP_REG, &success);
364         if (!success)
365             return false;
366         uint32_t registers = 0;
367         uint32_t Rt; // the source register
368         switch (encoding) {
369         case eEncodingT1:
370             registers = Bits32(opcode, 7, 0);
371             // The M bit represents LR.
372             if (Bit32(opcode, 8))
373                 registers |= (1u << 14);
374             // if BitCount(registers) < 1 then UNPREDICTABLE;
375             if (BitCount(registers) < 1)
376                 return false;
377             break;
378         case eEncodingT2:
379             // Ignore bits 15 & 13.
380             registers = Bits32(opcode, 15, 0) & ~0xa000;
381             // if BitCount(registers) < 2 then UNPREDICTABLE;
382             if (BitCount(registers) < 2)
383                 return false;
384             break;
385         case eEncodingT3:
386             Rt = Bits32(opcode, 15, 12);
387             // if BadReg(t) then UNPREDICTABLE;
388             if (BadReg(Rt))
389                 return false;
390             registers = (1u << Rt);
391             break;
392         case eEncodingA1:
393             registers = Bits32(opcode, 15, 0);
394             // Instead of return false, let's handle the following case as well,
395             // which amounts to pushing one reg onto the full descending stacks.
396             // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
397             break;
398         case eEncodingA2:
399             Rt = Bits32(opcode, 15, 12);
400             // if t == 13 then UNPREDICTABLE;
401             if (Rt == dwarf_sp)
402                 return false;
403             registers = (1u << Rt);
404             break;
405         default:
406             return false;
407         }
408         addr_t sp_offset = addr_byte_size * BitCount (registers);
409         addr_t addr = sp - sp_offset;
410         uint32_t i;
411 
412         EmulateInstruction::Context context;
413         if (conditional)
414             context.type = EmulateInstruction::eContextRegisterStore;
415         else
416             context.type = EmulateInstruction::eContextPushRegisterOnStack;
417         RegisterInfo reg_info;
418         RegisterInfo sp_reg;
419         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
420         for (i=0; i<15; ++i)
421         {
422             if (BitIsSet (registers, i))
423             {
424                 GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info);
425                 context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
426                 uint32_t reg_value = ReadCoreReg(i, &success);
427                 if (!success)
428                     return false;
429                 if (!MemAWrite (context, addr, reg_value, addr_byte_size))
430                     return false;
431                 addr += addr_byte_size;
432             }
433         }
434 
435         if (BitIsSet (registers, 15))
436         {
437             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info);
438             context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
439             const uint32_t pc = ReadCoreReg(PC_REG, &success);
440             if (!success)
441                 return false;
442             if (!MemAWrite (context, addr, pc, addr_byte_size))
443                 return false;
444         }
445 
446         context.type = EmulateInstruction::eContextAdjustStackPointer;
447         context.SetImmediateSigned (-sp_offset);
448 
449         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
450             return false;
451     }
452     return true;
453 }
454 
455 // Pop Multiple Registers loads multiple registers from the stack, loading from
456 // consecutive memory locations staring at the address in SP, and updates
457 // SP to point just above the loaded data.
458 bool
EmulatePOP(const uint32_t opcode,const ARMEncoding encoding)459 EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding)
460 {
461 #if 0
462     // ARM pseudo code...
463     if (ConditionPassed())
464     {
465         EncodingSpecificOperations(); NullCheckIfThumbEE(13);
466         address = SP;
467         for i = 0 to 14
468             if registers<i> == '1' then
469                 R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
470         if registers<15> == '1' then
471             if UnalignedAllowed then
472                 LoadWritePC(MemU[address,4]);
473             else
474                 LoadWritePC(MemA[address,4]);
475         if registers<13> == '0' then SP = SP + 4*BitCount(registers);
476         if registers<13> == '1' then SP = bits(32) UNKNOWN;
477     }
478 #endif
479 
480     bool success = false;
481 
482     bool conditional = false;
483     if (ConditionPassed(opcode, &conditional))
484     {
485         const uint32_t addr_byte_size = GetAddressByteSize();
486         const addr_t sp = ReadCoreReg (SP_REG, &success);
487         if (!success)
488             return false;
489         uint32_t registers = 0;
490         uint32_t Rt; // the destination register
491         switch (encoding) {
492         case eEncodingT1:
493             registers = Bits32(opcode, 7, 0);
494             // The P bit represents PC.
495             if (Bit32(opcode, 8))
496                 registers |= (1u << 15);
497             // if BitCount(registers) < 1 then UNPREDICTABLE;
498             if (BitCount(registers) < 1)
499                 return false;
500             break;
501         case eEncodingT2:
502             // Ignore bit 13.
503             registers = Bits32(opcode, 15, 0) & ~0x2000;
504             // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
505             if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
506                 return false;
507             // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
508             if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
509                 return false;
510             break;
511         case eEncodingT3:
512             Rt = Bits32(opcode, 15, 12);
513             // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
514             if (Rt == 13)
515                 return false;
516             if (Rt == 15 && InITBlock() && !LastInITBlock())
517                 return false;
518             registers = (1u << Rt);
519             break;
520         case eEncodingA1:
521             registers = Bits32(opcode, 15, 0);
522             // Instead of return false, let's handle the following case as well,
523             // which amounts to popping one reg from the full descending stacks.
524             // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
525 
526             // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
527             if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
528                 return false;
529             break;
530         case eEncodingA2:
531             Rt = Bits32(opcode, 15, 12);
532             // if t == 13 then UNPREDICTABLE;
533             if (Rt == dwarf_sp)
534                 return false;
535             registers = (1u << Rt);
536             break;
537         default:
538             return false;
539         }
540         addr_t sp_offset = addr_byte_size * BitCount (registers);
541         addr_t addr = sp;
542         uint32_t i, data;
543 
544         EmulateInstruction::Context context;
545         if (conditional)
546             context.type = EmulateInstruction::eContextRegisterLoad;
547         else
548             context.type = EmulateInstruction::eContextPopRegisterOffStack;
549 
550         RegisterInfo sp_reg;
551         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
552 
553         for (i=0; i<15; ++i)
554         {
555             if (BitIsSet (registers, i))
556             {
557                 context.SetRegisterPlusOffset (sp_reg, addr - sp);
558                 data = MemARead(context, addr, 4, 0, &success);
559                 if (!success)
560                     return false;
561                 if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data))
562                     return false;
563                 addr += addr_byte_size;
564             }
565         }
566 
567         if (BitIsSet (registers, 15))
568         {
569             context.SetRegisterPlusOffset (sp_reg, addr - sp);
570             data = MemARead(context, addr, 4, 0, &success);
571             if (!success)
572                 return false;
573             // In ARMv5T and above, this is an interworking branch.
574             if (!LoadWritePC(context, data))
575                 return false;
576             //addr += addr_byte_size;
577         }
578 
579         context.type = EmulateInstruction::eContextAdjustStackPointer;
580         context.SetImmediateSigned (sp_offset);
581 
582         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
583             return false;
584     }
585     return true;
586 }
587 
588 // Set r7 or ip to point to saved value residing within the stack.
589 // ADD (SP plus immediate)
590 bool
EmulateADDRdSPImm(const uint32_t opcode,const ARMEncoding encoding)591 EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding)
592 {
593 #if 0
594     // ARM pseudo code...
595     if (ConditionPassed())
596     {
597         EncodingSpecificOperations();
598         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
599         if d == 15 then
600            ALUWritePC(result); // setflags is always FALSE here
601         else
602             R[d] = result;
603             if setflags then
604                 APSR.N = result<31>;
605                 APSR.Z = IsZeroBit(result);
606                 APSR.C = carry;
607                 APSR.V = overflow;
608     }
609 #endif
610 
611     bool success = false;
612 
613     if (ConditionPassed(opcode))
614     {
615         const addr_t sp = ReadCoreReg (SP_REG, &success);
616         if (!success)
617             return false;
618         uint32_t Rd; // the destination register
619         uint32_t imm32;
620         switch (encoding) {
621         case eEncodingT1:
622             Rd = 7;
623             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
624             break;
625         case eEncodingA1:
626             Rd = Bits32(opcode, 15, 12);
627             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
628             break;
629         default:
630             return false;
631         }
632         addr_t sp_offset = imm32;
633         addr_t addr = sp + sp_offset; // a pointer to the stack area
634 
635         EmulateInstruction::Context context;
636         context.type = eContextSetFramePointer;
637         RegisterInfo sp_reg;
638         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
639         context.SetRegisterPlusOffset (sp_reg, sp_offset);
640 
641         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
642             return false;
643     }
644     return true;
645 }
646 
647 // Set r7 or ip to the current stack pointer.
648 // MOV (register)
649 bool
EmulateMOVRdSP(const uint32_t opcode,const ARMEncoding encoding)650 EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding)
651 {
652 #if 0
653     // ARM pseudo code...
654     if (ConditionPassed())
655     {
656         EncodingSpecificOperations();
657         result = R[m];
658         if d == 15 then
659             ALUWritePC(result); // setflags is always FALSE here
660         else
661             R[d] = result;
662             if setflags then
663                 APSR.N = result<31>;
664                 APSR.Z = IsZeroBit(result);
665                 // APSR.C unchanged
666                 // APSR.V unchanged
667     }
668 #endif
669 
670     bool success = false;
671 
672     if (ConditionPassed(opcode))
673     {
674         const addr_t sp = ReadCoreReg (SP_REG, &success);
675         if (!success)
676             return false;
677         uint32_t Rd; // the destination register
678         switch (encoding) {
679         case eEncodingT1:
680             Rd = 7;
681             break;
682         case eEncodingA1:
683             Rd = 12;
684             break;
685         default:
686             return false;
687         }
688 
689         EmulateInstruction::Context context;
690         if (Rd == GetFramePointerRegisterNumber())
691             context.type = EmulateInstruction::eContextSetFramePointer;
692         else
693             context.type = EmulateInstruction::eContextRegisterPlusOffset;
694         RegisterInfo sp_reg;
695         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
696         context.SetRegisterPlusOffset (sp_reg, 0);
697 
698         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
699             return false;
700     }
701     return true;
702 }
703 
704 // Move from high register (r8-r15) to low register (r0-r7).
705 // MOV (register)
706 bool
EmulateMOVLowHigh(const uint32_t opcode,const ARMEncoding encoding)707 EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding)
708 {
709     return EmulateMOVRdRm (opcode, encoding);
710 }
711 
712 // Move from register to register.
713 // MOV (register)
714 bool
EmulateMOVRdRm(const uint32_t opcode,const ARMEncoding encoding)715 EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding)
716 {
717 #if 0
718     // ARM pseudo code...
719     if (ConditionPassed())
720     {
721         EncodingSpecificOperations();
722         result = R[m];
723         if d == 15 then
724             ALUWritePC(result); // setflags is always FALSE here
725         else
726             R[d] = result;
727             if setflags then
728                 APSR.N = result<31>;
729                 APSR.Z = IsZeroBit(result);
730                 // APSR.C unchanged
731                 // APSR.V unchanged
732     }
733 #endif
734 
735     bool success = false;
736 
737     if (ConditionPassed(opcode))
738     {
739         uint32_t Rm; // the source register
740         uint32_t Rd; // the destination register
741         bool setflags;
742         switch (encoding) {
743         case eEncodingT1:
744             Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
745             Rm = Bits32(opcode, 6, 3);
746             setflags = false;
747             if (Rd == 15 && InITBlock() && !LastInITBlock())
748                 return false;
749             break;
750         case eEncodingT2:
751             Rd = Bits32(opcode, 2, 0);
752             Rm = Bits32(opcode, 5, 3);
753             setflags = true;
754             if (InITBlock())
755                 return false;
756             break;
757         case eEncodingT3:
758             Rd = Bits32(opcode, 11, 8);
759             Rm = Bits32(opcode, 3, 0);
760             setflags = BitIsSet(opcode, 20);
761             // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
762             if (setflags && (BadReg(Rd) || BadReg(Rm)))
763                 return false;
764             // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE;
765             if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
766                 return false;
767             break;
768         case eEncodingA1:
769             Rd = Bits32(opcode, 15, 12);
770             Rm = Bits32(opcode, 3, 0);
771             setflags = BitIsSet(opcode, 20);
772 
773             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
774             if (Rd == 15 && setflags)
775                 return EmulateSUBSPcLrEtc (opcode, encoding);
776             break;
777         default:
778             return false;
779         }
780         uint32_t result = ReadCoreReg(Rm, &success);
781         if (!success)
782             return false;
783 
784         // The context specifies that Rm is to be moved into Rd.
785         EmulateInstruction::Context context;
786         context.type = EmulateInstruction::eContextRegisterLoad;
787         RegisterInfo dwarf_reg;
788         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
789         context.SetRegister (dwarf_reg);
790 
791         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
792             return false;
793     }
794     return true;
795 }
796 
797 // Move (immediate) writes an immediate value to the destination register.  It
798 // can optionally update the condition flags based on the value.
799 // MOV (immediate)
800 bool
EmulateMOVRdImm(const uint32_t opcode,const ARMEncoding encoding)801 EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding)
802 {
803 #if 0
804     // ARM pseudo code...
805     if (ConditionPassed())
806     {
807         EncodingSpecificOperations();
808         result = imm32;
809         if d == 15 then         // Can only occur for ARM encoding
810             ALUWritePC(result); // setflags is always FALSE here
811         else
812             R[d] = result;
813             if setflags then
814                 APSR.N = result<31>;
815                 APSR.Z = IsZeroBit(result);
816                 APSR.C = carry;
817                 // APSR.V unchanged
818     }
819 #endif
820 
821     if (ConditionPassed(opcode))
822     {
823         uint32_t Rd; // the destination register
824         uint32_t imm32; // the immediate value to be written to Rd
825         uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
826                             // for setflags == false, this value is a don't care
827                             // initialized to 0 to silence the static analyzer
828         bool setflags;
829         switch (encoding) {
830             case eEncodingT1:
831                 Rd = Bits32(opcode, 10, 8);
832                 setflags = !InITBlock();
833                 imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
834                 carry = APSR_C;
835 
836                 break;
837 
838             case eEncodingT2:
839                 Rd = Bits32(opcode, 11, 8);
840                 setflags = BitIsSet(opcode, 20);
841                 imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
842                 if (BadReg(Rd))
843                   return false;
844 
845                 break;
846 
847             case eEncodingT3:
848             {
849                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32);
850                 Rd = Bits32 (opcode, 11, 8);
851                 setflags = false;
852                 uint32_t imm4 = Bits32 (opcode, 19, 16);
853                 uint32_t imm3 = Bits32 (opcode, 14, 12);
854                 uint32_t i = Bit32 (opcode, 26);
855                 uint32_t imm8 = Bits32 (opcode, 7, 0);
856                 imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
857 
858                 // if BadReg(d) then UNPREDICTABLE;
859                 if (BadReg (Rd))
860                     return false;
861             }
862                 break;
863 
864             case eEncodingA1:
865                 // d = UInt(Rd); setflags = (S == �1�); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C);
866                 Rd = Bits32 (opcode, 15, 12);
867                 setflags = BitIsSet (opcode, 20);
868                 imm32 = ARMExpandImm_C (opcode, APSR_C, carry);
869 
870                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
871                 if ((Rd == 15) && setflags)
872                     return EmulateSUBSPcLrEtc (opcode, encoding);
873 
874                 break;
875 
876             case eEncodingA2:
877             {
878                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
879                 Rd = Bits32 (opcode, 15, 12);
880                 setflags = false;
881                 uint32_t imm4 = Bits32 (opcode, 19, 16);
882                 uint32_t imm12 = Bits32 (opcode, 11, 0);
883                 imm32 = (imm4 << 12) | imm12;
884 
885                 // if d == 15 then UNPREDICTABLE;
886                 if (Rd == 15)
887                     return false;
888             }
889                 break;
890 
891             default:
892                 return false;
893         }
894         uint32_t result = imm32;
895 
896         // The context specifies that an immediate is to be moved into Rd.
897         EmulateInstruction::Context context;
898         context.type = EmulateInstruction::eContextImmediate;
899         context.SetNoArgs ();
900 
901         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
902             return false;
903     }
904     return true;
905 }
906 
907 // MUL multiplies two register values.  The least significant 32 bits of the result are written to the destination
908 // register.  These 32 bits do not depend on whether the source register values are considered to be signed values or
909 // unsigned values.
910 //
911 // Optionally, it can update the condition flags based on the result.  In the Thumb instruction set, this option is
912 // limited to only a few forms of the instruction.
913 bool
EmulateMUL(const uint32_t opcode,const ARMEncoding encoding)914 EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding)
915 {
916 #if 0
917     if ConditionPassed() then
918         EncodingSpecificOperations();
919         operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
920         operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
921         result = operand1 * operand2;
922         R[d] = result<31:0>;
923         if setflags then
924             APSR.N = result<31>;
925             APSR.Z = IsZeroBit(result);
926             if ArchVersion() == 4 then
927                 APSR.C = bit UNKNOWN;
928             // else APSR.C unchanged
929             // APSR.V always unchanged
930 #endif
931 
932     if (ConditionPassed(opcode))
933     {
934         uint32_t d;
935         uint32_t n;
936         uint32_t m;
937         bool setflags;
938 
939         // EncodingSpecificOperations();
940         switch (encoding)
941         {
942             case eEncodingT1:
943                 // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
944                 d = Bits32 (opcode, 2, 0);
945                 n = Bits32 (opcode, 5, 3);
946                 m = Bits32 (opcode, 2, 0);
947                 setflags = !InITBlock();
948 
949                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
950                 if ((ArchVersion() < ARMv6) && (d == n))
951                     return false;
952 
953                 break;
954 
955             case eEncodingT2:
956                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
957                 d = Bits32 (opcode, 11, 8);
958                 n = Bits32 (opcode, 19, 16);
959                 m = Bits32 (opcode, 3, 0);
960                 setflags = false;
961 
962                 // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
963                 if (BadReg (d) || BadReg (n) || BadReg (m))
964                     return false;
965 
966                 break;
967 
968             case eEncodingA1:
969                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
970                 d = Bits32 (opcode, 19, 16);
971                 n = Bits32 (opcode, 3, 0);
972                 m = Bits32 (opcode, 11, 8);
973                 setflags = BitIsSet (opcode, 20);
974 
975                 // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
976                 if ((d == 15) ||  (n == 15) || (m == 15))
977                     return false;
978 
979                 // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
980                 if ((ArchVersion() < ARMv6) && (d == n))
981                     return false;
982 
983                 break;
984 
985             default:
986                 return false;
987         }
988 
989         bool success = false;
990 
991         // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
992         uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
993         if (!success)
994             return false;
995 
996         // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
997         uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
998         if (!success)
999             return false;
1000 
1001         // result = operand1 * operand2;
1002         uint64_t result = operand1 * operand2;
1003 
1004         // R[d] = result<31:0>;
1005         RegisterInfo op1_reg;
1006         RegisterInfo op2_reg;
1007         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
1008         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
1009 
1010         EmulateInstruction::Context context;
1011         context.type = eContextArithmetic;
1012         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
1013 
1014         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result)))
1015             return false;
1016 
1017         // if setflags then
1018         if (setflags)
1019         {
1020             // APSR.N = result<31>;
1021             // APSR.Z = IsZeroBit(result);
1022             m_new_inst_cpsr = m_opcode_cpsr;
1023             SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31));
1024             SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1025             if (m_new_inst_cpsr != m_opcode_cpsr)
1026             {
1027                 if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1028                     return false;
1029             }
1030 
1031             // if ArchVersion() == 4 then
1032                 // APSR.C = bit UNKNOWN;
1033         }
1034     }
1035     return true;
1036 }
1037 
1038 // Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register.
1039 // It can optionally update the condition flags based on the value.
1040 bool
EmulateMVNImm(const uint32_t opcode,const ARMEncoding encoding)1041 EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding)
1042 {
1043 #if 0
1044     // ARM pseudo code...
1045     if (ConditionPassed())
1046     {
1047         EncodingSpecificOperations();
1048         result = NOT(imm32);
1049         if d == 15 then         // Can only occur for ARM encoding
1050             ALUWritePC(result); // setflags is always FALSE here
1051         else
1052             R[d] = result;
1053             if setflags then
1054                 APSR.N = result<31>;
1055                 APSR.Z = IsZeroBit(result);
1056                 APSR.C = carry;
1057                 // APSR.V unchanged
1058     }
1059 #endif
1060 
1061     if (ConditionPassed(opcode))
1062     {
1063         uint32_t Rd; // the destination register
1064         uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1065         uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1066         bool setflags;
1067         switch (encoding) {
1068         case eEncodingT1:
1069             Rd = Bits32(opcode, 11, 8);
1070             setflags = BitIsSet(opcode, 20);
1071             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1072             break;
1073         case eEncodingA1:
1074             Rd = Bits32(opcode, 15, 12);
1075             setflags = BitIsSet(opcode, 20);
1076             imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1077 
1078             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1079             if (Rd == 15 && setflags)
1080                 return EmulateSUBSPcLrEtc (opcode, encoding);
1081             break;
1082         default:
1083             return false;
1084         }
1085         uint32_t result = ~imm32;
1086 
1087         // The context specifies that an immediate is to be moved into Rd.
1088         EmulateInstruction::Context context;
1089         context.type = EmulateInstruction::eContextImmediate;
1090         context.SetNoArgs ();
1091 
1092         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1093             return false;
1094     }
1095     return true;
1096 }
1097 
1098 // Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register.
1099 // It can optionally update the condition flags based on the result.
1100 bool
EmulateMVNReg(const uint32_t opcode,const ARMEncoding encoding)1101 EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding)
1102 {
1103 #if 0
1104     // ARM pseudo code...
1105     if (ConditionPassed())
1106     {
1107         EncodingSpecificOperations();
1108         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1109         result = NOT(shifted);
1110         if d == 15 then         // Can only occur for ARM encoding
1111             ALUWritePC(result); // setflags is always FALSE here
1112         else
1113             R[d] = result;
1114             if setflags then
1115                 APSR.N = result<31>;
1116                 APSR.Z = IsZeroBit(result);
1117                 APSR.C = carry;
1118                 // APSR.V unchanged
1119     }
1120 #endif
1121 
1122     if (ConditionPassed(opcode))
1123     {
1124         uint32_t Rm; // the source register
1125         uint32_t Rd; // the destination register
1126         ARM_ShifterType shift_t;
1127         uint32_t shift_n; // the shift applied to the value read from Rm
1128         bool setflags;
1129         uint32_t carry; // the carry bit after the shift operation
1130         switch (encoding) {
1131         case eEncodingT1:
1132             Rd = Bits32(opcode, 2, 0);
1133             Rm = Bits32(opcode, 5, 3);
1134             setflags = !InITBlock();
1135             shift_t = SRType_LSL;
1136             shift_n = 0;
1137             if (InITBlock())
1138                 return false;
1139             break;
1140         case eEncodingT2:
1141             Rd = Bits32(opcode, 11, 8);
1142             Rm = Bits32(opcode, 3, 0);
1143             setflags = BitIsSet(opcode, 20);
1144             shift_n = DecodeImmShiftThumb(opcode, shift_t);
1145             // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1146             if (BadReg(Rd) || BadReg(Rm))
1147                 return false;
1148             break;
1149         case eEncodingA1:
1150             Rd = Bits32(opcode, 15, 12);
1151             Rm = Bits32(opcode, 3, 0);
1152             setflags = BitIsSet(opcode, 20);
1153             shift_n = DecodeImmShiftARM(opcode, shift_t);
1154             break;
1155         default:
1156             return false;
1157         }
1158         bool success = false;
1159         uint32_t value = ReadCoreReg(Rm, &success);
1160         if (!success)
1161             return false;
1162 
1163         uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1164         if (!success)
1165             return false;
1166         uint32_t result = ~shifted;
1167 
1168         // The context specifies that an immediate is to be moved into Rd.
1169         EmulateInstruction::Context context;
1170         context.type = EmulateInstruction::eContextImmediate;
1171         context.SetNoArgs ();
1172 
1173         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1174             return false;
1175     }
1176     return true;
1177 }
1178 
1179 // PC relative immediate load into register, possibly followed by ADD (SP plus register).
1180 // LDR (literal)
1181 bool
EmulateLDRRtPCRelative(const uint32_t opcode,const ARMEncoding encoding)1182 EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding)
1183 {
1184 #if 0
1185     // ARM pseudo code...
1186     if (ConditionPassed())
1187     {
1188         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1189         base = Align(PC,4);
1190         address = if add then (base + imm32) else (base - imm32);
1191         data = MemU[address,4];
1192         if t == 15 then
1193             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1194         elsif UnalignedSupport() || address<1:0> = '00' then
1195             R[t] = data;
1196         else // Can only apply before ARMv7
1197             if CurrentInstrSet() == InstrSet_ARM then
1198                 R[t] = ROR(data, 8*UInt(address<1:0>));
1199             else
1200                 R[t] = bits(32) UNKNOWN;
1201     }
1202 #endif
1203 
1204     if (ConditionPassed(opcode))
1205     {
1206         bool success = false;
1207         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1208         if (!success)
1209             return false;
1210 
1211         // PC relative immediate load context
1212         EmulateInstruction::Context context;
1213         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1214         RegisterInfo pc_reg;
1215         GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
1216         context.SetRegisterPlusOffset (pc_reg, 0);
1217 
1218         uint32_t Rt;    // the destination register
1219         uint32_t imm32; // immediate offset from the PC
1220         bool add;       // +imm32 or -imm32?
1221         addr_t base;    // the base address
1222         addr_t address; // the PC relative address
1223         uint32_t data;  // the literal data value from the PC relative load
1224         switch (encoding) {
1225         case eEncodingT1:
1226             Rt = Bits32(opcode, 10, 8);
1227             imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1228             add = true;
1229             break;
1230         case eEncodingT2:
1231             Rt = Bits32(opcode, 15, 12);
1232             imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1233             add = BitIsSet(opcode, 23);
1234             if (Rt == 15 && InITBlock() && !LastInITBlock())
1235                 return false;
1236             break;
1237         default:
1238             return false;
1239         }
1240 
1241         base = Align(pc, 4);
1242         if (add)
1243             address = base + imm32;
1244         else
1245             address = base - imm32;
1246 
1247         context.SetRegisterPlusOffset(pc_reg, address - base);
1248         data = MemURead(context, address, 4, 0, &success);
1249         if (!success)
1250             return false;
1251 
1252         if (Rt == 15)
1253         {
1254             if (Bits32(address, 1, 0) == 0)
1255             {
1256                 // In ARMv5T and above, this is an interworking branch.
1257                 if (!LoadWritePC(context, data))
1258                     return false;
1259             }
1260             else
1261                 return false;
1262         }
1263         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
1264         {
1265             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
1266                 return false;
1267         }
1268         else // We don't handle ARM for now.
1269             return false;
1270 
1271     }
1272     return true;
1273 }
1274 
1275 // An add operation to adjust the SP.
1276 // ADD (SP plus immediate)
1277 bool
EmulateADDSPImm(const uint32_t opcode,const ARMEncoding encoding)1278 EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding)
1279 {
1280 #if 0
1281     // ARM pseudo code...
1282     if (ConditionPassed())
1283     {
1284         EncodingSpecificOperations();
1285         (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1286         if d == 15 then // Can only occur for ARM encoding
1287             ALUWritePC(result); // setflags is always FALSE here
1288         else
1289             R[d] = result;
1290             if setflags then
1291                 APSR.N = result<31>;
1292                 APSR.Z = IsZeroBit(result);
1293                 APSR.C = carry;
1294                 APSR.V = overflow;
1295     }
1296 #endif
1297 
1298     bool success = false;
1299 
1300     if (ConditionPassed(opcode))
1301     {
1302         const addr_t sp = ReadCoreReg (SP_REG, &success);
1303         if (!success)
1304             return false;
1305         uint32_t imm32; // the immediate operand
1306         uint32_t d;
1307         //bool setflags = false; // Add this back if/when support eEncodingT3 eEncodingA1
1308         switch (encoding)
1309         {
1310             case eEncodingT1:
1311                 // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1312                 d = Bits32 (opcode, 10, 8);
1313                 imm32 = (Bits32 (opcode, 7, 0) << 2);
1314 
1315                 break;
1316 
1317             case eEncodingT2:
1318                 // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1319                 d = 13;
1320                 imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1321 
1322                 break;
1323 
1324             default:
1325                 return false;
1326         }
1327         addr_t sp_offset = imm32;
1328         addr_t addr = sp + sp_offset; // the adjusted stack pointer value
1329 
1330         EmulateInstruction::Context context;
1331         context.type = EmulateInstruction::eContextAdjustStackPointer;
1332         RegisterInfo sp_reg;
1333         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1334         context.SetRegisterPlusOffset (sp_reg, sp_offset);
1335 
1336         if (d == 15)
1337         {
1338             if (!ALUWritePC (context, addr))
1339                 return false;
1340         }
1341         else
1342         {
1343             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr))
1344                 return false;
1345 
1346             // Add this back if/when support eEncodingT3 eEncodingA1
1347             //if (setflags)
1348             //{
1349             //    APSR.N = result<31>;
1350             //    APSR.Z = IsZeroBit(result);
1351             //    APSR.C = carry;
1352             //    APSR.V = overflow;
1353             //}
1354         }
1355     }
1356     return true;
1357 }
1358 
1359 // An add operation to adjust the SP.
1360 // ADD (SP plus register)
1361 bool
EmulateADDSPRm(const uint32_t opcode,const ARMEncoding encoding)1362 EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding)
1363 {
1364 #if 0
1365     // ARM pseudo code...
1366     if (ConditionPassed())
1367     {
1368         EncodingSpecificOperations();
1369         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1370         (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1371         if d == 15 then
1372             ALUWritePC(result); // setflags is always FALSE here
1373         else
1374             R[d] = result;
1375             if setflags then
1376                 APSR.N = result<31>;
1377                 APSR.Z = IsZeroBit(result);
1378                 APSR.C = carry;
1379                 APSR.V = overflow;
1380     }
1381 #endif
1382 
1383     bool success = false;
1384 
1385     if (ConditionPassed(opcode))
1386     {
1387         const addr_t sp = ReadCoreReg (SP_REG, &success);
1388         if (!success)
1389             return false;
1390         uint32_t Rm; // the second operand
1391         switch (encoding) {
1392         case eEncodingT2:
1393             Rm = Bits32(opcode, 6, 3);
1394             break;
1395         default:
1396             return false;
1397         }
1398         int32_t reg_value = ReadCoreReg(Rm, &success);
1399         if (!success)
1400             return false;
1401 
1402         addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1403 
1404         EmulateInstruction::Context context;
1405         context.type = eContextArithmetic;
1406         RegisterInfo sp_reg;
1407         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1408 
1409         RegisterInfo other_reg;
1410         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1411         context.SetRegisterRegisterOperands (sp_reg, other_reg);
1412 
1413         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
1414             return false;
1415     }
1416     return true;
1417 }
1418 
1419 // Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
1420 // at a PC-relative address, and changes instruction set from ARM to Thumb, or
1421 // from Thumb to ARM.
1422 // BLX (immediate)
1423 bool
EmulateBLXImmediate(const uint32_t opcode,const ARMEncoding encoding)1424 EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding)
1425 {
1426 #if 0
1427     // ARM pseudo code...
1428     if (ConditionPassed())
1429     {
1430         EncodingSpecificOperations();
1431         if CurrentInstrSet() == InstrSet_ARM then
1432             LR = PC - 4;
1433         else
1434             LR = PC<31:1> : '1';
1435         if targetInstrSet == InstrSet_ARM then
1436             targetAddress = Align(PC,4) + imm32;
1437         else
1438             targetAddress = PC + imm32;
1439         SelectInstrSet(targetInstrSet);
1440         BranchWritePC(targetAddress);
1441     }
1442 #endif
1443 
1444     bool success = true;
1445 
1446     if (ConditionPassed(opcode))
1447     {
1448         EmulateInstruction::Context context;
1449         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1450         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1451         if (!success)
1452             return false;
1453         addr_t lr; // next instruction address
1454         addr_t target; // target address
1455         int32_t imm32; // PC-relative offset
1456         switch (encoding) {
1457         case eEncodingT1:
1458             {
1459             lr = pc | 1u; // return address
1460             uint32_t S = Bit32(opcode, 26);
1461             uint32_t imm10 = Bits32(opcode, 25, 16);
1462             uint32_t J1 = Bit32(opcode, 13);
1463             uint32_t J2 = Bit32(opcode, 11);
1464             uint32_t imm11 = Bits32(opcode, 10, 0);
1465             uint32_t I1 = !(J1 ^ S);
1466             uint32_t I2 = !(J2 ^ S);
1467             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1468             imm32 = llvm::SignExtend32<25>(imm25);
1469             target = pc + imm32;
1470             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
1471             if (InITBlock() && !LastInITBlock())
1472                 return false;
1473             break;
1474             }
1475         case eEncodingT2:
1476             {
1477             lr = pc | 1u; // return address
1478             uint32_t S = Bit32(opcode, 26);
1479             uint32_t imm10H = Bits32(opcode, 25, 16);
1480             uint32_t J1 = Bit32(opcode, 13);
1481             uint32_t J2 = Bit32(opcode, 11);
1482             uint32_t imm10L = Bits32(opcode, 10, 1);
1483             uint32_t I1 = !(J1 ^ S);
1484             uint32_t I2 = !(J2 ^ S);
1485             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
1486             imm32 = llvm::SignExtend32<25>(imm25);
1487             target = Align(pc, 4) + imm32;
1488             context.SetISAAndImmediateSigned (eModeARM, 4 + imm32);
1489             if (InITBlock() && !LastInITBlock())
1490                 return false;
1491             break;
1492             }
1493         case eEncodingA1:
1494             lr = pc - 4; // return address
1495             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1496             target = Align(pc, 4) + imm32;
1497             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
1498             break;
1499         case eEncodingA2:
1500             lr = pc - 4; // return address
1501             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
1502             target = pc + imm32;
1503             context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32);
1504             break;
1505         default:
1506             return false;
1507         }
1508         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1509             return false;
1510         if (!BranchWritePC(context, target))
1511             return false;
1512     }
1513     return true;
1514 }
1515 
1516 // Branch with Link and Exchange (register) calls a subroutine at an address and
1517 // instruction set specified by a register.
1518 // BLX (register)
1519 bool
EmulateBLXRm(const uint32_t opcode,const ARMEncoding encoding)1520 EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding)
1521 {
1522 #if 0
1523     // ARM pseudo code...
1524     if (ConditionPassed())
1525     {
1526         EncodingSpecificOperations();
1527         target = R[m];
1528         if CurrentInstrSet() == InstrSet_ARM then
1529             next_instr_addr = PC - 4;
1530             LR = next_instr_addr;
1531         else
1532             next_instr_addr = PC - 2;
1533             LR = next_instr_addr<31:1> : '1';
1534         BXWritePC(target);
1535     }
1536 #endif
1537 
1538     bool success = false;
1539 
1540     if (ConditionPassed(opcode))
1541     {
1542         EmulateInstruction::Context context;
1543         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1544         const uint32_t pc = ReadCoreReg(PC_REG, &success);
1545         addr_t lr; // next instruction address
1546         if (!success)
1547             return false;
1548         uint32_t Rm; // the register with the target address
1549         switch (encoding) {
1550         case eEncodingT1:
1551             lr = (pc - 2) | 1u; // return address
1552             Rm = Bits32(opcode, 6, 3);
1553             // if m == 15 then UNPREDICTABLE;
1554             if (Rm == 15)
1555                 return false;
1556             if (InITBlock() && !LastInITBlock())
1557                 return false;
1558             break;
1559         case eEncodingA1:
1560             lr = pc - 4; // return address
1561             Rm = Bits32(opcode, 3, 0);
1562             // if m == 15 then UNPREDICTABLE;
1563             if (Rm == 15)
1564                 return false;
1565             break;
1566         default:
1567             return false;
1568         }
1569         addr_t target = ReadCoreReg (Rm, &success);
1570         if (!success)
1571             return false;
1572         RegisterInfo dwarf_reg;
1573         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1574         context.SetRegister (dwarf_reg);
1575         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1576             return false;
1577         if (!BXWritePC(context, target))
1578             return false;
1579     }
1580     return true;
1581 }
1582 
1583 // Branch and Exchange causes a branch to an address and instruction set specified by a register.
1584 bool
EmulateBXRm(const uint32_t opcode,const ARMEncoding encoding)1585 EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding)
1586 {
1587 #if 0
1588     // ARM pseudo code...
1589     if (ConditionPassed())
1590     {
1591         EncodingSpecificOperations();
1592         BXWritePC(R[m]);
1593     }
1594 #endif
1595 
1596     if (ConditionPassed(opcode))
1597     {
1598         EmulateInstruction::Context context;
1599         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1600         uint32_t Rm; // the register with the target address
1601         switch (encoding) {
1602         case eEncodingT1:
1603             Rm = Bits32(opcode, 6, 3);
1604             if (InITBlock() && !LastInITBlock())
1605                 return false;
1606             break;
1607         case eEncodingA1:
1608             Rm = Bits32(opcode, 3, 0);
1609             break;
1610         default:
1611             return false;
1612         }
1613         bool success = false;
1614         addr_t target = ReadCoreReg (Rm, &success);
1615         if (!success)
1616             return false;
1617 
1618         RegisterInfo dwarf_reg;
1619         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1620         context.SetRegister (dwarf_reg);
1621         if (!BXWritePC(context, target))
1622             return false;
1623     }
1624     return true;
1625 }
1626 
1627 // Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an
1628 // address and instruction set specified by a register as though it were a BX instruction.
1629 //
1630 // TODO: Emulate Jazelle architecture?
1631 //       We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation.
1632 bool
EmulateBXJRm(const uint32_t opcode,const ARMEncoding encoding)1633 EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding)
1634 {
1635 #if 0
1636     // ARM pseudo code...
1637     if (ConditionPassed())
1638     {
1639         EncodingSpecificOperations();
1640         if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
1641             BXWritePC(R[m]);
1642         else
1643             if JazelleAcceptsExecution() then
1644                 SwitchToJazelleExecution();
1645             else
1646                 SUBARCHITECTURE_DEFINED handler call;
1647     }
1648 #endif
1649 
1650     if (ConditionPassed(opcode))
1651     {
1652         EmulateInstruction::Context context;
1653         context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1654         uint32_t Rm; // the register with the target address
1655         switch (encoding) {
1656         case eEncodingT1:
1657             Rm = Bits32(opcode, 19, 16);
1658             if (BadReg(Rm))
1659                 return false;
1660             if (InITBlock() && !LastInITBlock())
1661                 return false;
1662             break;
1663         case eEncodingA1:
1664             Rm = Bits32(opcode, 3, 0);
1665             if (Rm == 15)
1666                 return false;
1667             break;
1668         default:
1669             return false;
1670         }
1671         bool success = false;
1672         addr_t target = ReadCoreReg (Rm, &success);
1673         if (!success)
1674             return false;
1675 
1676         RegisterInfo dwarf_reg;
1677         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1678         context.SetRegister (dwarf_reg);
1679         if (!BXWritePC(context, target))
1680             return false;
1681     }
1682     return true;
1683 }
1684 
1685 // Set r7 to point to some ip offset.
1686 // SUB (immediate)
1687 bool
EmulateSUBR7IPImm(const uint32_t opcode,const ARMEncoding encoding)1688 EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding)
1689 {
1690 #if 0
1691     // ARM pseudo code...
1692     if (ConditionPassed())
1693     {
1694         EncodingSpecificOperations();
1695         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1696         if d == 15 then // Can only occur for ARM encoding
1697            ALUWritePC(result); // setflags is always FALSE here
1698         else
1699             R[d] = result;
1700             if setflags then
1701                 APSR.N = result<31>;
1702                 APSR.Z = IsZeroBit(result);
1703                 APSR.C = carry;
1704                 APSR.V = overflow;
1705     }
1706 #endif
1707 
1708     if (ConditionPassed(opcode))
1709     {
1710         bool success = false;
1711         const addr_t ip = ReadCoreReg (12, &success);
1712         if (!success)
1713             return false;
1714         uint32_t imm32;
1715         switch (encoding) {
1716         case eEncodingA1:
1717             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1718             break;
1719         default:
1720             return false;
1721         }
1722         addr_t ip_offset = imm32;
1723         addr_t addr = ip - ip_offset; // the adjusted ip value
1724 
1725         EmulateInstruction::Context context;
1726         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1727         RegisterInfo dwarf_reg;
1728         GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg);
1729         context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
1730 
1731         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
1732             return false;
1733     }
1734     return true;
1735 }
1736 
1737 // Set ip to point to some stack offset.
1738 // SUB (SP minus immediate)
1739 bool
EmulateSUBIPSPImm(const uint32_t opcode,const ARMEncoding encoding)1740 EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding)
1741 {
1742 #if 0
1743     // ARM pseudo code...
1744     if (ConditionPassed())
1745     {
1746         EncodingSpecificOperations();
1747         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1748         if d == 15 then // Can only occur for ARM encoding
1749            ALUWritePC(result); // setflags is always FALSE here
1750         else
1751             R[d] = result;
1752             if setflags then
1753                 APSR.N = result<31>;
1754                 APSR.Z = IsZeroBit(result);
1755                 APSR.C = carry;
1756                 APSR.V = overflow;
1757     }
1758 #endif
1759 
1760     if (ConditionPassed(opcode))
1761     {
1762         bool success = false;
1763         const addr_t sp = ReadCoreReg (SP_REG, &success);
1764         if (!success)
1765             return false;
1766         uint32_t imm32;
1767         switch (encoding) {
1768         case eEncodingA1:
1769             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1770             break;
1771         default:
1772             return false;
1773         }
1774         addr_t sp_offset = imm32;
1775         addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1776 
1777         EmulateInstruction::Context context;
1778         context.type = EmulateInstruction::eContextRegisterPlusOffset;
1779         RegisterInfo dwarf_reg;
1780         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
1781         context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
1782 
1783         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
1784             return false;
1785     }
1786     return true;
1787 }
1788 
1789 // This instruction subtracts an immediate value from the SP value, and writes
1790 // the result to the destination register.
1791 //
1792 // If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage.
1793 bool
EmulateSUBSPImm(const uint32_t opcode,const ARMEncoding encoding)1794 EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding)
1795 {
1796 #if 0
1797     // ARM pseudo code...
1798     if (ConditionPassed())
1799     {
1800         EncodingSpecificOperations();
1801         (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1802         if d == 15 then        // Can only occur for ARM encoding
1803            ALUWritePC(result); // setflags is always FALSE here
1804         else
1805             R[d] = result;
1806             if setflags then
1807                 APSR.N = result<31>;
1808                 APSR.Z = IsZeroBit(result);
1809                 APSR.C = carry;
1810                 APSR.V = overflow;
1811     }
1812 #endif
1813 
1814     bool success = false;
1815     if (ConditionPassed(opcode))
1816     {
1817         const addr_t sp = ReadCoreReg (SP_REG, &success);
1818         if (!success)
1819             return false;
1820 
1821         uint32_t Rd;
1822         bool setflags;
1823         uint32_t imm32;
1824         switch (encoding) {
1825         case eEncodingT1:
1826             Rd = 13;
1827             setflags = false;
1828             imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1829             break;
1830         case eEncodingT2:
1831             Rd = Bits32(opcode, 11, 8);
1832             setflags = BitIsSet(opcode, 20);
1833             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1834             if (Rd == 15 && setflags)
1835                 return EmulateCMPImm(opcode, eEncodingT2);
1836             if (Rd == 15 && !setflags)
1837                 return false;
1838             break;
1839         case eEncodingT3:
1840             Rd = Bits32(opcode, 11, 8);
1841             setflags = false;
1842             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
1843             if (Rd == 15)
1844                 return false;
1845             break;
1846         case eEncodingA1:
1847             Rd = Bits32(opcode, 15, 12);
1848             setflags = BitIsSet(opcode, 20);
1849             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1850 
1851             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1852             if (Rd == 15 && setflags)
1853                 return EmulateSUBSPcLrEtc (opcode, encoding);
1854             break;
1855         default:
1856             return false;
1857         }
1858         AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
1859 
1860         EmulateInstruction::Context context;
1861         if (Rd == 13)
1862         {
1863             uint64_t imm64 = imm32;  // Need to expand it to 64 bits before attempting to negate it, or the wrong
1864                                      // value gets passed down to context.SetImmediateSigned.
1865             context.type = EmulateInstruction::eContextAdjustStackPointer;
1866             context.SetImmediateSigned (-imm64); // the stack pointer offset
1867         }
1868         else
1869         {
1870             context.type = EmulateInstruction::eContextImmediate;
1871             context.SetNoArgs ();
1872         }
1873 
1874         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
1875             return false;
1876     }
1877     return true;
1878 }
1879 
1880 // A store operation to the stack that also updates the SP.
1881 bool
EmulateSTRRtSP(const uint32_t opcode,const ARMEncoding encoding)1882 EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding)
1883 {
1884 #if 0
1885     // ARM pseudo code...
1886     if (ConditionPassed())
1887     {
1888         EncodingSpecificOperations();
1889         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1890         address = if index then offset_addr else R[n];
1891         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1892         if wback then R[n] = offset_addr;
1893     }
1894 #endif
1895 
1896     bool conditional = false;
1897     bool success = false;
1898     if (ConditionPassed(opcode, &conditional))
1899     {
1900         const uint32_t addr_byte_size = GetAddressByteSize();
1901         const addr_t sp = ReadCoreReg (SP_REG, &success);
1902         if (!success)
1903             return false;
1904         uint32_t Rt; // the source register
1905         uint32_t imm12;
1906         uint32_t Rn;  // This function assumes Rn is the SP, but we should verify that.
1907 
1908         bool index;
1909         bool add;
1910         bool wback;
1911         switch (encoding) {
1912         case eEncodingA1:
1913             Rt = Bits32(opcode, 15, 12);
1914             imm12 = Bits32(opcode, 11, 0);
1915             Rn = Bits32 (opcode, 19, 16);
1916 
1917             if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
1918                 return false;
1919 
1920             index = BitIsSet (opcode, 24);
1921             add = BitIsSet (opcode, 23);
1922             wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
1923 
1924             if (wback && ((Rn == 15) || (Rn == Rt)))
1925                 return false;
1926             break;
1927         default:
1928             return false;
1929         }
1930         addr_t offset_addr;
1931         if (add)
1932             offset_addr = sp + imm12;
1933         else
1934             offset_addr = sp - imm12;
1935 
1936         addr_t addr;
1937         if (index)
1938             addr = offset_addr;
1939         else
1940             addr = sp;
1941 
1942         EmulateInstruction::Context context;
1943         if (conditional)
1944             context.type = EmulateInstruction::eContextRegisterStore;
1945         else
1946             context.type = EmulateInstruction::eContextPushRegisterOnStack;
1947         RegisterInfo sp_reg;
1948         RegisterInfo dwarf_reg;
1949 
1950         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1951         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
1952         context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
1953         if (Rt != 15)
1954         {
1955             uint32_t reg_value = ReadCoreReg(Rt, &success);
1956             if (!success)
1957                 return false;
1958             if (!MemUWrite (context, addr, reg_value, addr_byte_size))
1959                 return false;
1960         }
1961         else
1962         {
1963             const uint32_t pc = ReadCoreReg(PC_REG, &success);
1964             if (!success)
1965                 return false;
1966             if (!MemUWrite (context, addr, pc, addr_byte_size))
1967                 return false;
1968         }
1969 
1970 
1971         if (wback)
1972         {
1973             context.type = EmulateInstruction::eContextAdjustStackPointer;
1974             context.SetImmediateSigned (addr - sp);
1975             if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr))
1976                 return false;
1977         }
1978     }
1979     return true;
1980 }
1981 
1982 // Vector Push stores multiple extension registers to the stack.
1983 // It also updates SP to point to the start of the stored data.
1984 bool
EmulateVPUSH(const uint32_t opcode,const ARMEncoding encoding)1985 EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding)
1986 {
1987 #if 0
1988     // ARM pseudo code...
1989     if (ConditionPassed())
1990     {
1991         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1992         address = SP - imm32;
1993         SP = SP - imm32;
1994         if single_regs then
1995             for r = 0 to regs-1
1996                 MemA[address,4] = S[d+r]; address = address+4;
1997         else
1998             for r = 0 to regs-1
1999                 // Store as two word-aligned words in the correct order for current endianness.
2000                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
2001                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
2002                 address = address+8;
2003     }
2004 #endif
2005 
2006     bool success = false;
2007     bool conditional = false;
2008     if (ConditionPassed(opcode, &conditional))
2009     {
2010         const uint32_t addr_byte_size = GetAddressByteSize();
2011         const addr_t sp = ReadCoreReg (SP_REG, &success);
2012         if (!success)
2013             return false;
2014         bool single_regs;
2015         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2016         uint32_t imm32; // stack offset
2017         uint32_t regs;  // number of registers
2018         switch (encoding) {
2019         case eEncodingT1:
2020         case eEncodingA1:
2021             single_regs = false;
2022             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2023             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2024             // If UInt(imm8) is odd, see "FSTMX".
2025             regs = Bits32(opcode, 7, 0) / 2;
2026             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2027             if (regs == 0 || regs > 16 || (d + regs) > 32)
2028                 return false;
2029             break;
2030         case eEncodingT2:
2031         case eEncodingA2:
2032             single_regs = true;
2033             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2034             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2035             regs = Bits32(opcode, 7, 0);
2036             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2037             if (regs == 0 || regs > 16 || (d + regs) > 32)
2038                 return false;
2039             break;
2040         default:
2041             return false;
2042         }
2043         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2044         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2045         addr_t sp_offset = imm32;
2046         addr_t addr = sp - sp_offset;
2047         uint32_t i;
2048 
2049         EmulateInstruction::Context context;
2050         if (conditional)
2051             context.type = EmulateInstruction::eContextRegisterStore;
2052         else
2053             context.type = EmulateInstruction::eContextPushRegisterOnStack;
2054         RegisterInfo dwarf_reg;
2055         RegisterInfo sp_reg;
2056         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2057         for (i=0; i<regs; ++i)
2058         {
2059             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2060             context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
2061             // uint64_t to accommodate 64-bit registers.
2062             uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success);
2063             if (!success)
2064                 return false;
2065             if (!MemAWrite (context, addr, reg_value, reg_byte_size))
2066                 return false;
2067             addr += reg_byte_size;
2068         }
2069 
2070         context.type = EmulateInstruction::eContextAdjustStackPointer;
2071         context.SetImmediateSigned (-sp_offset);
2072 
2073         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2074             return false;
2075     }
2076     return true;
2077 }
2078 
2079 // Vector Pop loads multiple extension registers from the stack.
2080 // It also updates SP to point just above the loaded data.
2081 bool
EmulateVPOP(const uint32_t opcode,const ARMEncoding encoding)2082 EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding)
2083 {
2084 #if 0
2085     // ARM pseudo code...
2086     if (ConditionPassed())
2087     {
2088         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2089         address = SP;
2090         SP = SP + imm32;
2091         if single_regs then
2092             for r = 0 to regs-1
2093                 S[d+r] = MemA[address,4]; address = address+4;
2094         else
2095             for r = 0 to regs-1
2096                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2097                 // Combine the word-aligned words in the correct order for current endianness.
2098                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2099     }
2100 #endif
2101 
2102     bool success = false;
2103     bool conditional = false;
2104     if (ConditionPassed(opcode, &conditional))
2105     {
2106         const uint32_t addr_byte_size = GetAddressByteSize();
2107         const addr_t sp = ReadCoreReg (SP_REG, &success);
2108         if (!success)
2109             return false;
2110         bool single_regs;
2111         uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2112         uint32_t imm32; // stack offset
2113         uint32_t regs;  // number of registers
2114         switch (encoding) {
2115         case eEncodingT1:
2116         case eEncodingA1:
2117             single_regs = false;
2118             d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2119             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2120             // If UInt(imm8) is odd, see "FLDMX".
2121             regs = Bits32(opcode, 7, 0) / 2;
2122             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2123             if (regs == 0 || regs > 16 || (d + regs) > 32)
2124                 return false;
2125             break;
2126         case eEncodingT2:
2127         case eEncodingA2:
2128             single_regs = true;
2129             d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2130             imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2131             regs = Bits32(opcode, 7, 0);
2132             // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2133             if (regs == 0 || regs > 16 || (d + regs) > 32)
2134                 return false;
2135             break;
2136         default:
2137             return false;
2138         }
2139         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2140         uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2141         addr_t sp_offset = imm32;
2142         addr_t addr = sp;
2143         uint32_t i;
2144         uint64_t data; // uint64_t to accomodate 64-bit registers.
2145 
2146         EmulateInstruction::Context context;
2147         if (conditional)
2148             context.type = EmulateInstruction::eContextRegisterLoad;
2149         else
2150             context.type = EmulateInstruction::eContextPopRegisterOffStack;
2151         RegisterInfo dwarf_reg;
2152         RegisterInfo sp_reg;
2153         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2154         for (i=0; i<regs; ++i)
2155         {
2156             GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2157             context.SetRegisterPlusOffset (sp_reg, addr - sp);
2158             data = MemARead(context, addr, reg_byte_size, 0, &success);
2159             if (!success)
2160                 return false;
2161             if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2162                 return false;
2163             addr += reg_byte_size;
2164         }
2165 
2166         context.type = EmulateInstruction::eContextAdjustStackPointer;
2167         context.SetImmediateSigned (sp_offset);
2168 
2169         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2170             return false;
2171     }
2172     return true;
2173 }
2174 
2175 // SVC (previously SWI)
2176 bool
EmulateSVC(const uint32_t opcode,const ARMEncoding encoding)2177 EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding)
2178 {
2179 #if 0
2180     // ARM pseudo code...
2181     if (ConditionPassed())
2182     {
2183         EncodingSpecificOperations();
2184         CallSupervisor();
2185     }
2186 #endif
2187 
2188     bool success = false;
2189 
2190     if (ConditionPassed(opcode))
2191     {
2192         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2193         addr_t lr; // next instruction address
2194         if (!success)
2195             return false;
2196         uint32_t imm32; // the immediate constant
2197         uint32_t mode;  // ARM or Thumb mode
2198         switch (encoding) {
2199         case eEncodingT1:
2200             lr = (pc + 2) | 1u; // return address
2201             imm32 = Bits32(opcode, 7, 0);
2202             mode = eModeThumb;
2203             break;
2204         case eEncodingA1:
2205             lr = pc + 4; // return address
2206             imm32 = Bits32(opcode, 23, 0);
2207             mode = eModeARM;
2208             break;
2209         default:
2210             return false;
2211         }
2212 
2213         EmulateInstruction::Context context;
2214         context.type = EmulateInstruction::eContextSupervisorCall;
2215         context.SetISAAndImmediate (mode, imm32);
2216         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
2217             return false;
2218     }
2219     return true;
2220 }
2221 
2222 // If Then makes up to four following instructions (the IT block) conditional.
2223 bool
EmulateIT(const uint32_t opcode,const ARMEncoding encoding)2224 EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding)
2225 {
2226 #if 0
2227     // ARM pseudo code...
2228     EncodingSpecificOperations();
2229     ITSTATE.IT<7:0> = firstcond:mask;
2230 #endif
2231 
2232     m_it_session.InitIT(Bits32(opcode, 7, 0));
2233     return true;
2234 }
2235 
2236 bool
EmulateNop(const uint32_t opcode,const ARMEncoding encoding)2237 EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding)
2238 {
2239     // NOP, nothing to do...
2240     return true;
2241 }
2242 
2243 // Branch causes a branch to a target address.
2244 bool
EmulateB(const uint32_t opcode,const ARMEncoding encoding)2245 EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding)
2246 {
2247 #if 0
2248     // ARM pseudo code...
2249     if (ConditionPassed())
2250     {
2251         EncodingSpecificOperations();
2252         BranchWritePC(PC + imm32);
2253     }
2254 #endif
2255 
2256     bool success = false;
2257 
2258     if (ConditionPassed(opcode))
2259     {
2260         EmulateInstruction::Context context;
2261         context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2262         const uint32_t pc = ReadCoreReg(PC_REG, &success);
2263         if (!success)
2264             return false;
2265         addr_t target; // target address
2266         int32_t imm32; // PC-relative offset
2267         switch (encoding) {
2268         case eEncodingT1:
2269             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2270             imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2271             target = pc + imm32;
2272             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2273             break;
2274         case eEncodingT2:
2275             imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0));
2276             target = pc + imm32;
2277             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2278             break;
2279         case eEncodingT3:
2280             // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2281             {
2282             uint32_t S = Bit32(opcode, 26);
2283             uint32_t imm6 = Bits32(opcode, 21, 16);
2284             uint32_t J1 = Bit32(opcode, 13);
2285             uint32_t J2 = Bit32(opcode, 11);
2286             uint32_t imm11 = Bits32(opcode, 10, 0);
2287             uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2288             imm32 = llvm::SignExtend32<21>(imm21);
2289             target = pc + imm32;
2290             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2291             break;
2292             }
2293         case eEncodingT4:
2294             {
2295             uint32_t S = Bit32(opcode, 26);
2296             uint32_t imm10 = Bits32(opcode, 25, 16);
2297             uint32_t J1 = Bit32(opcode, 13);
2298             uint32_t J2 = Bit32(opcode, 11);
2299             uint32_t imm11 = Bits32(opcode, 10, 0);
2300             uint32_t I1 = !(J1 ^ S);
2301             uint32_t I2 = !(J2 ^ S);
2302             uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2303             imm32 = llvm::SignExtend32<25>(imm25);
2304             target = pc + imm32;
2305             context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2306             break;
2307             }
2308         case eEncodingA1:
2309             imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2310             target = pc + imm32;
2311             context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
2312             break;
2313         default:
2314             return false;
2315         }
2316         if (!BranchWritePC(context, target))
2317             return false;
2318     }
2319     return true;
2320 }
2321 
2322 // Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
2323 // zero and conditionally branch forward a constant value.  They do not affect the condition flags.
2324 // CBNZ, CBZ
2325 bool
EmulateCB(const uint32_t opcode,const ARMEncoding encoding)2326 EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding)
2327 {
2328 #if 0
2329     // ARM pseudo code...
2330     EncodingSpecificOperations();
2331     if nonzero ^ IsZero(R[n]) then
2332         BranchWritePC(PC + imm32);
2333 #endif
2334 
2335     bool success = false;
2336 
2337     // Read the register value from the operand register Rn.
2338     uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2339     if (!success)
2340         return false;
2341 
2342     EmulateInstruction::Context context;
2343     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2344     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2345     if (!success)
2346         return false;
2347 
2348     addr_t target;  // target address
2349     uint32_t imm32; // PC-relative offset to branch forward
2350     bool nonzero;
2351     switch (encoding) {
2352     case eEncodingT1:
2353         imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2354         nonzero = BitIsSet(opcode, 11);
2355         target = pc + imm32;
2356         context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2357         break;
2358     default:
2359         return false;
2360     }
2361     if (nonzero ^ (reg_val == 0))
2362         if (!BranchWritePC(context, target))
2363             return false;
2364 
2365     return true;
2366 }
2367 
2368 // Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
2369 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2370 // The branch length is twice the value of the byte returned from the table.
2371 //
2372 // Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
2373 // A base register provides a pointer to the table, and a second register supplies an index into the table.
2374 // The branch length is twice the value of the halfword returned from the table.
2375 // TBB, TBH
2376 bool
EmulateTB(const uint32_t opcode,const ARMEncoding encoding)2377 EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding)
2378 {
2379 #if 0
2380     // ARM pseudo code...
2381     EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2382     if is_tbh then
2383         halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2384     else
2385         halfwords = UInt(MemU[R[n]+R[m], 1]);
2386     BranchWritePC(PC + 2*halfwords);
2387 #endif
2388 
2389     bool success = false;
2390 
2391     uint32_t Rn;     // the base register which contains the address of the table of branch lengths
2392     uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
2393     bool is_tbh;     // true if table branch halfword
2394     switch (encoding) {
2395     case eEncodingT1:
2396         Rn = Bits32(opcode, 19, 16);
2397         Rm = Bits32(opcode, 3, 0);
2398         is_tbh = BitIsSet(opcode, 4);
2399         if (Rn == 13 || BadReg(Rm))
2400             return false;
2401         if (InITBlock() && !LastInITBlock())
2402             return false;
2403         break;
2404     default:
2405         return false;
2406     }
2407 
2408     // Read the address of the table from the operand register Rn.
2409     // The PC can be used, in which case the table immediately follows this instruction.
2410     uint32_t base = ReadCoreReg(Rm, &success);
2411     if (!success)
2412         return false;
2413 
2414     // the table index
2415     uint32_t index = ReadCoreReg(Rm, &success);
2416     if (!success)
2417         return false;
2418 
2419     // the offsetted table address
2420     addr_t addr = base + (is_tbh ? index*2 : index);
2421 
2422     // PC-relative offset to branch forward
2423     EmulateInstruction::Context context;
2424     context.type = EmulateInstruction::eContextTableBranchReadMemory;
2425     uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2426     if (!success)
2427         return false;
2428 
2429     const uint32_t pc = ReadCoreReg(PC_REG, &success);
2430     if (!success)
2431         return false;
2432 
2433     // target address
2434     addr_t target = pc + offset;
2435     context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2436     context.SetISAAndImmediateSigned (eModeThumb, 4 + offset);
2437 
2438     if (!BranchWritePC(context, target))
2439         return false;
2440 
2441     return true;
2442 }
2443 
2444 // This instruction adds an immediate value to a register value, and writes the result to the destination register.
2445 // It can optionally update the condition flags based on the result.
2446 bool
EmulateADDImmThumb(const uint32_t opcode,const ARMEncoding encoding)2447 EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding)
2448 {
2449 #if 0
2450     if ConditionPassed() then
2451         EncodingSpecificOperations();
2452         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2453         R[d] = result;
2454         if setflags then
2455             APSR.N = result<31>;
2456             APSR.Z = IsZeroBit(result);
2457             APSR.C = carry;
2458             APSR.V = overflow;
2459 #endif
2460 
2461     bool success = false;
2462 
2463     if (ConditionPassed(opcode))
2464     {
2465         uint32_t d;
2466         uint32_t n;
2467         bool setflags;
2468         uint32_t imm32;
2469         uint32_t carry_out;
2470 
2471         //EncodingSpecificOperations();
2472         switch (encoding)
2473         {
2474             case eEncodingT1:
2475                 // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32);
2476                 d = Bits32 (opcode, 2, 0);
2477                 n = Bits32 (opcode, 5, 3);
2478                 setflags = !InITBlock();
2479                 imm32 = Bits32 (opcode, 8,6);
2480 
2481                 break;
2482 
2483             case eEncodingT2:
2484                 // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32);
2485                 d = Bits32 (opcode, 10, 8);
2486                 n = Bits32 (opcode, 10, 8);
2487                 setflags = !InITBlock();
2488                 imm32 = Bits32 (opcode, 7, 0);
2489 
2490                 break;
2491 
2492             case eEncodingT3:
2493                 // if Rd == '1111' && S == '1' then SEE CMN (immediate);
2494                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2495                 // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8);
2496                 d = Bits32 (opcode, 11, 8);
2497                 n = Bits32 (opcode, 19, 16);
2498                 setflags = BitIsSet (opcode, 20);
2499                 imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out);
2500 
2501                 // if BadReg(d) || n == 15 then UNPREDICTABLE;
2502                 if (BadReg (d) || (n == 15))
2503                     return false;
2504 
2505                 break;
2506 
2507             case eEncodingT4:
2508             {
2509                 // if Rn == '1111' then SEE ADR;
2510                 // if Rn == '1101' then SEE ADD (SP plus immediate);
2511                 // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
2512                 d = Bits32 (opcode, 11, 8);
2513                 n = Bits32 (opcode, 19, 16);
2514                 setflags = false;
2515                 uint32_t i = Bit32 (opcode, 26);
2516                 uint32_t imm3 = Bits32 (opcode, 14, 12);
2517                 uint32_t imm8 = Bits32 (opcode, 7, 0);
2518                 imm32 = (i << 11) | (imm3 << 8) | imm8;
2519 
2520                 // if BadReg(d) then UNPREDICTABLE;
2521                 if (BadReg (d))
2522                     return false;
2523 
2524                 break;
2525             }
2526             default:
2527                 return false;
2528         }
2529 
2530         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2531         if (!success)
2532             return false;
2533 
2534         //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2535         AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
2536 
2537         RegisterInfo reg_n;
2538         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
2539 
2540         EmulateInstruction::Context context;
2541         context.type = eContextArithmetic;
2542         context.SetRegisterPlusOffset (reg_n, imm32);
2543 
2544         //R[d] = result;
2545         //if setflags then
2546             //APSR.N = result<31>;
2547             //APSR.Z = IsZeroBit(result);
2548             //APSR.C = carry;
2549             //APSR.V = overflow;
2550         if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
2551             return false;
2552 
2553     }
2554     return true;
2555 }
2556 
2557 // This instruction adds an immediate value to a register value, and writes the result to the destination
2558 // register.  It can optionally update the condition flags based on the result.
2559 bool
EmulateADDImmARM(const uint32_t opcode,const ARMEncoding encoding)2560 EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding)
2561 {
2562 #if 0
2563     // ARM pseudo code...
2564     if ConditionPassed() then
2565         EncodingSpecificOperations();
2566         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2567         if d == 15 then
2568             ALUWritePC(result); // setflags is always FALSE here
2569         else
2570             R[d] = result;
2571             if setflags then
2572                 APSR.N = result<31>;
2573                 APSR.Z = IsZeroBit(result);
2574                 APSR.C = carry;
2575                 APSR.V = overflow;
2576 #endif
2577 
2578     bool success = false;
2579 
2580     if (ConditionPassed(opcode))
2581     {
2582         uint32_t Rd, Rn;
2583         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
2584         bool setflags;
2585         switch (encoding)
2586         {
2587         case eEncodingA1:
2588             Rd = Bits32(opcode, 15, 12);
2589             Rn = Bits32(opcode, 19, 16);
2590             setflags = BitIsSet(opcode, 20);
2591             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2592             break;
2593         default:
2594             return false;
2595         }
2596 
2597         // Read the first operand.
2598         uint32_t val1 = ReadCoreReg(Rn, &success);
2599         if (!success)
2600             return false;
2601 
2602         AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
2603 
2604         EmulateInstruction::Context context;
2605         context.type = eContextArithmetic;
2606         RegisterInfo dwarf_reg;
2607         GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
2608         context.SetRegisterPlusOffset (dwarf_reg, imm32);
2609 
2610         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2611             return false;
2612     }
2613     return true;
2614 }
2615 
2616 // This instruction adds a register value and an optionally-shifted register value, and writes the result
2617 // to the destination register. It can optionally update the condition flags based on the result.
2618 bool
EmulateADDReg(const uint32_t opcode,const ARMEncoding encoding)2619 EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding)
2620 {
2621 #if 0
2622     // ARM pseudo code...
2623     if ConditionPassed() then
2624         EncodingSpecificOperations();
2625         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2626         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2627         if d == 15 then
2628             ALUWritePC(result); // setflags is always FALSE here
2629         else
2630             R[d] = result;
2631             if setflags then
2632                 APSR.N = result<31>;
2633                 APSR.Z = IsZeroBit(result);
2634                 APSR.C = carry;
2635                 APSR.V = overflow;
2636 #endif
2637 
2638     bool success = false;
2639 
2640     if (ConditionPassed(opcode))
2641     {
2642         uint32_t Rd, Rn, Rm;
2643         ARM_ShifterType shift_t;
2644         uint32_t shift_n; // the shift applied to the value read from Rm
2645         bool setflags;
2646         switch (encoding)
2647         {
2648         case eEncodingT1:
2649             Rd = Bits32(opcode, 2, 0);
2650             Rn = Bits32(opcode, 5, 3);
2651             Rm = Bits32(opcode, 8, 6);
2652             setflags = !InITBlock();
2653             shift_t = SRType_LSL;
2654             shift_n = 0;
2655             break;
2656         case eEncodingT2:
2657             Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2658             Rm = Bits32(opcode, 6, 3);
2659             setflags = false;
2660             shift_t = SRType_LSL;
2661             shift_n = 0;
2662             if (Rn == 15 && Rm == 15)
2663                 return false;
2664             if (Rd == 15 && InITBlock() && !LastInITBlock())
2665                 return false;
2666             break;
2667         case eEncodingA1:
2668             Rd = Bits32(opcode, 15, 12);
2669             Rn = Bits32(opcode, 19, 16);
2670             Rm = Bits32(opcode, 3, 0);
2671             setflags = BitIsSet(opcode, 20);
2672             shift_n = DecodeImmShiftARM(opcode, shift_t);
2673             break;
2674         default:
2675             return false;
2676         }
2677 
2678         // Read the first operand.
2679         uint32_t val1 = ReadCoreReg(Rn, &success);
2680         if (!success)
2681             return false;
2682 
2683         // Read the second operand.
2684         uint32_t val2 = ReadCoreReg(Rm, &success);
2685         if (!success)
2686             return false;
2687 
2688         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2689         if (!success)
2690             return false;
2691         AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2692 
2693         EmulateInstruction::Context context;
2694         context.type = eContextArithmetic;
2695         RegisterInfo op1_reg;
2696         RegisterInfo op2_reg;
2697         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
2698         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
2699         context.SetRegisterRegisterOperands (op1_reg, op2_reg);
2700 
2701         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2702             return false;
2703     }
2704     return true;
2705 }
2706 
2707 // Compare Negative (immediate) adds a register value and an immediate value.
2708 // It updates the condition flags based on the result, and discards the result.
2709 bool
EmulateCMNImm(const uint32_t opcode,const ARMEncoding encoding)2710 EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding)
2711 {
2712 #if 0
2713     // ARM pseudo code...
2714     if ConditionPassed() then
2715         EncodingSpecificOperations();
2716         (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2717         APSR.N = result<31>;
2718         APSR.Z = IsZeroBit(result);
2719         APSR.C = carry;
2720         APSR.V = overflow;
2721 #endif
2722 
2723     bool success = false;
2724 
2725     uint32_t Rn; // the first operand
2726     uint32_t imm32; // the immediate value to be compared with
2727     switch (encoding) {
2728     case eEncodingT1:
2729         Rn = Bits32(opcode, 19, 16);
2730         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2731         if (Rn == 15)
2732             return false;
2733         break;
2734     case eEncodingA1:
2735         Rn = Bits32(opcode, 19, 16);
2736         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2737         break;
2738     default:
2739         return false;
2740     }
2741     // Read the register value from the operand register Rn.
2742     uint32_t reg_val = ReadCoreReg(Rn, &success);
2743     if (!success)
2744         return false;
2745 
2746     AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
2747 
2748     EmulateInstruction::Context context;
2749     context.type = EmulateInstruction::eContextImmediate;
2750     context.SetNoArgs ();
2751     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2752         return false;
2753 
2754     return true;
2755 }
2756 
2757 // Compare Negative (register) adds a register value and an optionally-shifted register value.
2758 // It updates the condition flags based on the result, and discards the result.
2759 bool
EmulateCMNReg(const uint32_t opcode,const ARMEncoding encoding)2760 EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding)
2761 {
2762 #if 0
2763     // ARM pseudo code...
2764     if ConditionPassed() then
2765         EncodingSpecificOperations();
2766         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2767         (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2768         APSR.N = result<31>;
2769         APSR.Z = IsZeroBit(result);
2770         APSR.C = carry;
2771         APSR.V = overflow;
2772 #endif
2773 
2774     bool success = false;
2775 
2776     uint32_t Rn; // the first operand
2777     uint32_t Rm; // the second operand
2778     ARM_ShifterType shift_t;
2779     uint32_t shift_n; // the shift applied to the value read from Rm
2780     switch (encoding) {
2781     case eEncodingT1:
2782         Rn = Bits32(opcode, 2, 0);
2783         Rm = Bits32(opcode, 5, 3);
2784         shift_t = SRType_LSL;
2785         shift_n = 0;
2786         break;
2787     case eEncodingT2:
2788         Rn = Bits32(opcode, 19, 16);
2789         Rm = Bits32(opcode, 3, 0);
2790         shift_n = DecodeImmShiftThumb(opcode, shift_t);
2791         // if n == 15 || BadReg(m) then UNPREDICTABLE;
2792         if (Rn == 15 || BadReg(Rm))
2793             return false;
2794         break;
2795     case eEncodingA1:
2796         Rn = Bits32(opcode, 19, 16);
2797         Rm = Bits32(opcode, 3, 0);
2798         shift_n = DecodeImmShiftARM(opcode, shift_t);
2799         break;
2800     default:
2801         return false;
2802     }
2803     // Read the register value from register Rn.
2804     uint32_t val1 = ReadCoreReg(Rn, &success);
2805     if (!success)
2806         return false;
2807 
2808     // Read the register value from register Rm.
2809     uint32_t val2 = ReadCoreReg(Rm, &success);
2810     if (!success)
2811         return false;
2812 
2813     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2814     if (!success)
2815         return false;
2816     AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2817 
2818     EmulateInstruction::Context context;
2819     context.type = EmulateInstruction::eContextImmediate;
2820     context.SetNoArgs();
2821     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2822         return false;
2823 
2824     return true;
2825 }
2826 
2827 // Compare (immediate) subtracts an immediate value from a register value.
2828 // It updates the condition flags based on the result, and discards the result.
2829 bool
EmulateCMPImm(const uint32_t opcode,const ARMEncoding encoding)2830 EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding)
2831 {
2832 #if 0
2833     // ARM pseudo code...
2834     if ConditionPassed() then
2835         EncodingSpecificOperations();
2836         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2837         APSR.N = result<31>;
2838         APSR.Z = IsZeroBit(result);
2839         APSR.C = carry;
2840         APSR.V = overflow;
2841 #endif
2842 
2843     bool success = false;
2844 
2845     uint32_t Rn; // the first operand
2846     uint32_t imm32; // the immediate value to be compared with
2847     switch (encoding) {
2848     case eEncodingT1:
2849         Rn = Bits32(opcode, 10, 8);
2850         imm32 = Bits32(opcode, 7, 0);
2851         break;
2852     case eEncodingT2:
2853         Rn = Bits32(opcode, 19, 16);
2854         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2855         if (Rn == 15)
2856             return false;
2857         break;
2858     case eEncodingA1:
2859         Rn = Bits32(opcode, 19, 16);
2860         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2861         break;
2862     default:
2863         return false;
2864     }
2865     // Read the register value from the operand register Rn.
2866     uint32_t reg_val = ReadCoreReg(Rn, &success);
2867     if (!success)
2868         return false;
2869 
2870     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
2871 
2872     EmulateInstruction::Context context;
2873     context.type = EmulateInstruction::eContextImmediate;
2874     context.SetNoArgs ();
2875     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2876         return false;
2877 
2878     return true;
2879 }
2880 
2881 // Compare (register) subtracts an optionally-shifted register value from a register value.
2882 // It updates the condition flags based on the result, and discards the result.
2883 bool
EmulateCMPReg(const uint32_t opcode,const ARMEncoding encoding)2884 EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding)
2885 {
2886 #if 0
2887     // ARM pseudo code...
2888     if ConditionPassed() then
2889         EncodingSpecificOperations();
2890         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2891         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2892         APSR.N = result<31>;
2893         APSR.Z = IsZeroBit(result);
2894         APSR.C = carry;
2895         APSR.V = overflow;
2896 #endif
2897 
2898     bool success = false;
2899 
2900     uint32_t Rn; // the first operand
2901     uint32_t Rm; // the second operand
2902     ARM_ShifterType shift_t;
2903     uint32_t shift_n; // the shift applied to the value read from Rm
2904     switch (encoding) {
2905     case eEncodingT1:
2906         Rn = Bits32(opcode, 2, 0);
2907         Rm = Bits32(opcode, 5, 3);
2908         shift_t = SRType_LSL;
2909         shift_n = 0;
2910         break;
2911     case eEncodingT2:
2912         Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2913         Rm = Bits32(opcode, 6, 3);
2914         shift_t = SRType_LSL;
2915         shift_n = 0;
2916         if (Rn < 8 && Rm < 8)
2917             return false;
2918         if (Rn == 15 || Rm == 15)
2919             return false;
2920         break;
2921     case eEncodingA1:
2922         Rn = Bits32(opcode, 19, 16);
2923         Rm = Bits32(opcode, 3, 0);
2924         shift_n = DecodeImmShiftARM(opcode, shift_t);
2925         break;
2926     default:
2927         return false;
2928     }
2929     // Read the register value from register Rn.
2930     uint32_t val1 = ReadCoreReg(Rn, &success);
2931     if (!success)
2932         return false;
2933 
2934     // Read the register value from register Rm.
2935     uint32_t val2 = ReadCoreReg(Rm, &success);
2936     if (!success)
2937         return false;
2938 
2939     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2940     if (!success)
2941         return false;
2942     AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
2943 
2944     EmulateInstruction::Context context;
2945     context.type = EmulateInstruction::eContextImmediate;
2946     context.SetNoArgs();
2947     if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2948         return false;
2949 
2950     return true;
2951 }
2952 
2953 // Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
2954 // shifting in copies of its sign bit, and writes the result to the destination register.  It can
2955 // optionally update the condition flags based on the result.
2956 bool
EmulateASRImm(const uint32_t opcode,const ARMEncoding encoding)2957 EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding)
2958 {
2959 #if 0
2960     // ARM pseudo code...
2961     if ConditionPassed() then
2962         EncodingSpecificOperations();
2963         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2964         if d == 15 then         // Can only occur for ARM encoding
2965             ALUWritePC(result); // setflags is always FALSE here
2966         else
2967             R[d] = result;
2968             if setflags then
2969                 APSR.N = result<31>;
2970                 APSR.Z = IsZeroBit(result);
2971                 APSR.C = carry;
2972                 // APSR.V unchanged
2973 #endif
2974 
2975     return EmulateShiftImm (opcode, encoding, SRType_ASR);
2976 }
2977 
2978 // Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
2979 // shifting in copies of its sign bit, and writes the result to the destination register.
2980 // The variable number of bits is read from the bottom byte of a register. It can optionally update
2981 // the condition flags based on the result.
2982 bool
EmulateASRReg(const uint32_t opcode,const ARMEncoding encoding)2983 EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding)
2984 {
2985 #if 0
2986     // ARM pseudo code...
2987     if ConditionPassed() then
2988         EncodingSpecificOperations();
2989         shift_n = UInt(R[m]<7:0>);
2990         (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2991         R[d] = result;
2992         if setflags then
2993             APSR.N = result<31>;
2994             APSR.Z = IsZeroBit(result);
2995             APSR.C = carry;
2996             // APSR.V unchanged
2997 #endif
2998 
2999     return EmulateShiftReg (opcode, encoding, SRType_ASR);
3000 }
3001 
3002 // Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
3003 // shifting in zeros, and writes the result to the destination register.  It can optionally
3004 // update the condition flags based on the result.
3005 bool
EmulateLSLImm(const uint32_t opcode,const ARMEncoding encoding)3006 EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding)
3007 {
3008 #if 0
3009     // ARM pseudo code...
3010     if ConditionPassed() then
3011         EncodingSpecificOperations();
3012         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3013         if d == 15 then         // Can only occur for ARM encoding
3014             ALUWritePC(result); // setflags is always FALSE here
3015         else
3016             R[d] = result;
3017             if setflags then
3018                 APSR.N = result<31>;
3019                 APSR.Z = IsZeroBit(result);
3020                 APSR.C = carry;
3021                 // APSR.V unchanged
3022 #endif
3023 
3024     return EmulateShiftImm (opcode, encoding, SRType_LSL);
3025 }
3026 
3027 // Logical Shift Left (register) shifts a register value left by a variable number of bits,
3028 // shifting in zeros, and writes the result to the destination register.  The variable number
3029 // of bits is read from the bottom byte of a register. It can optionally update the condition
3030 // flags based on the result.
3031 bool
EmulateLSLReg(const uint32_t opcode,const ARMEncoding encoding)3032 EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding)
3033 {
3034 #if 0
3035     // ARM pseudo code...
3036     if ConditionPassed() then
3037         EncodingSpecificOperations();
3038         shift_n = UInt(R[m]<7:0>);
3039         (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3040         R[d] = result;
3041         if setflags then
3042             APSR.N = result<31>;
3043             APSR.Z = IsZeroBit(result);
3044             APSR.C = carry;
3045             // APSR.V unchanged
3046 #endif
3047 
3048     return EmulateShiftReg (opcode, encoding, SRType_LSL);
3049 }
3050 
3051 // Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
3052 // shifting in zeros, and writes the result to the destination register.  It can optionally
3053 // update the condition flags based on the result.
3054 bool
EmulateLSRImm(const uint32_t opcode,const ARMEncoding encoding)3055 EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding)
3056 {
3057 #if 0
3058     // ARM pseudo code...
3059     if ConditionPassed() then
3060         EncodingSpecificOperations();
3061         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3062         if d == 15 then         // Can only occur for ARM encoding
3063             ALUWritePC(result); // setflags is always FALSE here
3064         else
3065             R[d] = result;
3066             if setflags then
3067                 APSR.N = result<31>;
3068                 APSR.Z = IsZeroBit(result);
3069                 APSR.C = carry;
3070                 // APSR.V unchanged
3071 #endif
3072 
3073     return EmulateShiftImm (opcode, encoding, SRType_LSR);
3074 }
3075 
3076 // Logical Shift Right (register) shifts a register value right by a variable number of bits,
3077 // shifting in zeros, and writes the result to the destination register.  The variable number
3078 // of bits is read from the bottom byte of a register. It can optionally update the condition
3079 // flags based on the result.
3080 bool
EmulateLSRReg(const uint32_t opcode,const ARMEncoding encoding)3081 EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding)
3082 {
3083 #if 0
3084     // ARM pseudo code...
3085     if ConditionPassed() then
3086         EncodingSpecificOperations();
3087         shift_n = UInt(R[m]<7:0>);
3088         (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3089         R[d] = result;
3090         if setflags then
3091             APSR.N = result<31>;
3092             APSR.Z = IsZeroBit(result);
3093             APSR.C = carry;
3094             // APSR.V unchanged
3095 #endif
3096 
3097     return EmulateShiftReg (opcode, encoding, SRType_LSR);
3098 }
3099 
3100 // Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
3101 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3102 // It can optionally update the condition flags based on the result.
3103 bool
EmulateRORImm(const uint32_t opcode,const ARMEncoding encoding)3104 EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding)
3105 {
3106 #if 0
3107     // ARM pseudo code...
3108     if ConditionPassed() then
3109         EncodingSpecificOperations();
3110         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3111         if d == 15 then         // Can only occur for ARM encoding
3112             ALUWritePC(result); // setflags is always FALSE here
3113         else
3114             R[d] = result;
3115             if setflags then
3116                 APSR.N = result<31>;
3117                 APSR.Z = IsZeroBit(result);
3118                 APSR.C = carry;
3119                 // APSR.V unchanged
3120 #endif
3121 
3122     return EmulateShiftImm (opcode, encoding, SRType_ROR);
3123 }
3124 
3125 // Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
3126 // The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3127 // The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
3128 // flags based on the result.
3129 bool
EmulateRORReg(const uint32_t opcode,const ARMEncoding encoding)3130 EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding)
3131 {
3132 #if 0
3133     // ARM pseudo code...
3134     if ConditionPassed() then
3135         EncodingSpecificOperations();
3136         shift_n = UInt(R[m]<7:0>);
3137         (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3138         R[d] = result;
3139         if setflags then
3140             APSR.N = result<31>;
3141             APSR.Z = IsZeroBit(result);
3142             APSR.C = carry;
3143             // APSR.V unchanged
3144 #endif
3145 
3146     return EmulateShiftReg (opcode, encoding, SRType_ROR);
3147 }
3148 
3149 // Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
3150 // with the carry flag shifted into bit [31].
3151 //
3152 // RRX can optionally update the condition flags based on the result.
3153 // In that case, bit [0] is shifted into the carry flag.
3154 bool
EmulateRRX(const uint32_t opcode,const ARMEncoding encoding)3155 EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding)
3156 {
3157 #if 0
3158     // ARM pseudo code...
3159     if ConditionPassed() then
3160         EncodingSpecificOperations();
3161         (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3162         if d == 15 then         // Can only occur for ARM encoding
3163             ALUWritePC(result); // setflags is always FALSE here
3164         else
3165             R[d] = result;
3166             if setflags then
3167                 APSR.N = result<31>;
3168                 APSR.Z = IsZeroBit(result);
3169                 APSR.C = carry;
3170                 // APSR.V unchanged
3171 #endif
3172 
3173     return EmulateShiftImm (opcode, encoding, SRType_RRX);
3174 }
3175 
3176 bool
EmulateShiftImm(const uint32_t opcode,const ARMEncoding encoding,ARM_ShifterType shift_type)3177 EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3178 {
3179 //    assert(shift_type == SRType_ASR
3180 //           || shift_type == SRType_LSL
3181 //           || shift_type == SRType_LSR
3182 //           || shift_type == SRType_ROR
3183 //           || shift_type == SRType_RRX);
3184 
3185     bool success = false;
3186 
3187     if (ConditionPassed(opcode))
3188     {
3189         uint32_t Rd;    // the destination register
3190         uint32_t Rm;    // the first operand register
3191         uint32_t imm5;  // encoding for the shift amount
3192         uint32_t carry; // the carry bit after the shift operation
3193         bool setflags;
3194 
3195         // Special case handling!
3196         // A8.6.139 ROR (immediate) -- Encoding T1
3197         ARMEncoding use_encoding = encoding;
3198         if (shift_type == SRType_ROR && use_encoding == eEncodingT1)
3199         {
3200             // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
3201             // have the same decoding of bit fields as the other Thumb2 shift operations.
3202             use_encoding = eEncodingT2;
3203         }
3204 
3205         switch (use_encoding) {
3206         case eEncodingT1:
3207             // Due to the above special case handling!
3208             if (shift_type == SRType_ROR)
3209                 return false;
3210 
3211             Rd = Bits32(opcode, 2, 0);
3212             Rm = Bits32(opcode, 5, 3);
3213             setflags = !InITBlock();
3214             imm5 = Bits32(opcode, 10, 6);
3215             break;
3216         case eEncodingT2:
3217             // A8.6.141 RRX
3218             // There's no imm form of RRX instructions.
3219             if (shift_type == SRType_RRX)
3220                 return false;
3221 
3222             Rd = Bits32(opcode, 11, 8);
3223             Rm = Bits32(opcode, 3, 0);
3224             setflags = BitIsSet(opcode, 20);
3225             imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3226             if (BadReg(Rd) || BadReg(Rm))
3227                 return false;
3228             break;
3229         case eEncodingA1:
3230             Rd = Bits32(opcode, 15, 12);
3231             Rm = Bits32(opcode, 3, 0);
3232             setflags = BitIsSet(opcode, 20);
3233             imm5 = Bits32(opcode, 11, 7);
3234             break;
3235         default:
3236             return false;
3237         }
3238 
3239         // A8.6.139 ROR (immediate)
3240         if (shift_type == SRType_ROR && imm5 == 0)
3241             shift_type = SRType_RRX;
3242 
3243         // Get the first operand.
3244         uint32_t value = ReadCoreReg (Rm, &success);
3245         if (!success)
3246             return false;
3247 
3248         // Decode the shift amount if not RRX.
3249         uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3250 
3251         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3252         if (!success)
3253             return false;
3254 
3255         // The context specifies that an immediate is to be moved into Rd.
3256         EmulateInstruction::Context context;
3257         context.type = EmulateInstruction::eContextImmediate;
3258         context.SetNoArgs ();
3259 
3260         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3261             return false;
3262     }
3263     return true;
3264 }
3265 
3266 bool
EmulateShiftReg(const uint32_t opcode,const ARMEncoding encoding,ARM_ShifterType shift_type)3267 EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3268 {
3269     // assert(shift_type == SRType_ASR
3270     //        || shift_type == SRType_LSL
3271     //        || shift_type == SRType_LSR
3272     //        || shift_type == SRType_ROR);
3273 
3274     bool success = false;
3275 
3276     if (ConditionPassed(opcode))
3277     {
3278         uint32_t Rd;    // the destination register
3279         uint32_t Rn;    // the first operand register
3280         uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
3281         uint32_t carry; // the carry bit after the shift operation
3282         bool setflags;
3283         switch (encoding) {
3284         case eEncodingT1:
3285             Rd = Bits32(opcode, 2, 0);
3286             Rn = Rd;
3287             Rm = Bits32(opcode, 5, 3);
3288             setflags = !InITBlock();
3289             break;
3290         case eEncodingT2:
3291             Rd = Bits32(opcode, 11, 8);
3292             Rn = Bits32(opcode, 19, 16);
3293             Rm = Bits32(opcode, 3, 0);
3294             setflags = BitIsSet(opcode, 20);
3295             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3296                 return false;
3297             break;
3298         case eEncodingA1:
3299             Rd = Bits32(opcode, 15, 12);
3300             Rn = Bits32(opcode, 3, 0);
3301             Rm = Bits32(opcode, 11, 8);
3302             setflags = BitIsSet(opcode, 20);
3303             if (Rd == 15 || Rn == 15 || Rm == 15)
3304                 return false;
3305             break;
3306         default:
3307             return false;
3308         }
3309 
3310         // Get the first operand.
3311         uint32_t value = ReadCoreReg (Rn, &success);
3312         if (!success)
3313             return false;
3314         // Get the Rm register content.
3315         uint32_t val = ReadCoreReg (Rm, &success);
3316         if (!success)
3317             return false;
3318 
3319         // Get the shift amount.
3320         uint32_t amt = Bits32(val, 7, 0);
3321 
3322         uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3323         if (!success)
3324             return false;
3325 
3326         // The context specifies that an immediate is to be moved into Rd.
3327         EmulateInstruction::Context context;
3328         context.type = EmulateInstruction::eContextImmediate;
3329         context.SetNoArgs ();
3330 
3331         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3332             return false;
3333     }
3334     return true;
3335 }
3336 
3337 // LDM loads multiple registers from consecutive memory locations, using an
3338 // address from a base register.  Optionally the address just above the highest of those locations
3339 // can be written back to the base register.
3340 bool
EmulateLDM(const uint32_t opcode,const ARMEncoding encoding)3341 EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding)
3342 {
3343 #if 0
3344     // ARM pseudo code...
3345     if ConditionPassed()
3346         EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3347         address = R[n];
3348 
3349         for i = 0 to 14
3350             if registers<i> == '1' then
3351                 R[i] = MemA[address, 4]; address = address + 4;
3352         if registers<15> == '1' then
3353             LoadWritePC (MemA[address, 4]);
3354 
3355         if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3356         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3357 
3358 #endif
3359 
3360     bool success = false;
3361     bool conditional = false;
3362     if (ConditionPassed(opcode, &conditional))
3363     {
3364         uint32_t n;
3365         uint32_t registers = 0;
3366         bool wback;
3367         const uint32_t addr_byte_size = GetAddressByteSize();
3368         switch (encoding)
3369         {
3370             case eEncodingT1:
3371                 // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0');
3372                 n = Bits32 (opcode, 10, 8);
3373                 registers = Bits32 (opcode, 7, 0);
3374                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3375                 wback = BitIsClear (registers, n);
3376                 // if BitCount(registers) < 1 then UNPREDICTABLE;
3377                 if (BitCount(registers) < 1)
3378                     return false;
3379                 break;
3380             case eEncodingT2:
3381                 // if W == '1' && Rn == '1101' then SEE POP;
3382                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3383                 n = Bits32 (opcode, 19, 16);
3384                 registers = Bits32 (opcode, 15, 0);
3385                 registers = registers & 0xdfff; // Make sure bit 13 is zero.
3386                 wback = BitIsSet (opcode, 21);
3387 
3388                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3389                 if ((n == 15)
3390                     || (BitCount (registers) < 2)
3391                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3392                     return false;
3393 
3394                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3395                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3396                     return false;
3397 
3398                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3399                 if (wback
3400                     && BitIsSet (registers, n))
3401                     return false;
3402                 break;
3403 
3404             case eEncodingA1:
3405                 n = Bits32 (opcode, 19, 16);
3406                 registers = Bits32 (opcode, 15, 0);
3407                 wback = BitIsSet (opcode, 21);
3408                 if ((n == 15)
3409                     || (BitCount (registers) < 1))
3410                     return false;
3411                 break;
3412             default:
3413                 return false;
3414         }
3415 
3416         int32_t offset = 0;
3417         const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3418         if (!success)
3419             return false;
3420 
3421         EmulateInstruction::Context context;
3422         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3423         RegisterInfo dwarf_reg;
3424         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3425         context.SetRegisterPlusOffset (dwarf_reg, offset);
3426 
3427         for (int i = 0; i < 14; ++i)
3428         {
3429             if (BitIsSet (registers, i))
3430             {
3431                 context.type = EmulateInstruction::eContextRegisterPlusOffset;
3432                 context.SetRegisterPlusOffset (dwarf_reg, offset);
3433                 if (wback && (n == 13)) // Pop Instruction
3434                 {
3435                     if (conditional)
3436                         context.type = EmulateInstruction::eContextRegisterLoad;
3437                     else
3438                         context.type = EmulateInstruction::eContextPopRegisterOffStack;
3439                 }
3440 
3441                 // R[i] = MemA [address, 4]; address = address + 4;
3442                 uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3443                 if (!success)
3444                     return false;
3445 
3446                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3447                     return false;
3448 
3449                 offset += addr_byte_size;
3450             }
3451         }
3452 
3453         if (BitIsSet (registers, 15))
3454         {
3455             //LoadWritePC (MemA [address, 4]);
3456             context.type = EmulateInstruction::eContextRegisterPlusOffset;
3457             context.SetRegisterPlusOffset (dwarf_reg, offset);
3458             uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3459             if (!success)
3460                 return false;
3461             // In ARMv5T and above, this is an interworking branch.
3462             if (!LoadWritePC(context, data))
3463                 return false;
3464         }
3465 
3466         if (wback && BitIsClear (registers, n))
3467         {
3468             // R[n] = R[n] + 4 * BitCount (registers)
3469             int32_t offset = addr_byte_size * BitCount (registers);
3470             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3471             context.SetRegisterPlusOffset (dwarf_reg, offset);
3472 
3473             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
3474                 return false;
3475         }
3476         if (wback && BitIsSet (registers, n))
3477             // R[n] bits(32) UNKNOWN;
3478             return WriteBits32Unknown (n);
3479     }
3480     return true;
3481 }
3482 
3483 // LDMDA loads multiple registers from consecutive memory locations using an address from a base register.
3484 // The consecutive memory locations end at this address and the address just below the lowest of those locations
3485 // can optionally be written back to the base register.
3486 bool
EmulateLDMDA(const uint32_t opcode,const ARMEncoding encoding)3487 EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding)
3488 {
3489 #if 0
3490     // ARM pseudo code...
3491     if ConditionPassed() then
3492         EncodingSpecificOperations();
3493         address = R[n] - 4*BitCount(registers) + 4;
3494 
3495         for i = 0 to 14
3496             if registers<i> == '1' then
3497                   R[i] = MemA[address,4]; address = address + 4;
3498 
3499         if registers<15> == '1' then
3500             LoadWritePC(MemA[address,4]);
3501 
3502         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3503         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3504 #endif
3505 
3506     bool success = false;
3507 
3508     if (ConditionPassed(opcode))
3509     {
3510         uint32_t n;
3511         uint32_t registers = 0;
3512         bool wback;
3513         const uint32_t addr_byte_size = GetAddressByteSize();
3514 
3515         // EncodingSpecificOperations();
3516         switch (encoding)
3517         {
3518             case eEncodingA1:
3519                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3520                 n = Bits32 (opcode, 19, 16);
3521                 registers = Bits32 (opcode, 15, 0);
3522                 wback = BitIsSet (opcode, 21);
3523 
3524                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3525                 if ((n == 15) || (BitCount (registers) < 1))
3526                     return false;
3527 
3528                 break;
3529 
3530             default:
3531                 return false;
3532         }
3533         // address = R[n] - 4*BitCount(registers) + 4;
3534 
3535         int32_t offset = 0;
3536         addr_t Rn = ReadCoreReg (n, &success);
3537 
3538         if (!success)
3539             return false;
3540 
3541         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size;
3542 
3543         EmulateInstruction::Context context;
3544         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3545         RegisterInfo dwarf_reg;
3546         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3547         context.SetRegisterPlusOffset (dwarf_reg, offset);
3548 
3549         // for i = 0 to 14
3550         for (int i = 0; i < 14; ++i)
3551         {
3552             // if registers<i> == '1' then
3553             if (BitIsSet (registers, i))
3554             {
3555                   // R[i] = MemA[address,4]; address = address + 4;
3556                   context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3557                   uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3558                   if (!success)
3559                       return false;
3560                   if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3561                       return false;
3562                   offset += addr_byte_size;
3563             }
3564         }
3565 
3566         // if registers<15> == '1' then
3567         //     LoadWritePC(MemA[address,4]);
3568         if (BitIsSet (registers, 15))
3569         {
3570             context.SetRegisterPlusOffset (dwarf_reg, offset);
3571             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3572             if (!success)
3573                 return false;
3574             // In ARMv5T and above, this is an interworking branch.
3575             if (!LoadWritePC(context, data))
3576                 return false;
3577         }
3578 
3579         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3580         if (wback && BitIsClear (registers, n))
3581         {
3582             if (!success)
3583                 return false;
3584 
3585             offset = (addr_byte_size * BitCount (registers)) * -1;
3586             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3587             context.SetImmediateSigned (offset);
3588             addr_t addr = Rn + offset;
3589             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3590                 return false;
3591         }
3592 
3593         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3594         if (wback && BitIsSet (registers, n))
3595             return WriteBits32Unknown (n);
3596     }
3597     return true;
3598 }
3599 
3600 // LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
3601 // consecutive memory lcoations end just below this address, and the address of the lowest of those locations can
3602 // be optionally written back to the base register.
3603 bool
EmulateLDMDB(const uint32_t opcode,const ARMEncoding encoding)3604 EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding)
3605 {
3606 #if 0
3607     // ARM pseudo code...
3608     if ConditionPassed() then
3609         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3610         address = R[n] - 4*BitCount(registers);
3611 
3612         for i = 0 to 14
3613             if registers<i> == '1' then
3614                   R[i] = MemA[address,4]; address = address + 4;
3615         if registers<15> == '1' then
3616                   LoadWritePC(MemA[address,4]);
3617 
3618         if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3619         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3620 #endif
3621 
3622     bool success = false;
3623 
3624     if (ConditionPassed(opcode))
3625     {
3626         uint32_t n;
3627         uint32_t registers = 0;
3628         bool wback;
3629         const uint32_t addr_byte_size = GetAddressByteSize();
3630         switch (encoding)
3631         {
3632             case eEncodingT1:
3633                 // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3634                 n = Bits32 (opcode, 19, 16);
3635                 registers = Bits32 (opcode, 15, 0);
3636                 registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
3637                 wback = BitIsSet (opcode, 21);
3638 
3639                 // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3640                 if ((n == 15)
3641                     || (BitCount (registers) < 2)
3642                     || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3643                     return false;
3644 
3645                 // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3646                 if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3647                     return false;
3648 
3649                 // if wback && registers<n> == '1' then UNPREDICTABLE;
3650                 if (wback && BitIsSet (registers, n))
3651                     return false;
3652 
3653                 break;
3654 
3655             case eEncodingA1:
3656                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3657                 n = Bits32 (opcode, 19, 16);
3658                 registers = Bits32 (opcode, 15, 0);
3659                 wback = BitIsSet (opcode, 21);
3660 
3661                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3662                 if ((n == 15) || (BitCount (registers) < 1))
3663                     return false;
3664 
3665                 break;
3666 
3667             default:
3668                 return false;
3669         }
3670 
3671         // address = R[n] - 4*BitCount(registers);
3672 
3673         int32_t offset = 0;
3674         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3675 
3676         if (!success)
3677             return false;
3678 
3679         addr_t address = Rn - (addr_byte_size * BitCount (registers));
3680         EmulateInstruction::Context context;
3681         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3682         RegisterInfo dwarf_reg;
3683         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3684         context.SetRegisterPlusOffset (dwarf_reg, Rn - address);
3685 
3686         for (int i = 0; i < 14; ++i)
3687         {
3688             if (BitIsSet (registers, i))
3689             {
3690                 // R[i] = MemA[address,4]; address = address + 4;
3691                 context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3692                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3693                 if (!success)
3694                     return false;
3695 
3696                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3697                     return false;
3698 
3699                 offset += addr_byte_size;
3700             }
3701         }
3702 
3703         // if registers<15> == '1' then
3704         //     LoadWritePC(MemA[address,4]);
3705         if (BitIsSet (registers, 15))
3706         {
3707             context.SetRegisterPlusOffset (dwarf_reg, offset);
3708             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3709             if (!success)
3710                 return false;
3711             // In ARMv5T and above, this is an interworking branch.
3712             if (!LoadWritePC(context, data))
3713                 return false;
3714         }
3715 
3716         // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3717         if (wback && BitIsClear (registers, n))
3718         {
3719             if (!success)
3720                 return false;
3721 
3722             offset = (addr_byte_size * BitCount (registers)) * -1;
3723             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3724             context.SetImmediateSigned (offset);
3725             addr_t addr = Rn + offset;
3726             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3727                 return false;
3728         }
3729 
3730         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3731         if (wback && BitIsSet (registers, n))
3732             return WriteBits32Unknown (n);
3733     }
3734     return true;
3735 }
3736 
3737 // LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
3738 // consecutive memory locations start just above this address, and thea ddress of the last of those locations can
3739 // optinoally be written back to the base register.
3740 bool
EmulateLDMIB(const uint32_t opcode,const ARMEncoding encoding)3741 EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding)
3742 {
3743 #if 0
3744     if ConditionPassed() then
3745         EncodingSpecificOperations();
3746         address = R[n] + 4;
3747 
3748         for i = 0 to 14
3749             if registers<i> == '1' then
3750                   R[i] = MemA[address,4]; address = address + 4;
3751         if registers<15> == '1' then
3752             LoadWritePC(MemA[address,4]);
3753 
3754         if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3755         if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3756 #endif
3757 
3758     bool success = false;
3759 
3760     if (ConditionPassed(opcode))
3761     {
3762         uint32_t n;
3763         uint32_t registers = 0;
3764         bool wback;
3765         const uint32_t addr_byte_size = GetAddressByteSize();
3766         switch (encoding)
3767         {
3768             case eEncodingA1:
3769                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
3770                 n = Bits32 (opcode, 19, 16);
3771                 registers = Bits32 (opcode, 15, 0);
3772                 wback = BitIsSet (opcode, 21);
3773 
3774                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3775                 if ((n == 15) || (BitCount (registers) < 1))
3776                     return false;
3777 
3778                 break;
3779             default:
3780                 return false;
3781         }
3782         // address = R[n] + 4;
3783 
3784         int32_t offset = 0;
3785         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3786 
3787         if (!success)
3788             return false;
3789 
3790         addr_t address = Rn + addr_byte_size;
3791 
3792         EmulateInstruction::Context context;
3793         context.type = EmulateInstruction::eContextRegisterPlusOffset;
3794         RegisterInfo dwarf_reg;
3795         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3796         context.SetRegisterPlusOffset (dwarf_reg, offset);
3797 
3798         for (int i = 0; i < 14; ++i)
3799         {
3800             if (BitIsSet (registers, i))
3801             {
3802                 // R[i] = MemA[address,4]; address = address + 4;
3803 
3804                 context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size);
3805                 uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3806                 if (!success)
3807                     return false;
3808 
3809                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3810                     return false;
3811 
3812                 offset += addr_byte_size;
3813             }
3814         }
3815 
3816         // if registers<15> == '1' then
3817         //     LoadWritePC(MemA[address,4]);
3818         if (BitIsSet (registers, 15))
3819         {
3820             context.SetRegisterPlusOffset (dwarf_reg, offset);
3821             uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3822             if (!success)
3823                 return false;
3824             // In ARMv5T and above, this is an interworking branch.
3825             if (!LoadWritePC(context, data))
3826                 return false;
3827         }
3828 
3829         // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3830         if (wback && BitIsClear (registers, n))
3831         {
3832             if (!success)
3833                 return false;
3834 
3835             offset = addr_byte_size * BitCount (registers);
3836             context.type = EmulateInstruction::eContextAdjustBaseRegister;
3837             context.SetImmediateSigned (offset);
3838             addr_t addr = Rn + offset;
3839             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3840                 return false;
3841         }
3842 
3843         // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3844         if (wback && BitIsSet (registers, n))
3845             return WriteBits32Unknown (n);
3846     }
3847     return true;
3848 }
3849 
3850 // Load Register (immediate) calculates an address from a base register value and
3851 // an immediate offset, loads a word from memory, and writes to a register.
3852 // LDR (immediate, Thumb)
3853 bool
EmulateLDRRtRnImm(const uint32_t opcode,const ARMEncoding encoding)3854 EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding)
3855 {
3856 #if 0
3857     // ARM pseudo code...
3858     if (ConditionPassed())
3859     {
3860         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3861         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3862         address = if index then offset_addr else R[n];
3863         data = MemU[address,4];
3864         if wback then R[n] = offset_addr;
3865         if t == 15 then
3866             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3867         elsif UnalignedSupport() || address<1:0> = '00' then
3868             R[t] = data;
3869         else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3870     }
3871 #endif
3872 
3873     bool success = false;
3874 
3875     if (ConditionPassed(opcode))
3876     {
3877         uint32_t Rt; // the destination register
3878         uint32_t Rn; // the base register
3879         uint32_t imm32; // the immediate offset used to form the address
3880         addr_t offset_addr; // the offset address
3881         addr_t address; // the calculated address
3882         uint32_t data; // the literal data value from memory load
3883         bool add, index, wback;
3884         switch (encoding) {
3885             case eEncodingT1:
3886                 Rt = Bits32(opcode, 2, 0);
3887                 Rn = Bits32(opcode, 5, 3);
3888                 imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3889                 // index = TRUE; add = TRUE; wback = FALSE
3890                 add = true;
3891                 index = true;
3892                 wback = false;
3893 
3894                 break;
3895 
3896             case eEncodingT2:
3897                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
3898                 Rt = Bits32 (opcode, 10, 8);
3899                 Rn = 13;
3900                 imm32 = Bits32 (opcode, 7, 0) << 2;
3901 
3902                 // index = TRUE; add = TRUE; wback = FALSE;
3903                 index = true;
3904                 add = true;
3905                 wback = false;
3906 
3907                 break;
3908 
3909             case eEncodingT3:
3910                 // if Rn == '1111' then SEE LDR (literal);
3911                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
3912                 Rt = Bits32 (opcode, 15, 12);
3913                 Rn = Bits32 (opcode, 19, 16);
3914                 imm32 = Bits32 (opcode, 11, 0);
3915 
3916                 // index = TRUE; add = TRUE; wback = FALSE;
3917                 index = true;
3918                 add = true;
3919                 wback = false;
3920 
3921                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3922                 if ((Rt == 15) && InITBlock() && !LastInITBlock())
3923                     return false;
3924 
3925                 break;
3926 
3927             case eEncodingT4:
3928                 // if Rn == '1111' then SEE LDR (literal);
3929                 // if P == '1' && U == '1' && W == '0' then SEE LDRT;
3930                 // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
3931                 // if P == '0' && W == '0' then UNDEFINED;
3932                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
3933                     return false;
3934 
3935                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
3936                 Rt = Bits32 (opcode, 15, 12);
3937                 Rn = Bits32 (opcode, 19, 16);
3938                 imm32 = Bits32 (opcode, 7, 0);
3939 
3940                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
3941                 index = BitIsSet (opcode, 10);
3942                 add = BitIsSet (opcode, 9);
3943                 wback = BitIsSet (opcode, 8);
3944 
3945                 // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
3946                 if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock()))
3947                     return false;
3948 
3949                 break;
3950 
3951             default:
3952                 return false;
3953         }
3954         uint32_t base = ReadCoreReg (Rn, &success);
3955         if (!success)
3956             return false;
3957         if (add)
3958             offset_addr = base + imm32;
3959         else
3960             offset_addr = base - imm32;
3961 
3962         address = (index ? offset_addr : base);
3963 
3964         RegisterInfo base_reg;
3965         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
3966         if (wback)
3967         {
3968             EmulateInstruction::Context ctx;
3969             ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
3970             ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3971 
3972             if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
3973                 return false;
3974         }
3975 
3976         // Prepare to write to the Rt register.
3977         EmulateInstruction::Context context;
3978         context.type = EmulateInstruction::eContextRegisterLoad;
3979         context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3980 
3981         // Read memory from the address.
3982         data = MemURead(context, address, 4, 0, &success);
3983         if (!success)
3984             return false;
3985 
3986         if (Rt == 15)
3987         {
3988             if (Bits32(address, 1, 0) == 0)
3989             {
3990                 if (!LoadWritePC(context, data))
3991                     return false;
3992             }
3993             else
3994                 return false;
3995         }
3996         else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
3997         {
3998             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
3999                 return false;
4000         }
4001         else
4002             WriteBits32Unknown (Rt);
4003     }
4004     return true;
4005 }
4006 
4007 // STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
4008 // from a base register.  The consecutive memory locations start at this address, and teh address just above the last
4009 // of those locations can optionally be written back to the base register.
4010 bool
EmulateSTM(const uint32_t opcode,const ARMEncoding encoding)4011 EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding)
4012 {
4013 #if 0
4014     if ConditionPassed() then
4015         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4016         address = R[n];
4017 
4018         for i = 0 to 14
4019             if registers<i> == '1' then
4020                 if i == n && wback && i != LowestSetBit(registers) then
4021                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4022                 else
4023                     MemA[address,4] = R[i];
4024                 address = address + 4;
4025 
4026         if registers<15> == '1' then // Only possible for encoding A1
4027             MemA[address,4] = PCStoreValue();
4028         if wback then R[n] = R[n] + 4*BitCount(registers);
4029 #endif
4030 
4031     bool success = false;
4032 
4033     if (ConditionPassed(opcode))
4034     {
4035         uint32_t n;
4036         uint32_t registers = 0;
4037         bool wback;
4038         const uint32_t addr_byte_size = GetAddressByteSize();
4039 
4040         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4041         switch (encoding)
4042         {
4043             case eEncodingT1:
4044                 // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4045                 n = Bits32 (opcode, 10, 8);
4046                 registers = Bits32 (opcode, 7, 0);
4047                 registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
4048                 wback = true;
4049 
4050                 // if BitCount(registers) < 1 then UNPREDICTABLE;
4051                 if (BitCount (registers) < 1)
4052                     return false;
4053 
4054                 break;
4055 
4056             case eEncodingT2:
4057                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4058                 n = Bits32 (opcode, 19, 16);
4059                 registers = Bits32 (opcode, 15, 0);
4060                 registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4061                 wback = BitIsSet (opcode, 21);
4062 
4063                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4064                 if ((n == 15) || (BitCount (registers) < 2))
4065                     return false;
4066 
4067                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4068                 if (wback && BitIsSet (registers, n))
4069                     return false;
4070 
4071                 break;
4072 
4073             case eEncodingA1:
4074                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4075                 n = Bits32 (opcode, 19, 16);
4076                 registers = Bits32 (opcode, 15, 0);
4077                 wback = BitIsSet (opcode, 21);
4078 
4079                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4080                 if ((n == 15) || (BitCount (registers) < 1))
4081                     return false;
4082 
4083                 break;
4084 
4085             default:
4086                 return false;
4087         }
4088 
4089         // address = R[n];
4090         int32_t offset = 0;
4091         const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4092         if (!success)
4093             return false;
4094 
4095         EmulateInstruction::Context context;
4096         context.type = EmulateInstruction::eContextRegisterStore;
4097         RegisterInfo base_reg;
4098         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4099 
4100         // for i = 0 to 14
4101         uint32_t lowest_set_bit = 14;
4102         for (uint32_t i = 0; i < 14; ++i)
4103         {
4104             // if registers<i> == '1' then
4105             if (BitIsSet (registers, i))
4106             {
4107                   if (i < lowest_set_bit)
4108                       lowest_set_bit = i;
4109                   // if i == n && wback && i != LowestSetBit(registers) then
4110                   if ((i == n) && wback && (i != lowest_set_bit))
4111                       // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4112                       WriteBits32UnknownToMemory (address + offset);
4113                   else
4114                   {
4115                      // MemA[address,4] = R[i];
4116                       uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4117                       if (!success)
4118                           return false;
4119 
4120                       RegisterInfo data_reg;
4121                       GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4122                       context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4123                       if (!MemAWrite (context, address + offset, data, addr_byte_size))
4124                           return false;
4125                   }
4126 
4127                   // address = address + 4;
4128                   offset += addr_byte_size;
4129             }
4130         }
4131 
4132         // if registers<15> == '1' then // Only possible for encoding A1
4133         //     MemA[address,4] = PCStoreValue();
4134         if (BitIsSet (registers, 15))
4135         {
4136             RegisterInfo pc_reg;
4137             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4138             context.SetRegisterPlusOffset (pc_reg, 8);
4139             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4140             if (!success)
4141                 return false;
4142 
4143             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4144                 return false;
4145         }
4146 
4147         // if wback then R[n] = R[n] + 4*BitCount(registers);
4148         if (wback)
4149         {
4150             offset = addr_byte_size * BitCount (registers);
4151             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4152             context.SetImmediateSigned (offset);
4153             addr_t data = address + offset;
4154             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4155                 return false;
4156         }
4157     }
4158     return true;
4159 }
4160 
4161 // STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
4162 // from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
4163 // of those locations can optionally be written back to the base register.
4164 bool
EmulateSTMDA(const uint32_t opcode,const ARMEncoding encoding)4165 EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding)
4166 {
4167 #if 0
4168     if ConditionPassed() then
4169         EncodingSpecificOperations();
4170         address = R[n] - 4*BitCount(registers) + 4;
4171 
4172         for i = 0 to 14
4173             if registers<i> == '1' then
4174                 if i == n && wback && i != LowestSetBit(registers) then
4175                     MemA[address,4] = bits(32) UNKNOWN;
4176                 else
4177                     MemA[address,4] = R[i];
4178                 address = address + 4;
4179 
4180         if registers<15> == '1' then
4181             MemA[address,4] = PCStoreValue();
4182 
4183         if wback then R[n] = R[n] - 4*BitCount(registers);
4184 #endif
4185 
4186     bool success = false;
4187 
4188     if (ConditionPassed(opcode))
4189     {
4190         uint32_t n;
4191         uint32_t registers = 0;
4192         bool wback;
4193         const uint32_t addr_byte_size = GetAddressByteSize();
4194 
4195         // EncodingSpecificOperations();
4196         switch (encoding)
4197         {
4198             case eEncodingA1:
4199                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4200                 n = Bits32 (opcode, 19, 16);
4201                 registers = Bits32 (opcode, 15, 0);
4202                 wback = BitIsSet (opcode, 21);
4203 
4204                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4205                 if ((n == 15) || (BitCount (registers) < 1))
4206                     return false;
4207                 break;
4208             default:
4209                 return false;
4210         }
4211 
4212         // address = R[n] - 4*BitCount(registers) + 4;
4213         int32_t offset = 0;
4214         addr_t Rn = ReadCoreReg (n, &success);
4215         if (!success)
4216             return false;
4217 
4218         addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4;
4219 
4220         EmulateInstruction::Context context;
4221         context.type = EmulateInstruction::eContextRegisterStore;
4222         RegisterInfo base_reg;
4223         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4224 
4225         // for i = 0 to 14
4226         uint32_t lowest_bit_set = 14;
4227         for (uint32_t i = 0; i < 14; ++i)
4228         {
4229             // if registers<i> == '1' then
4230             if (BitIsSet (registers, i))
4231             {
4232                 if (i < lowest_bit_set)
4233                     lowest_bit_set = i;
4234                 //if i == n && wback && i != LowestSetBit(registers) then
4235                 if ((i == n) && wback && (i != lowest_bit_set))
4236                     // MemA[address,4] = bits(32) UNKNOWN;
4237                     WriteBits32UnknownToMemory (address + offset);
4238                 else
4239                 {
4240                     // MemA[address,4] = R[i];
4241                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4242                     if (!success)
4243                         return false;
4244 
4245                     RegisterInfo data_reg;
4246                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4247                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4248                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4249                         return false;
4250                 }
4251 
4252                 // address = address + 4;
4253                 offset += addr_byte_size;
4254             }
4255         }
4256 
4257         // if registers<15> == '1' then
4258         //    MemA[address,4] = PCStoreValue();
4259         if (BitIsSet (registers, 15))
4260         {
4261             RegisterInfo pc_reg;
4262             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4263             context.SetRegisterPlusOffset (pc_reg, 8);
4264             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4265             if (!success)
4266                 return false;
4267 
4268             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4269                 return false;
4270         }
4271 
4272         // if wback then R[n] = R[n] - 4*BitCount(registers);
4273         if (wback)
4274         {
4275             offset = (addr_byte_size * BitCount (registers)) * -1;
4276             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4277             context.SetImmediateSigned (offset);
4278             addr_t data = Rn + offset;
4279             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4280                 return false;
4281         }
4282     }
4283     return true;
4284 }
4285 
4286 // STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
4287 // from a base register.  The consecutive memory locations end just below this address, and the address of the first of
4288 // those locations can optionally be written back to the base register.
4289 bool
EmulateSTMDB(const uint32_t opcode,const ARMEncoding encoding)4290 EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding)
4291 {
4292 #if 0
4293     if ConditionPassed() then
4294         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4295         address = R[n] - 4*BitCount(registers);
4296 
4297         for i = 0 to 14
4298             if registers<i> == '1' then
4299                 if i == n && wback && i != LowestSetBit(registers) then
4300                     MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4301                 else
4302                     MemA[address,4] = R[i];
4303                 address = address + 4;
4304 
4305         if registers<15> == '1' then // Only possible for encoding A1
4306             MemA[address,4] = PCStoreValue();
4307 
4308         if wback then R[n] = R[n] - 4*BitCount(registers);
4309 #endif
4310 
4311 
4312     bool success = false;
4313 
4314     if (ConditionPassed(opcode))
4315     {
4316         uint32_t n;
4317         uint32_t registers = 0;
4318         bool wback;
4319         const uint32_t addr_byte_size = GetAddressByteSize();
4320 
4321         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4322         switch (encoding)
4323         {
4324             case eEncodingT1:
4325                 // if W == '1' && Rn == '1101' then SEE PUSH;
4326                 if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
4327                 {
4328                     // See PUSH
4329                 }
4330                 // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4331                 n = Bits32 (opcode, 19, 16);
4332                 registers = Bits32 (opcode, 15, 0);
4333                 registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
4334                 wback = BitIsSet (opcode, 21);
4335                 // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4336                 if ((n == 15) || BitCount (registers) < 2)
4337                     return false;
4338                 // if wback && registers<n> == '1' then UNPREDICTABLE;
4339                 if (wback && BitIsSet (registers, n))
4340                     return false;
4341                 break;
4342 
4343             case eEncodingA1:
4344                 // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH;
4345                 if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
4346                 {
4347                     // See Push
4348                 }
4349                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4350                 n = Bits32 (opcode, 19, 16);
4351                 registers = Bits32 (opcode, 15, 0);
4352                 wback = BitIsSet (opcode, 21);
4353                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4354                 if ((n == 15) || BitCount (registers) < 1)
4355                     return false;
4356                 break;
4357 
4358             default:
4359                 return false;
4360         }
4361 
4362         // address = R[n] - 4*BitCount(registers);
4363 
4364         int32_t offset = 0;
4365         addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4366         if (!success)
4367         return false;
4368 
4369         addr_t address = Rn - (addr_byte_size * BitCount (registers));
4370 
4371         EmulateInstruction::Context context;
4372         context.type = EmulateInstruction::eContextRegisterStore;
4373         RegisterInfo base_reg;
4374         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4375 
4376         // for i = 0 to 14
4377         uint32_t lowest_set_bit = 14;
4378         for (uint32_t i = 0; i < 14; ++i)
4379         {
4380             // if registers<i> == '1' then
4381             if (BitIsSet (registers, i))
4382             {
4383                 if (i < lowest_set_bit)
4384                     lowest_set_bit = i;
4385                 // if i == n && wback && i != LowestSetBit(registers) then
4386                 if ((i == n) && wback && (i != lowest_set_bit))
4387                     // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4388                     WriteBits32UnknownToMemory (address + offset);
4389                 else
4390                 {
4391                     // MemA[address,4] = R[i];
4392                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4393                     if (!success)
4394                         return false;
4395 
4396                     RegisterInfo data_reg;
4397                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4398                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4399                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4400                         return false;
4401                 }
4402 
4403                 // address = address + 4;
4404                 offset += addr_byte_size;
4405             }
4406         }
4407 
4408         // if registers<15> == '1' then // Only possible for encoding A1
4409         //     MemA[address,4] = PCStoreValue();
4410         if (BitIsSet (registers, 15))
4411         {
4412             RegisterInfo pc_reg;
4413             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4414             context.SetRegisterPlusOffset (pc_reg, 8);
4415             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4416             if (!success)
4417                 return false;
4418 
4419             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4420                 return false;
4421         }
4422 
4423         // if wback then R[n] = R[n] - 4*BitCount(registers);
4424         if (wback)
4425         {
4426             offset = (addr_byte_size * BitCount (registers)) * -1;
4427             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4428             context.SetImmediateSigned (offset);
4429             addr_t data = Rn + offset;
4430             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4431                 return false;
4432         }
4433     }
4434     return true;
4435 }
4436 
4437 // STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
4438 // from a base register.  The consecutive memory locations start just above this address, and the address of the last
4439 // of those locations can optionally be written back to the base register.
4440 bool
EmulateSTMIB(const uint32_t opcode,const ARMEncoding encoding)4441 EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding)
4442 {
4443 #if 0
4444     if ConditionPassed() then
4445         EncodingSpecificOperations();
4446         address = R[n] + 4;
4447 
4448         for i = 0 to 14
4449             if registers<i> == '1' then
4450                 if i == n && wback && i != LowestSetBit(registers) then
4451                     MemA[address,4] = bits(32) UNKNOWN;
4452                 else
4453                     MemA[address,4] = R[i];
4454                 address = address + 4;
4455 
4456         if registers<15> == '1' then
4457             MemA[address,4] = PCStoreValue();
4458 
4459         if wback then R[n] = R[n] + 4*BitCount(registers);
4460 #endif
4461 
4462     bool success = false;
4463 
4464     if (ConditionPassed(opcode))
4465     {
4466         uint32_t n;
4467         uint32_t registers = 0;
4468         bool wback;
4469         const uint32_t addr_byte_size = GetAddressByteSize();
4470 
4471         // EncodingSpecificOperations();
4472         switch (encoding)
4473         {
4474             case eEncodingA1:
4475                 // n = UInt(Rn); registers = register_list; wback = (W == '1');
4476                 n = Bits32 (opcode, 19, 16);
4477                 registers = Bits32 (opcode, 15, 0);
4478                 wback = BitIsSet (opcode, 21);
4479 
4480                 // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4481                 if ((n == 15) && (BitCount (registers) < 1))
4482                     return false;
4483                 break;
4484             default:
4485                 return false;
4486         }
4487         // address = R[n] + 4;
4488 
4489         int32_t offset = 0;
4490         addr_t Rn = ReadCoreReg (n, &success);
4491         if (!success)
4492             return false;
4493 
4494         addr_t address = Rn + addr_byte_size;
4495 
4496         EmulateInstruction::Context context;
4497         context.type = EmulateInstruction::eContextRegisterStore;
4498         RegisterInfo base_reg;
4499         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4500 
4501         uint32_t lowest_set_bit = 14;
4502         // for i = 0 to 14
4503         for (uint32_t i = 0; i < 14; ++i)
4504         {
4505             // if registers<i> == '1' then
4506             if (BitIsSet (registers, i))
4507             {
4508                 if (i < lowest_set_bit)
4509                     lowest_set_bit = i;
4510                 // if i == n && wback && i != LowestSetBit(registers) then
4511                 if ((i == n) && wback && (i != lowest_set_bit))
4512                     // MemA[address,4] = bits(32) UNKNOWN;
4513                     WriteBits32UnknownToMemory (address + offset);
4514                 // else
4515                 else
4516                 {
4517                     // MemA[address,4] = R[i];
4518                     uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4519                     if (!success)
4520                         return false;
4521 
4522                     RegisterInfo data_reg;
4523                     GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4524                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size);
4525                     if (!MemAWrite (context, address + offset, data, addr_byte_size))
4526                         return false;
4527                 }
4528 
4529                 // address = address + 4;
4530                 offset += addr_byte_size;
4531             }
4532         }
4533 
4534         // if registers<15> == '1' then
4535             // MemA[address,4] = PCStoreValue();
4536         if (BitIsSet (registers, 15))
4537         {
4538             RegisterInfo pc_reg;
4539             GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4540             context.SetRegisterPlusOffset (pc_reg, 8);
4541             const uint32_t pc = ReadCoreReg (PC_REG, &success);
4542             if (!success)
4543             return false;
4544 
4545             if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4546                 return false;
4547         }
4548 
4549         // if wback then R[n] = R[n] + 4*BitCount(registers);
4550         if (wback)
4551         {
4552             offset = addr_byte_size * BitCount (registers);
4553             context.type = EmulateInstruction::eContextAdjustBaseRegister;
4554             context.SetImmediateSigned (offset);
4555             addr_t data = Rn + offset;
4556             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4557                 return false;
4558         }
4559     }
4560     return true;
4561 }
4562 
4563 // STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word
4564 // from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
4565 bool
EmulateSTRThumb(const uint32_t opcode,const ARMEncoding encoding)4566 EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding)
4567 {
4568 #if 0
4569     if ConditionPassed() then
4570         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4571         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4572         address = if index then offset_addr else R[n];
4573         if UnalignedSupport() || address<1:0> == '00' then
4574             MemU[address,4] = R[t];
4575         else // Can only occur before ARMv7
4576             MemU[address,4] = bits(32) UNKNOWN;
4577         if wback then R[n] = offset_addr;
4578 #endif
4579 
4580     bool success = false;
4581 
4582     if (ConditionPassed(opcode))
4583     {
4584         const uint32_t addr_byte_size = GetAddressByteSize();
4585 
4586         uint32_t t;
4587         uint32_t n;
4588         uint32_t imm32;
4589         bool index;
4590         bool add;
4591         bool wback;
4592         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4593         switch (encoding)
4594         {
4595             case eEncodingT1:
4596                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
4597                 t = Bits32 (opcode, 2, 0);
4598                 n = Bits32 (opcode, 5, 3);
4599                 imm32 = Bits32 (opcode, 10, 6) << 2;
4600 
4601                 // index = TRUE; add = TRUE; wback = FALSE;
4602                 index = true;
4603                 add = false;
4604                 wback = false;
4605                 break;
4606 
4607             case eEncodingT2:
4608                 // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4609                 t = Bits32 (opcode, 10, 8);
4610                 n = 13;
4611                 imm32 = Bits32 (opcode, 7, 0) << 2;
4612 
4613                 // index = TRUE; add = TRUE; wback = FALSE;
4614                 index = true;
4615                 add = true;
4616                 wback = false;
4617                 break;
4618 
4619             case eEncodingT3:
4620                 // if Rn == '1111' then UNDEFINED;
4621                 if (Bits32 (opcode, 19, 16) == 15)
4622                     return false;
4623 
4624                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4625                 t = Bits32 (opcode, 15, 12);
4626                 n = Bits32 (opcode, 19, 16);
4627                 imm32 = Bits32 (opcode, 11, 0);
4628 
4629                 // index = TRUE; add = TRUE; wback = FALSE;
4630                 index = true;
4631                 add = true;
4632                 wback = false;
4633 
4634                 // if t == 15 then UNPREDICTABLE;
4635                 if (t == 15)
4636                     return false;
4637                 break;
4638 
4639             case eEncodingT4:
4640                 // if P == '1' && U == '1' && W == '0' then SEE STRT;
4641                 // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH;
4642                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4643                 if ((Bits32 (opcode, 19, 16) == 15)
4644                       || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
4645                     return false;
4646 
4647                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4648                 t = Bits32 (opcode, 15, 12);
4649                 n = Bits32 (opcode, 19, 16);
4650                 imm32 = Bits32 (opcode, 7, 0);
4651 
4652                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4653                 index = BitIsSet (opcode, 10);
4654                 add = BitIsSet (opcode, 9);
4655                 wback = BitIsSet (opcode, 8);
4656 
4657                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
4658                 if ((t == 15) || (wback && (n == t)))
4659                     return false;
4660                 break;
4661 
4662             default:
4663                 return false;
4664         }
4665 
4666         addr_t offset_addr;
4667         addr_t address;
4668 
4669         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4670         uint32_t base_address = ReadCoreReg (n, &success);
4671         if (!success)
4672             return false;
4673 
4674         if (add)
4675             offset_addr = base_address + imm32;
4676         else
4677             offset_addr = base_address - imm32;
4678 
4679         // address = if index then offset_addr else R[n];
4680         if (index)
4681             address = offset_addr;
4682         else
4683             address = base_address;
4684 
4685         EmulateInstruction::Context context;
4686         context.type = eContextRegisterStore;
4687         RegisterInfo base_reg;
4688         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4689 
4690         // if UnalignedSupport() || address<1:0> == '00' then
4691         if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
4692         {
4693             // MemU[address,4] = R[t];
4694             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4695             if (!success)
4696                 return false;
4697 
4698             RegisterInfo data_reg;
4699             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4700             int32_t offset = address - base_address;
4701             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4702             if (!MemUWrite (context, address, data, addr_byte_size))
4703                 return false;
4704         }
4705         else
4706         {
4707             // MemU[address,4] = bits(32) UNKNOWN;
4708             WriteBits32UnknownToMemory (address);
4709         }
4710 
4711         // if wback then R[n] = offset_addr;
4712         if (wback)
4713         {
4714             context.type = eContextRegisterLoad;
4715             context.SetAddress (offset_addr);
4716             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4717                 return false;
4718         }
4719     }
4720     return true;
4721 }
4722 
4723 // STR (Store Register) calculates an address from a base register value and an offset register value, stores a
4724 // word from a register to memory.   The offset register value can optionally be shifted.
4725 bool
EmulateSTRRegister(const uint32_t opcode,const ARMEncoding encoding)4726 EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding)
4727 {
4728 #if 0
4729     if ConditionPassed() then
4730         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4731         offset = Shift(R[m], shift_t, shift_n, APSR.C);
4732         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4733         address = if index then offset_addr else R[n];
4734         if t == 15 then // Only possible for encoding A1
4735             data = PCStoreValue();
4736         else
4737             data = R[t];
4738         if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4739             MemU[address,4] = data;
4740         else // Can only occur before ARMv7
4741             MemU[address,4] = bits(32) UNKNOWN;
4742         if wback then R[n] = offset_addr;
4743 #endif
4744 
4745     bool success = false;
4746 
4747     if (ConditionPassed(opcode))
4748     {
4749         const uint32_t addr_byte_size = GetAddressByteSize();
4750 
4751         uint32_t t;
4752         uint32_t n;
4753         uint32_t m;
4754         ARM_ShifterType shift_t;
4755         uint32_t shift_n;
4756         bool index;
4757         bool add;
4758         bool wback;
4759 
4760         // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4761         switch (encoding)
4762         {
4763             case eEncodingT1:
4764                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4765                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4766                 t = Bits32 (opcode, 2, 0);
4767                 n = Bits32 (opcode, 5, 3);
4768                 m = Bits32 (opcode, 8, 6);
4769 
4770                 // index = TRUE; add = TRUE; wback = FALSE;
4771                 index = true;
4772                 add = true;
4773                 wback = false;
4774 
4775                 // (shift_t, shift_n) = (SRType_LSL, 0);
4776                 shift_t = SRType_LSL;
4777                 shift_n = 0;
4778                 break;
4779 
4780             case eEncodingT2:
4781                 // if Rn == '1111' then UNDEFINED;
4782                 if (Bits32 (opcode, 19, 16) == 15)
4783                     return false;
4784 
4785                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4786                 t = Bits32 (opcode, 15, 12);
4787                 n = Bits32 (opcode, 19, 16);
4788                 m = Bits32 (opcode, 3, 0);
4789 
4790                 // index = TRUE; add = TRUE; wback = FALSE;
4791                 index = true;
4792                 add = true;
4793                 wback = false;
4794 
4795                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4796                 shift_t = SRType_LSL;
4797                 shift_n = Bits32 (opcode, 5, 4);
4798 
4799                 // if t == 15 || BadReg(m) then UNPREDICTABLE;
4800                 if ((t == 15) || (BadReg (m)))
4801                     return false;
4802                 break;
4803 
4804             case eEncodingA1:
4805             {
4806                 // if P == '0' && W == '1' then SEE STRT;
4807                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4808                 t = Bits32 (opcode, 15, 12);
4809                 n = Bits32 (opcode, 19, 16);
4810                 m = Bits32 (opcode, 3, 0);
4811 
4812                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
4813                 index = BitIsSet (opcode, 24);
4814                 add = BitIsSet (opcode, 23);
4815                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
4816 
4817                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
4818                 uint32_t typ = Bits32 (opcode, 6, 5);
4819                 uint32_t imm5 = Bits32 (opcode, 11, 7);
4820                 shift_n = DecodeImmShift(typ, imm5, shift_t);
4821 
4822                 // if m == 15 then UNPREDICTABLE;
4823                 if (m == 15)
4824                     return false;
4825 
4826                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
4827                 if (wback && ((n == 15) || (n == t)))
4828                     return false;
4829 
4830                 break;
4831             }
4832             default:
4833                 return false;
4834         }
4835 
4836         addr_t offset_addr;
4837         addr_t address;
4838         int32_t offset = 0;
4839 
4840         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4841         if (!success)
4842             return false;
4843 
4844         uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
4845         if (!success)
4846             return false;
4847 
4848         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4849         offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success);
4850         if (!success)
4851             return false;
4852 
4853         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4854         if (add)
4855             offset_addr = base_address + offset;
4856         else
4857             offset_addr = base_address - offset;
4858 
4859         // address = if index then offset_addr else R[n];
4860         if (index)
4861             address = offset_addr;
4862         else
4863             address = base_address;
4864 
4865         uint32_t data;
4866         // if t == 15 then // Only possible for encoding A1
4867         if (t == 15)
4868             // data = PCStoreValue();
4869             data = ReadCoreReg (PC_REG, &success);
4870         else
4871             // data = R[t];
4872             data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4873 
4874         if (!success)
4875             return false;
4876 
4877         EmulateInstruction::Context context;
4878         context.type = eContextRegisterStore;
4879 
4880         // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4881         if (UnalignedSupport ()
4882             || (BitIsClear (address, 1) && BitIsClear (address, 0))
4883             || CurrentInstrSet() == eModeARM)
4884         {
4885             // MemU[address,4] = data;
4886 
4887             RegisterInfo base_reg;
4888             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 +  n, base_reg);
4889 
4890             RegisterInfo data_reg;
4891             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4892 
4893             context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4894             if (!MemUWrite (context, address, data, addr_byte_size))
4895                 return false;
4896 
4897         }
4898         else
4899             // MemU[address,4] = bits(32) UNKNOWN;
4900             WriteBits32UnknownToMemory (address);
4901 
4902         // if wback then R[n] = offset_addr;
4903         if (wback)
4904         {
4905             context.type = eContextRegisterLoad;
4906             context.SetAddress (offset_addr);
4907             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4908                 return false;
4909         }
4910 
4911     }
4912     return true;
4913 }
4914 
4915 bool
EmulateSTRBThumb(const uint32_t opcode,const ARMEncoding encoding)4916 EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding)
4917 {
4918 #if 0
4919     if ConditionPassed() then
4920         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4921         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4922         address = if index then offset_addr else R[n];
4923         MemU[address,1] = R[t]<7:0>;
4924         if wback then R[n] = offset_addr;
4925 #endif
4926 
4927 
4928     bool success = false;
4929 
4930     if (ConditionPassed(opcode))
4931     {
4932         uint32_t t;
4933         uint32_t n;
4934         uint32_t imm32;
4935         bool index;
4936         bool add;
4937         bool wback;
4938         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4939         switch (encoding)
4940         {
4941             case eEncodingT1:
4942                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
4943                 t = Bits32 (opcode, 2, 0);
4944                 n = Bits32 (opcode, 5, 3);
4945                 imm32 = Bits32 (opcode, 10, 6);
4946 
4947                 // index = TRUE; add = TRUE; wback = FALSE;
4948                 index = true;
4949                 add = true;
4950                 wback = false;
4951                 break;
4952 
4953             case eEncodingT2:
4954                 // if Rn == '1111' then UNDEFINED;
4955                 if (Bits32 (opcode, 19, 16) == 15)
4956                     return false;
4957 
4958                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4959                 t = Bits32 (opcode, 15, 12);
4960                 n = Bits32 (opcode, 19, 16);
4961                 imm32 = Bits32 (opcode, 11, 0);
4962 
4963                 // index = TRUE; add = TRUE; wback = FALSE;
4964                 index = true;
4965                 add = true;
4966                 wback = false;
4967 
4968                 // if BadReg(t) then UNPREDICTABLE;
4969                 if (BadReg (t))
4970                     return false;
4971                 break;
4972 
4973             case eEncodingT3:
4974                 // if P == '1' && U == '1' && W == '0' then SEE STRBT;
4975                 // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4976                 if (Bits32 (opcode, 19, 16) == 15)
4977                     return false;
4978 
4979                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4980                 t = Bits32 (opcode, 15, 12);
4981                 n = Bits32 (opcode, 19, 16);
4982                 imm32 = Bits32 (opcode, 7, 0);
4983 
4984                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4985                 index = BitIsSet (opcode, 10);
4986                 add = BitIsSet (opcode, 9);
4987                 wback = BitIsSet (opcode, 8);
4988 
4989                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
4990                 if ((BadReg (t)) || (wback && (n == t)))
4991                     return false;
4992                 break;
4993 
4994             default:
4995                 return false;
4996         }
4997 
4998         addr_t offset_addr;
4999         addr_t address;
5000         addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
5001         if (!success)
5002             return false;
5003 
5004         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5005         if (add)
5006             offset_addr = base_address + imm32;
5007         else
5008             offset_addr = base_address - imm32;
5009 
5010         // address = if index then offset_addr else R[n];
5011         if (index)
5012             address = offset_addr;
5013         else
5014             address = base_address;
5015 
5016         // MemU[address,1] = R[t]<7:0>
5017         RegisterInfo base_reg;
5018         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5019 
5020         RegisterInfo data_reg;
5021         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5022 
5023         EmulateInstruction::Context context;
5024         context.type = eContextRegisterStore;
5025         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
5026 
5027         uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5028         if (!success)
5029             return false;
5030 
5031         data = Bits32 (data, 7, 0);
5032 
5033         if (!MemUWrite (context, address, data, 1))
5034             return false;
5035 
5036         // if wback then R[n] = offset_addr;
5037         if (wback)
5038         {
5039             context.type = eContextRegisterLoad;
5040             context.SetAddress (offset_addr);
5041             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5042                 return false;
5043         }
5044 
5045     }
5046 
5047     return true;
5048 }
5049 
5050 // STRH (register) calculates an address from a base register value and an offset register value, and stores a
5051 // halfword from a register to memory.  The offset register alue can be shifted left by 0, 1, 2, or 3 bits.
5052 bool
EmulateSTRHRegister(const uint32_t opcode,const ARMEncoding encoding)5053 EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding)
5054 {
5055 #if 0
5056     if ConditionPassed() then
5057         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5058         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5059         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5060         address = if index then offset_addr else R[n];
5061         if UnalignedSupport() || address<0> == '0' then
5062             MemU[address,2] = R[t]<15:0>;
5063         else // Can only occur before ARMv7
5064             MemU[address,2] = bits(16) UNKNOWN;
5065         if wback then R[n] = offset_addr;
5066 #endif
5067 
5068     bool success = false;
5069 
5070     if (ConditionPassed(opcode))
5071     {
5072         uint32_t t;
5073         uint32_t n;
5074         uint32_t m;
5075         bool index;
5076         bool add;
5077         bool wback;
5078         ARM_ShifterType shift_t;
5079         uint32_t shift_n;
5080 
5081         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5082         switch (encoding)
5083         {
5084             case eEncodingT1:
5085                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5086                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5087                 t = Bits32 (opcode, 2, 0);
5088                 n = Bits32 (opcode, 5, 3);
5089                 m = Bits32 (opcode, 8, 6);
5090 
5091                 // index = TRUE; add = TRUE; wback = FALSE;
5092                 index = true;
5093                 add = true;
5094                 wback = false;
5095 
5096                 // (shift_t, shift_n) = (SRType_LSL, 0);
5097                 shift_t = SRType_LSL;
5098                 shift_n = 0;
5099 
5100                 break;
5101 
5102             case eEncodingT2:
5103                 // if Rn == '1111' then UNDEFINED;
5104                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5105                 t = Bits32 (opcode, 15, 12);
5106                 n = Bits32 (opcode, 19, 16);
5107                 m = Bits32 (opcode, 3, 0);
5108                 if (n == 15)
5109                     return false;
5110 
5111                 // index = TRUE; add = TRUE; wback = FALSE;
5112                 index = true;
5113                 add = true;
5114                 wback = false;
5115 
5116                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5117                 shift_t = SRType_LSL;
5118                 shift_n = Bits32 (opcode, 5, 4);
5119 
5120                 // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5121                 if (BadReg (t) || BadReg (m))
5122                     return false;
5123 
5124                 break;
5125 
5126             case eEncodingA1:
5127                 // if P == '0' && W == '1' then SEE STRHT;
5128                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5129                 t = Bits32 (opcode, 15, 12);
5130                 n = Bits32 (opcode, 19, 16);
5131                 m = Bits32 (opcode, 3, 0);
5132 
5133                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5134                 index = BitIsSet (opcode, 24);
5135                 add = BitIsSet (opcode, 23);
5136                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5137 
5138                 // (shift_t, shift_n) = (SRType_LSL, 0);
5139                 shift_t = SRType_LSL;
5140                 shift_n = 0;
5141 
5142                 // if t == 15 || m == 15 then UNPREDICTABLE;
5143                 if ((t == 15) || (m == 15))
5144                     return false;
5145 
5146                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5147                 if (wback && ((n == 15) || (n == t)))
5148                     return false;
5149 
5150                 break;
5151 
5152             default:
5153                 return false;
5154         }
5155 
5156         uint32_t Rm = ReadCoreReg (m, &success);
5157         if (!success)
5158             return false;
5159 
5160         uint32_t Rn = ReadCoreReg (n, &success);
5161         if (!success)
5162             return false;
5163 
5164         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5165         uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
5166         if (!success)
5167             return false;
5168 
5169         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5170         addr_t offset_addr;
5171         if (add)
5172             offset_addr = Rn + offset;
5173         else
5174             offset_addr = Rn - offset;
5175 
5176         // address = if index then offset_addr else R[n];
5177         addr_t address;
5178         if (index)
5179             address = offset_addr;
5180         else
5181             address = Rn;
5182 
5183         EmulateInstruction::Context context;
5184         context.type = eContextRegisterStore;
5185         RegisterInfo base_reg;
5186         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5187         RegisterInfo offset_reg;
5188         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5189 
5190         // if UnalignedSupport() || address<0> == '0' then
5191         if (UnalignedSupport() || BitIsClear (address, 0))
5192         {
5193             // MemU[address,2] = R[t]<15:0>;
5194             uint32_t Rt = ReadCoreReg (t, &success);
5195             if (!success)
5196                 return false;
5197 
5198             EmulateInstruction::Context context;
5199             context.type = eContextRegisterStore;
5200             RegisterInfo base_reg;
5201             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5202             RegisterInfo offset_reg;
5203             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5204             RegisterInfo data_reg;
5205             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5206             context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
5207 
5208             if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2))
5209                 return false;
5210         }
5211         else // Can only occur before ARMv7
5212         {
5213             // MemU[address,2] = bits(16) UNKNOWN;
5214         }
5215 
5216         // if wback then R[n] = offset_addr;
5217         if (wback)
5218         {
5219             context.type = eContextAdjustBaseRegister;
5220             context.SetAddress (offset_addr);
5221             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5222                 return false;
5223         }
5224     }
5225 
5226     return true;
5227 }
5228 
5229 // Add with Carry (immediate) adds an immediate value and the carry flag value to a register value,
5230 // and writes the result to the destination register.  It can optionally update the condition flags
5231 // based on the result.
5232 bool
EmulateADCImm(const uint32_t opcode,const ARMEncoding encoding)5233 EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding)
5234 {
5235 #if 0
5236     // ARM pseudo code...
5237     if ConditionPassed() then
5238         EncodingSpecificOperations();
5239         (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5240         if d == 15 then         // Can only occur for ARM encoding
5241             ALUWritePC(result); // setflags is always FALSE here
5242         else
5243             R[d] = result;
5244             if setflags then
5245                 APSR.N = result<31>;
5246                 APSR.Z = IsZeroBit(result);
5247                 APSR.C = carry;
5248                 APSR.V = overflow;
5249 #endif
5250 
5251     bool success = false;
5252 
5253     if (ConditionPassed(opcode))
5254     {
5255         uint32_t Rd, Rn;
5256         uint32_t imm32; // the immediate value to be added to the value obtained from Rn
5257         bool setflags;
5258         switch (encoding)
5259         {
5260         case eEncodingT1:
5261             Rd = Bits32(opcode, 11, 8);
5262             Rn = Bits32(opcode, 19, 16);
5263             setflags = BitIsSet(opcode, 20);
5264             imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5265             if (BadReg(Rd) || BadReg(Rn))
5266                 return false;
5267             break;
5268         case eEncodingA1:
5269             Rd = Bits32(opcode, 15, 12);
5270             Rn = Bits32(opcode, 19, 16);
5271             setflags = BitIsSet(opcode, 20);
5272             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5273 
5274             if (Rd == 15 && setflags)
5275                 return EmulateSUBSPcLrEtc (opcode, encoding);
5276             break;
5277         default:
5278             return false;
5279         }
5280 
5281         // Read the first operand.
5282         int32_t val1 = ReadCoreReg(Rn, &success);
5283         if (!success)
5284             return false;
5285 
5286         AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5287 
5288         EmulateInstruction::Context context;
5289         context.type = EmulateInstruction::eContextImmediate;
5290         context.SetNoArgs ();
5291 
5292         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5293             return false;
5294     }
5295     return true;
5296 }
5297 
5298 // Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted
5299 // register value, and writes the result to the destination register.  It can optionally update the
5300 // condition flags based on the result.
5301 bool
EmulateADCReg(const uint32_t opcode,const ARMEncoding encoding)5302 EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding)
5303 {
5304 #if 0
5305     // ARM pseudo code...
5306     if ConditionPassed() then
5307         EncodingSpecificOperations();
5308         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5309         (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5310         if d == 15 then         // Can only occur for ARM encoding
5311             ALUWritePC(result); // setflags is always FALSE here
5312         else
5313             R[d] = result;
5314             if setflags then
5315                 APSR.N = result<31>;
5316                 APSR.Z = IsZeroBit(result);
5317                 APSR.C = carry;
5318                 APSR.V = overflow;
5319 #endif
5320 
5321     bool success = false;
5322 
5323     if (ConditionPassed(opcode))
5324     {
5325         uint32_t Rd, Rn, Rm;
5326         ARM_ShifterType shift_t;
5327         uint32_t shift_n; // the shift applied to the value read from Rm
5328         bool setflags;
5329         switch (encoding)
5330         {
5331         case eEncodingT1:
5332             Rd = Rn = Bits32(opcode, 2, 0);
5333             Rm = Bits32(opcode, 5, 3);
5334             setflags = !InITBlock();
5335             shift_t = SRType_LSL;
5336             shift_n = 0;
5337             break;
5338         case eEncodingT2:
5339             Rd = Bits32(opcode, 11, 8);
5340             Rn = Bits32(opcode, 19, 16);
5341             Rm = Bits32(opcode, 3, 0);
5342             setflags = BitIsSet(opcode, 20);
5343             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5344             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5345                 return false;
5346             break;
5347         case eEncodingA1:
5348             Rd = Bits32(opcode, 15, 12);
5349             Rn = Bits32(opcode, 19, 16);
5350             Rm = Bits32(opcode, 3, 0);
5351             setflags = BitIsSet(opcode, 20);
5352             shift_n = DecodeImmShiftARM(opcode, shift_t);
5353 
5354             if (Rd == 15 && setflags)
5355                 return EmulateSUBSPcLrEtc (opcode, encoding);
5356             break;
5357         default:
5358             return false;
5359         }
5360 
5361         // Read the first operand.
5362         int32_t val1 = ReadCoreReg(Rn, &success);
5363         if (!success)
5364             return false;
5365 
5366         // Read the second operand.
5367         int32_t val2 = ReadCoreReg(Rm, &success);
5368         if (!success)
5369             return false;
5370 
5371         uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5372         if (!success)
5373             return false;
5374         AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5375 
5376         EmulateInstruction::Context context;
5377         context.type = EmulateInstruction::eContextImmediate;
5378         context.SetNoArgs ();
5379 
5380         if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5381             return false;
5382     }
5383     return true;
5384 }
5385 
5386 // This instruction adds an immediate value to the PC value to form a PC-relative address,
5387 // and writes the result to the destination register.
5388 bool
EmulateADR(const uint32_t opcode,const ARMEncoding encoding)5389 EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding)
5390 {
5391 #if 0
5392     // ARM pseudo code...
5393     if ConditionPassed() then
5394         EncodingSpecificOperations();
5395         result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5396         if d == 15 then         // Can only occur for ARM encodings
5397             ALUWritePC(result);
5398         else
5399             R[d] = result;
5400 #endif
5401 
5402     bool success = false;
5403 
5404     if (ConditionPassed(opcode))
5405     {
5406         uint32_t Rd;
5407         uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5408         bool add;
5409         switch (encoding)
5410         {
5411         case eEncodingT1:
5412             Rd = Bits32(opcode, 10, 8);
5413             imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5414             add = true;
5415             break;
5416         case eEncodingT2:
5417         case eEncodingT3:
5418             Rd = Bits32(opcode, 11, 8);
5419             imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5420             add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5421             if (BadReg(Rd))
5422                 return false;
5423             break;
5424         case eEncodingA1:
5425         case eEncodingA2:
5426             Rd = Bits32(opcode, 15, 12);
5427             imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5428             add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5429             break;
5430         default:
5431             return false;
5432         }
5433 
5434         // Read the PC value.
5435         uint32_t pc = ReadCoreReg(PC_REG, &success);
5436         if (!success)
5437             return false;
5438 
5439         uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5440 
5441         EmulateInstruction::Context context;
5442         context.type = EmulateInstruction::eContextImmediate;
5443         context.SetNoArgs ();
5444 
5445         if (!WriteCoreReg(context, result, Rd))
5446             return false;
5447     }
5448     return true;
5449 }
5450 
5451 // This instruction performs a bitwise AND of a register value and an immediate value, and writes the result
5452 // to the destination register.  It can optionally update the condition flags based on the result.
5453 bool
EmulateANDImm(const uint32_t opcode,const ARMEncoding encoding)5454 EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding)
5455 {
5456 #if 0
5457     // ARM pseudo code...
5458     if ConditionPassed() then
5459         EncodingSpecificOperations();
5460         result = R[n] AND imm32;
5461         if d == 15 then         // Can only occur for ARM encoding
5462             ALUWritePC(result); // setflags is always FALSE here
5463         else
5464             R[d] = result;
5465             if setflags then
5466                 APSR.N = result<31>;
5467                 APSR.Z = IsZeroBit(result);
5468                 APSR.C = carry;
5469                 // APSR.V unchanged
5470 #endif
5471 
5472     bool success = false;
5473 
5474     if (ConditionPassed(opcode))
5475     {
5476         uint32_t Rd, Rn;
5477         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
5478         bool setflags;
5479         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5480         switch (encoding)
5481         {
5482         case eEncodingT1:
5483             Rd = Bits32(opcode, 11, 8);
5484             Rn = Bits32(opcode, 19, 16);
5485             setflags = BitIsSet(opcode, 20);
5486             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5487             // if Rd == '1111' && S == '1' then SEE TST (immediate);
5488             if (Rd == 15 && setflags)
5489                 return EmulateTSTImm(opcode, eEncodingT1);
5490             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
5491                 return false;
5492             break;
5493         case eEncodingA1:
5494             Rd = Bits32(opcode, 15, 12);
5495             Rn = Bits32(opcode, 19, 16);
5496             setflags = BitIsSet(opcode, 20);
5497             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5498 
5499             if (Rd == 15 && setflags)
5500                 return EmulateSUBSPcLrEtc (opcode, encoding);
5501             break;
5502         default:
5503             return false;
5504         }
5505 
5506         // Read the first operand.
5507         uint32_t val1 = ReadCoreReg(Rn, &success);
5508         if (!success)
5509             return false;
5510 
5511         uint32_t result = val1 & imm32;
5512 
5513         EmulateInstruction::Context context;
5514         context.type = EmulateInstruction::eContextImmediate;
5515         context.SetNoArgs ();
5516 
5517         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5518             return false;
5519     }
5520     return true;
5521 }
5522 
5523 // This instruction performs a bitwise AND of a register value and an optionally-shifted register value,
5524 // and writes the result to the destination register.  It can optionally update the condition flags
5525 // based on the result.
5526 bool
EmulateANDReg(const uint32_t opcode,const ARMEncoding encoding)5527 EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding)
5528 {
5529 #if 0
5530     // ARM pseudo code...
5531     if ConditionPassed() then
5532         EncodingSpecificOperations();
5533         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5534         result = R[n] AND shifted;
5535         if d == 15 then         // Can only occur for ARM encoding
5536             ALUWritePC(result); // setflags is always FALSE here
5537         else
5538             R[d] = result;
5539             if setflags then
5540                 APSR.N = result<31>;
5541                 APSR.Z = IsZeroBit(result);
5542                 APSR.C = carry;
5543                 // APSR.V unchanged
5544 #endif
5545 
5546     bool success = false;
5547 
5548     if (ConditionPassed(opcode))
5549     {
5550         uint32_t Rd, Rn, Rm;
5551         ARM_ShifterType shift_t;
5552         uint32_t shift_n; // the shift applied to the value read from Rm
5553         bool setflags;
5554         uint32_t carry;
5555         switch (encoding)
5556         {
5557         case eEncodingT1:
5558             Rd = Rn = Bits32(opcode, 2, 0);
5559             Rm = Bits32(opcode, 5, 3);
5560             setflags = !InITBlock();
5561             shift_t = SRType_LSL;
5562             shift_n = 0;
5563             break;
5564         case eEncodingT2:
5565             Rd = Bits32(opcode, 11, 8);
5566             Rn = Bits32(opcode, 19, 16);
5567             Rm = Bits32(opcode, 3, 0);
5568             setflags = BitIsSet(opcode, 20);
5569             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5570             // if Rd == '1111' && S == '1' then SEE TST (register);
5571             if (Rd == 15 && setflags)
5572                 return EmulateTSTReg(opcode, eEncodingT2);
5573             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
5574                 return false;
5575             break;
5576         case eEncodingA1:
5577             Rd = Bits32(opcode, 15, 12);
5578             Rn = Bits32(opcode, 19, 16);
5579             Rm = Bits32(opcode, 3, 0);
5580             setflags = BitIsSet(opcode, 20);
5581             shift_n = DecodeImmShiftARM(opcode, shift_t);
5582 
5583             if (Rd == 15 && setflags)
5584                 return EmulateSUBSPcLrEtc (opcode, encoding);
5585             break;
5586         default:
5587             return false;
5588         }
5589 
5590         // Read the first operand.
5591         uint32_t val1 = ReadCoreReg(Rn, &success);
5592         if (!success)
5593             return false;
5594 
5595         // Read the second operand.
5596         uint32_t val2 = ReadCoreReg(Rm, &success);
5597         if (!success)
5598             return false;
5599 
5600         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5601         if (!success)
5602             return false;
5603         uint32_t result = val1 & shifted;
5604 
5605         EmulateInstruction::Context context;
5606         context.type = EmulateInstruction::eContextImmediate;
5607         context.SetNoArgs ();
5608 
5609         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5610             return false;
5611     }
5612     return true;
5613 }
5614 
5615 // Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an
5616 // immediate value, and writes the result to the destination register.  It can optionally update the
5617 // condition flags based on the result.
5618 bool
EmulateBICImm(const uint32_t opcode,const ARMEncoding encoding)5619 EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding)
5620 {
5621 #if 0
5622     // ARM pseudo code...
5623     if ConditionPassed() then
5624         EncodingSpecificOperations();
5625         result = R[n] AND NOT(imm32);
5626         if d == 15 then         // Can only occur for ARM encoding
5627             ALUWritePC(result); // setflags is always FALSE here
5628         else
5629             R[d] = result;
5630             if setflags then
5631                 APSR.N = result<31>;
5632                 APSR.Z = IsZeroBit(result);
5633                 APSR.C = carry;
5634                 // APSR.V unchanged
5635 #endif
5636 
5637     bool success = false;
5638 
5639     if (ConditionPassed(opcode))
5640     {
5641         uint32_t Rd, Rn;
5642         uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn
5643         bool setflags;
5644         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5645         switch (encoding)
5646         {
5647         case eEncodingT1:
5648             Rd = Bits32(opcode, 11, 8);
5649             Rn = Bits32(opcode, 19, 16);
5650             setflags = BitIsSet(opcode, 20);
5651             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5652             if (BadReg(Rd) || BadReg(Rn))
5653                 return false;
5654             break;
5655         case eEncodingA1:
5656             Rd = Bits32(opcode, 15, 12);
5657             Rn = Bits32(opcode, 19, 16);
5658             setflags = BitIsSet(opcode, 20);
5659             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5660 
5661             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5662             if (Rd == 15 && setflags)
5663                 return EmulateSUBSPcLrEtc (opcode, encoding);
5664             break;
5665         default:
5666             return false;
5667         }
5668 
5669         // Read the first operand.
5670         uint32_t val1 = ReadCoreReg(Rn, &success);
5671         if (!success)
5672             return false;
5673 
5674         uint32_t result = val1 & ~imm32;
5675 
5676         EmulateInstruction::Context context;
5677         context.type = EmulateInstruction::eContextImmediate;
5678         context.SetNoArgs ();
5679 
5680         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5681             return false;
5682     }
5683     return true;
5684 }
5685 
5686 // Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an
5687 // optionally-shifted register value, and writes the result to the destination register.
5688 // It can optionally update the condition flags based on the result.
5689 bool
EmulateBICReg(const uint32_t opcode,const ARMEncoding encoding)5690 EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding)
5691 {
5692 #if 0
5693     // ARM pseudo code...
5694     if ConditionPassed() then
5695         EncodingSpecificOperations();
5696         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5697         result = R[n] AND NOT(shifted);
5698         if d == 15 then         // Can only occur for ARM encoding
5699             ALUWritePC(result); // setflags is always FALSE here
5700         else
5701             R[d] = result;
5702             if setflags then
5703                 APSR.N = result<31>;
5704                 APSR.Z = IsZeroBit(result);
5705                 APSR.C = carry;
5706                 // APSR.V unchanged
5707 #endif
5708 
5709     bool success = false;
5710 
5711     if (ConditionPassed(opcode))
5712     {
5713         uint32_t Rd, Rn, Rm;
5714         ARM_ShifterType shift_t;
5715         uint32_t shift_n; // the shift applied to the value read from Rm
5716         bool setflags;
5717         uint32_t carry;
5718         switch (encoding)
5719         {
5720         case eEncodingT1:
5721             Rd = Rn = Bits32(opcode, 2, 0);
5722             Rm = Bits32(opcode, 5, 3);
5723             setflags = !InITBlock();
5724             shift_t = SRType_LSL;
5725             shift_n = 0;
5726             break;
5727         case eEncodingT2:
5728             Rd = Bits32(opcode, 11, 8);
5729             Rn = Bits32(opcode, 19, 16);
5730             Rm = Bits32(opcode, 3, 0);
5731             setflags = BitIsSet(opcode, 20);
5732             shift_n = DecodeImmShiftThumb(opcode, shift_t);
5733             if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5734                 return false;
5735             break;
5736         case eEncodingA1:
5737             Rd = Bits32(opcode, 15, 12);
5738             Rn = Bits32(opcode, 19, 16);
5739             Rm = Bits32(opcode, 3, 0);
5740             setflags = BitIsSet(opcode, 20);
5741             shift_n = DecodeImmShiftARM(opcode, shift_t);
5742 
5743             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5744             if (Rd == 15 && setflags)
5745                 return EmulateSUBSPcLrEtc (opcode, encoding);
5746             break;
5747         default:
5748             return false;
5749         }
5750 
5751         // Read the first operand.
5752         uint32_t val1 = ReadCoreReg(Rn, &success);
5753         if (!success)
5754             return false;
5755 
5756         // Read the second operand.
5757         uint32_t val2 = ReadCoreReg(Rm, &success);
5758         if (!success)
5759             return false;
5760 
5761         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5762         if (!success)
5763             return false;
5764         uint32_t result = val1 & ~shifted;
5765 
5766         EmulateInstruction::Context context;
5767         context.type = EmulateInstruction::eContextImmediate;
5768         context.SetNoArgs ();
5769 
5770         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5771             return false;
5772     }
5773     return true;
5774 }
5775 
5776 // LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
5777 // from memory, and writes it to a register.  It can use offset, post-indexed, or pre-indexed addressing.
5778 bool
EmulateLDRImmediateARM(const uint32_t opcode,const ARMEncoding encoding)5779 EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding)
5780 {
5781 #if 0
5782     if ConditionPassed() then
5783         EncodingSpecificOperations();
5784         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5785         address = if index then offset_addr else R[n];
5786         data = MemU[address,4];
5787         if wback then R[n] = offset_addr;
5788         if t == 15 then
5789             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5790         elsif UnalignedSupport() || address<1:0> = '00' then
5791             R[t] = data;
5792         else // Can only apply before ARMv7
5793             R[t] = ROR(data, 8*UInt(address<1:0>));
5794 #endif
5795 
5796     bool success = false;
5797 
5798     if (ConditionPassed(opcode))
5799     {
5800         const uint32_t addr_byte_size = GetAddressByteSize();
5801 
5802         uint32_t t;
5803         uint32_t n;
5804         uint32_t imm32;
5805         bool index;
5806         bool add;
5807         bool wback;
5808 
5809         switch (encoding)
5810         {
5811             case eEncodingA1:
5812                 // if Rn == '1111' then SEE LDR (literal);
5813                 // if P == '0' && W == '1' then SEE LDRT;
5814                 // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP;
5815                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5816                 t = Bits32 (opcode, 15, 12);
5817                 n = Bits32 (opcode, 19, 16);
5818                 imm32 = Bits32 (opcode, 11, 0);
5819 
5820                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5821                 index = BitIsSet (opcode, 24);
5822                 add = BitIsSet (opcode, 23);
5823                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5824 
5825                 // if wback && n == t then UNPREDICTABLE;
5826                 if (wback && (n == t))
5827                     return false;
5828 
5829                 break;
5830 
5831             default:
5832                 return false;
5833         }
5834 
5835         addr_t address;
5836         addr_t offset_addr;
5837         addr_t base_address = ReadCoreReg (n, &success);
5838         if (!success)
5839             return false;
5840 
5841         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5842         if (add)
5843             offset_addr = base_address + imm32;
5844         else
5845             offset_addr = base_address - imm32;
5846 
5847         // address = if index then offset_addr else R[n];
5848         if (index)
5849             address = offset_addr;
5850         else
5851             address = base_address;
5852 
5853         // data = MemU[address,4];
5854 
5855         RegisterInfo base_reg;
5856         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5857 
5858         EmulateInstruction::Context context;
5859         context.type = eContextRegisterLoad;
5860         context.SetRegisterPlusOffset (base_reg, address - base_address);
5861 
5862         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5863         if (!success)
5864             return false;
5865 
5866         // if wback then R[n] = offset_addr;
5867         if (wback)
5868         {
5869             context.type = eContextAdjustBaseRegister;
5870             context.SetAddress (offset_addr);
5871             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5872                 return false;
5873         }
5874 
5875         // if t == 15 then
5876         if (t == 15)
5877         {
5878             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5879             if (BitIsClear (address, 1) && BitIsClear (address, 0))
5880             {
5881                 // LoadWritePC (data);
5882                 context.type = eContextRegisterLoad;
5883                 context.SetRegisterPlusOffset (base_reg, address - base_address);
5884                 LoadWritePC (context, data);
5885             }
5886             else
5887                   return false;
5888         }
5889         // elsif UnalignedSupport() || address<1:0> = '00' then
5890         else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5891         {
5892             // R[t] = data;
5893             context.type = eContextRegisterLoad;
5894             context.SetRegisterPlusOffset (base_reg, address - base_address);
5895             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5896                 return false;
5897         }
5898         // else // Can only apply before ARMv7
5899         else
5900         {
5901             // R[t] = ROR(data, 8*UInt(address<1:0>));
5902             data = ROR (data, Bits32 (address, 1, 0), &success);
5903             if (!success)
5904                 return false;
5905             context.type = eContextRegisterLoad;
5906             context.SetImmediate (data);
5907             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5908                 return false;
5909         }
5910 
5911     }
5912     return true;
5913 }
5914 
5915 // LDR (register) calculates an address from a base register value and an offset register value, loads a word
5916 // from memory, and writes it to a resgister.  The offset register value can optionally be shifted.
5917 bool
EmulateLDRRegister(const uint32_t opcode,const ARMEncoding encoding)5918 EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding)
5919 {
5920 #if 0
5921     if ConditionPassed() then
5922         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5923         offset = Shift(R[m], shift_t, shift_n, APSR.C);
5924         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5925         address = if index then offset_addr else R[n];
5926         data = MemU[address,4];
5927         if wback then R[n] = offset_addr;
5928         if t == 15 then
5929             if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5930         elsif UnalignedSupport() || address<1:0> = '00' then
5931             R[t] = data;
5932         else // Can only apply before ARMv7
5933             if CurrentInstrSet() == InstrSet_ARM then
5934                 R[t] = ROR(data, 8*UInt(address<1:0>));
5935             else
5936                 R[t] = bits(32) UNKNOWN;
5937 #endif
5938 
5939     bool success = false;
5940 
5941     if (ConditionPassed(opcode))
5942     {
5943         const uint32_t addr_byte_size = GetAddressByteSize();
5944 
5945         uint32_t t;
5946         uint32_t n;
5947         uint32_t m;
5948         bool index;
5949         bool add;
5950         bool wback;
5951         ARM_ShifterType shift_t;
5952         uint32_t shift_n;
5953 
5954         switch (encoding)
5955         {
5956             case eEncodingT1:
5957                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5958                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5959                 t = Bits32 (opcode, 2, 0);
5960                 n = Bits32 (opcode, 5, 3);
5961                 m = Bits32 (opcode, 8, 6);
5962 
5963                 // index = TRUE; add = TRUE; wback = FALSE;
5964                 index = true;
5965                 add = true;
5966                 wback = false;
5967 
5968                 // (shift_t, shift_n) = (SRType_LSL, 0);
5969                 shift_t = SRType_LSL;
5970                 shift_n = 0;
5971 
5972                 break;
5973 
5974             case eEncodingT2:
5975                 // if Rn == '1111' then SEE LDR (literal);
5976                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5977                 t = Bits32 (opcode, 15, 12);
5978                 n = Bits32 (opcode, 19, 16);
5979                 m = Bits32 (opcode, 3, 0);
5980 
5981                 // index = TRUE; add = TRUE; wback = FALSE;
5982                 index = true;
5983                 add = true;
5984                 wback = false;
5985 
5986                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5987                 shift_t = SRType_LSL;
5988                 shift_n = Bits32 (opcode, 5, 4);
5989 
5990                 // if BadReg(m) then UNPREDICTABLE;
5991                 if (BadReg (m))
5992                     return false;
5993 
5994                 // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
5995                 if ((t == 15) && InITBlock() && !LastInITBlock())
5996                     return false;
5997 
5998                 break;
5999 
6000             case eEncodingA1:
6001             {
6002                 // if P == '0' && W == '1' then SEE LDRT;
6003                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6004                 t = Bits32 (opcode, 15, 12);
6005                 n = Bits32 (opcode, 19, 16);
6006                 m = Bits32 (opcode, 3, 0);
6007 
6008                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6009                 index = BitIsSet (opcode, 24);
6010                 add = BitIsSet (opcode, 23);
6011                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6012 
6013                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6014                 uint32_t type = Bits32 (opcode, 6, 5);
6015                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6016                 shift_n = DecodeImmShift (type, imm5, shift_t);
6017 
6018                 // if m == 15 then UNPREDICTABLE;
6019                 if (m == 15)
6020                     return false;
6021 
6022                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6023                 if (wback && ((n == 15) || (n == t)))
6024                     return false;
6025             }
6026                 break;
6027 
6028 
6029             default:
6030                 return false;
6031         }
6032 
6033         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6034         if (!success)
6035             return false;
6036 
6037         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6038         if (!success)
6039             return false;
6040 
6041         addr_t offset_addr;
6042         addr_t address;
6043 
6044         // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an application level alias for the CPSR".
6045         addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success);
6046         if (!success)
6047             return false;
6048 
6049         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6050         if (add)
6051             offset_addr = Rn + offset;
6052         else
6053             offset_addr = Rn - offset;
6054 
6055         // address = if index then offset_addr else R[n];
6056             if (index)
6057                 address = offset_addr;
6058             else
6059                 address = Rn;
6060 
6061         // data = MemU[address,4];
6062         RegisterInfo base_reg;
6063         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6064 
6065         EmulateInstruction::Context context;
6066         context.type = eContextRegisterLoad;
6067         context.SetRegisterPlusOffset (base_reg, address - Rn);
6068 
6069         uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
6070         if (!success)
6071             return false;
6072 
6073         // if wback then R[n] = offset_addr;
6074         if (wback)
6075         {
6076             context.type = eContextAdjustBaseRegister;
6077             context.SetAddress (offset_addr);
6078             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6079                 return false;
6080         }
6081 
6082         // if t == 15 then
6083         if (t == 15)
6084         {
6085             // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6086             if (BitIsClear (address, 1) && BitIsClear (address, 0))
6087             {
6088                 context.type = eContextRegisterLoad;
6089                 context.SetRegisterPlusOffset (base_reg, address - Rn);
6090                 LoadWritePC (context, data);
6091             }
6092             else
6093                 return false;
6094         }
6095         // elsif UnalignedSupport() || address<1:0> = '00' then
6096         else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
6097         {
6098             // R[t] = data;
6099             context.type = eContextRegisterLoad;
6100             context.SetRegisterPlusOffset (base_reg, address - Rn);
6101             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6102                 return false;
6103         }
6104         else // Can only apply before ARMv7
6105         {
6106             // if CurrentInstrSet() == InstrSet_ARM then
6107             if (CurrentInstrSet () == eModeARM)
6108             {
6109                 // R[t] = ROR(data, 8*UInt(address<1:0>));
6110                 data = ROR (data, Bits32 (address, 1, 0), &success);
6111                 if (!success)
6112                     return false;
6113                 context.type = eContextRegisterLoad;
6114                 context.SetImmediate (data);
6115                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6116                     return false;
6117             }
6118             else
6119             {
6120                 // R[t] = bits(32) UNKNOWN;
6121                 WriteBits32Unknown (t);
6122             }
6123         }
6124     }
6125     return true;
6126 }
6127 
6128 // LDRB (immediate, Thumb)
6129 bool
EmulateLDRBImmediate(const uint32_t opcode,const ARMEncoding encoding)6130 EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6131 {
6132 #if 0
6133     if ConditionPassed() then
6134         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6135         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6136         address = if index then offset_addr else R[n];
6137         R[t] = ZeroExtend(MemU[address,1], 32);
6138         if wback then R[n] = offset_addr;
6139 #endif
6140 
6141     bool success = false;
6142 
6143     if (ConditionPassed(opcode))
6144     {
6145         uint32_t t;
6146         uint32_t n;
6147         uint32_t imm32;
6148         bool index;
6149         bool add;
6150         bool wback;
6151 
6152         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6153         switch (encoding)
6154         {
6155             case eEncodingT1:
6156                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6157                 t = Bits32 (opcode, 2, 0);
6158                 n = Bits32 (opcode, 5, 3);
6159                 imm32 = Bits32 (opcode, 10, 6);
6160 
6161                 // index = TRUE; add = TRUE; wback = FALSE;
6162                 index = true;
6163                 add = true;
6164                 wback= false;
6165 
6166                 break;
6167 
6168             case eEncodingT2:
6169                 // if Rt == '1111' then SEE PLD;
6170                 // if Rn == '1111' then SEE LDRB (literal);
6171                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6172                 t = Bits32 (opcode, 15, 12);
6173                 n = Bits32 (opcode, 19, 16);
6174                 imm32 = Bits32 (opcode, 11, 0);
6175 
6176                 // index = TRUE; add = TRUE; wback = FALSE;
6177                 index = true;
6178                 add = true;
6179                 wback = false;
6180 
6181                 // if t == 13 then UNPREDICTABLE;
6182                 if (t == 13)
6183                     return false;
6184 
6185                 break;
6186 
6187             case eEncodingT3:
6188                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6189                 // if Rn == '1111' then SEE LDRB (literal);
6190                 // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6191                 // if P == '0' && W == '0' then UNDEFINED;
6192                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6193                     return false;
6194 
6195                   // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6196                 t = Bits32 (opcode, 15, 12);
6197                 n = Bits32 (opcode, 19, 16);
6198                 imm32 = Bits32 (opcode, 7, 0);
6199 
6200                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6201                 index = BitIsSet (opcode, 10);
6202                 add = BitIsSet (opcode, 9);
6203                 wback = BitIsSet (opcode, 8);
6204 
6205                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6206                 if (BadReg (t) || (wback && (n == t)))
6207                     return false;
6208 
6209                 break;
6210 
6211             default:
6212                 return false;
6213         }
6214 
6215         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6216         if (!success)
6217             return false;
6218 
6219         addr_t address;
6220         addr_t offset_addr;
6221 
6222         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6223         if (add)
6224             offset_addr = Rn + imm32;
6225         else
6226             offset_addr = Rn - imm32;
6227 
6228         // address = if index then offset_addr else R[n];
6229         if (index)
6230             address = offset_addr;
6231         else
6232             address = Rn;
6233 
6234         // R[t] = ZeroExtend(MemU[address,1], 32);
6235         RegisterInfo base_reg;
6236         RegisterInfo data_reg;
6237         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6238         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6239 
6240         EmulateInstruction::Context context;
6241         context.type = eContextRegisterLoad;
6242         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
6243 
6244         uint64_t data = MemURead (context, address, 1, 0, &success);
6245         if (!success)
6246             return false;
6247 
6248         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6249             return false;
6250 
6251         // if wback then R[n] = offset_addr;
6252         if (wback)
6253         {
6254             context.type = eContextAdjustBaseRegister;
6255             context.SetAddress (offset_addr);
6256             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6257                 return false;
6258         }
6259     }
6260     return true;
6261 }
6262 
6263 // LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6264 // zero-extends it to form a 32-bit word and writes it to a register.
6265 bool
EmulateLDRBLiteral(const uint32_t opcode,const ARMEncoding encoding)6266 EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6267 {
6268 #if 0
6269     if ConditionPassed() then
6270         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6271         base = Align(PC,4);
6272         address = if add then (base + imm32) else (base - imm32);
6273         R[t] = ZeroExtend(MemU[address,1], 32);
6274 #endif
6275 
6276     bool success = false;
6277 
6278     if (ConditionPassed(opcode))
6279     {
6280         uint32_t t;
6281         uint32_t imm32;
6282         bool add;
6283         switch (encoding)
6284         {
6285             case eEncodingT1:
6286                 // if Rt == '1111' then SEE PLD;
6287                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6288                 t = Bits32 (opcode, 15, 12);
6289                 imm32 = Bits32 (opcode, 11, 0);
6290                 add = BitIsSet (opcode, 23);
6291 
6292                 // if t == 13 then UNPREDICTABLE;
6293                 if (t == 13)
6294                     return false;
6295 
6296                 break;
6297 
6298             case eEncodingA1:
6299                 // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6300                 t = Bits32 (opcode, 15, 12);
6301                 imm32 = Bits32 (opcode, 11, 0);
6302                 add = BitIsSet (opcode, 23);
6303 
6304                 // if t == 15 then UNPREDICTABLE;
6305                 if (t == 15)
6306                     return false;
6307                 break;
6308 
6309             default:
6310                 return false;
6311         }
6312 
6313         // base = Align(PC,4);
6314         uint32_t pc_val = ReadCoreReg (PC_REG, &success);
6315         if (!success)
6316             return false;
6317 
6318         uint32_t base = AlignPC (pc_val);
6319 
6320         addr_t address;
6321         // address = if add then (base + imm32) else (base - imm32);
6322         if (add)
6323             address = base + imm32;
6324         else
6325             address = base - imm32;
6326 
6327         // R[t] = ZeroExtend(MemU[address,1], 32);
6328         EmulateInstruction::Context context;
6329         context.type = eContextRelativeBranchImmediate;
6330         context.SetImmediate (address - base);
6331 
6332         uint64_t data = MemURead (context, address, 1, 0, &success);
6333         if (!success)
6334             return false;
6335 
6336         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6337             return false;
6338     }
6339     return true;
6340 }
6341 
6342 // LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from
6343 // memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6344 // optionally be shifted.
6345 bool
EmulateLDRBRegister(const uint32_t opcode,const ARMEncoding encoding)6346 EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding)
6347 {
6348 #if 0
6349     if ConditionPassed() then
6350         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6351         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6352         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6353         address = if index then offset_addr else R[n];
6354         R[t] = ZeroExtend(MemU[address,1],32);
6355         if wback then R[n] = offset_addr;
6356 #endif
6357 
6358     bool success = false;
6359 
6360     if (ConditionPassed(opcode))
6361     {
6362         uint32_t t;
6363         uint32_t n;
6364         uint32_t m;
6365         bool index;
6366         bool add;
6367         bool wback;
6368         ARM_ShifterType shift_t;
6369         uint32_t shift_n;
6370 
6371         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6372         switch (encoding)
6373         {
6374             case eEncodingT1:
6375                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6376                 t = Bits32 (opcode, 2, 0);
6377                 n = Bits32 (opcode, 5, 3);
6378                 m = Bits32 (opcode, 8, 6);
6379 
6380                 // index = TRUE; add = TRUE; wback = FALSE;
6381                 index = true;
6382                 add = true;
6383                 wback = false;
6384 
6385                 // (shift_t, shift_n) = (SRType_LSL, 0);
6386                 shift_t = SRType_LSL;
6387                 shift_n = 0;
6388                 break;
6389 
6390             case eEncodingT2:
6391                 // if Rt == '1111' then SEE PLD;
6392                 // if Rn == '1111' then SEE LDRB (literal);
6393                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6394                 t = Bits32 (opcode, 15, 12);
6395                 n = Bits32 (opcode, 19, 16);
6396                 m = Bits32 (opcode, 3, 0);
6397 
6398                 // index = TRUE; add = TRUE; wback = FALSE;
6399                 index = true;
6400                 add = true;
6401                 wback = false;
6402 
6403                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6404                 shift_t = SRType_LSL;
6405                 shift_n = Bits32 (opcode, 5, 4);
6406 
6407                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6408                 if ((t == 13) || BadReg (m))
6409                     return false;
6410                 break;
6411 
6412             case eEncodingA1:
6413             {
6414                 // if P == '0' && W == '1' then SEE LDRBT;
6415                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6416                 t = Bits32 (opcode, 15, 12);
6417                 n = Bits32 (opcode, 19, 16);
6418                 m = Bits32 (opcode, 3, 0);
6419 
6420                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6421                 index = BitIsSet (opcode, 24);
6422                 add = BitIsSet (opcode, 23);
6423                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6424 
6425                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6426                 uint32_t type = Bits32 (opcode, 6, 5);
6427                 uint32_t imm5 = Bits32 (opcode, 11, 7);
6428                 shift_n = DecodeImmShift (type, imm5, shift_t);
6429 
6430                 // if t == 15 || m == 15 then UNPREDICTABLE;
6431                 if ((t == 15) || (m == 15))
6432                     return false;
6433 
6434                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6435                 if (wback && ((n == 15) || (n == t)))
6436                     return false;
6437             }
6438                 break;
6439 
6440             default:
6441                 return false;
6442         }
6443 
6444         addr_t offset_addr;
6445         addr_t address;
6446 
6447         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6448         uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6449         if (!success)
6450             return false;
6451 
6452         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6453         if (!success)
6454             return false;
6455 
6456         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6457         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6458         if (!success)
6459             return false;
6460 
6461         if (add)
6462             offset_addr = Rn + offset;
6463         else
6464             offset_addr = Rn - offset;
6465 
6466         // address = if index then offset_addr else R[n];
6467         if (index)
6468             address = offset_addr;
6469         else
6470             address = Rn;
6471 
6472         // R[t] = ZeroExtend(MemU[address,1],32);
6473         RegisterInfo base_reg;
6474         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6475 
6476         EmulateInstruction::Context context;
6477         context.type = eContextRegisterLoad;
6478         context.SetRegisterPlusOffset (base_reg, address - Rn);
6479 
6480         uint64_t data = MemURead (context, address, 1, 0, &success);
6481         if (!success)
6482             return false;
6483 
6484         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6485             return false;
6486 
6487         // if wback then R[n] = offset_addr;
6488         if (wback)
6489         {
6490             context.type = eContextAdjustBaseRegister;
6491             context.SetAddress (offset_addr);
6492             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6493                 return false;
6494         }
6495     }
6496     return true;
6497 }
6498 
6499 // LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a
6500 // halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register.  It can use offset,
6501 // post-indexed, or pre-indexed addressing.
6502 bool
EmulateLDRHImmediate(const uint32_t opcode,const ARMEncoding encoding)6503 EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding)
6504 {
6505 #if 0
6506     if ConditionPassed() then
6507         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6508         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6509         address = if index then offset_addr else R[n];
6510         data = MemU[address,2];
6511         if wback then R[n] = offset_addr;
6512         if UnalignedSupport() || address<0> = '0' then
6513             R[t] = ZeroExtend(data, 32);
6514         else // Can only apply before ARMv7
6515             R[t] = bits(32) UNKNOWN;
6516 #endif
6517 
6518 
6519     bool success = false;
6520 
6521     if (ConditionPassed(opcode))
6522     {
6523         uint32_t t;
6524         uint32_t n;
6525         uint32_t imm32;
6526         bool index;
6527         bool add;
6528         bool wback;
6529 
6530         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6531         switch (encoding)
6532         {
6533             case eEncodingT1:
6534                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
6535                 t = Bits32 (opcode, 2, 0);
6536                 n = Bits32 (opcode, 5, 3);
6537                 imm32 = Bits32 (opcode, 10, 6) << 1;
6538 
6539                 // index = TRUE; add = TRUE; wback = FALSE;
6540                 index = true;
6541                 add = true;
6542                 wback = false;
6543 
6544                 break;
6545 
6546             case eEncodingT2:
6547                 // if Rt == '1111' then SEE "Unallocated memory hints";
6548                 // if Rn == '1111' then SEE LDRH (literal);
6549                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6550                 t = Bits32 (opcode, 15, 12);
6551                 n = Bits32 (opcode, 19, 16);
6552                 imm32 = Bits32 (opcode, 11, 0);
6553 
6554                 // index = TRUE; add = TRUE; wback = FALSE;
6555                 index = true;
6556                 add = true;
6557                 wback = false;
6558 
6559                 // if t == 13 then UNPREDICTABLE;
6560                 if (t == 13)
6561                     return false;
6562                 break;
6563 
6564             case eEncodingT3:
6565                 // if Rn == '1111' then SEE LDRH (literal);
6566                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
6567                 // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
6568                 // if P == '0' && W == '0' then UNDEFINED;
6569                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6570                     return false;
6571 
6572                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6573                 t = Bits32 (opcode, 15, 12);
6574                 n = Bits32 (opcode, 19, 16);
6575                 imm32 = Bits32 (opcode, 7, 0);
6576 
6577                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6578                 index = BitIsSet (opcode, 10);
6579                 add = BitIsSet (opcode, 9);
6580                 wback = BitIsSet (opcode, 8);
6581 
6582                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6583                 if (BadReg (t) || (wback && (n == t)))
6584                     return false;
6585                 break;
6586 
6587             default:
6588                 return false;
6589         }
6590 
6591         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6592         uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6593         if (!success)
6594             return false;
6595 
6596         addr_t offset_addr;
6597         addr_t address;
6598 
6599         if (add)
6600             offset_addr = Rn + imm32;
6601         else
6602             offset_addr = Rn - imm32;
6603 
6604         // address = if index then offset_addr else R[n];
6605         if (index)
6606             address = offset_addr;
6607         else
6608             address = Rn;
6609 
6610         // data = MemU[address,2];
6611         RegisterInfo base_reg;
6612         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6613 
6614         EmulateInstruction::Context context;
6615         context.type = eContextRegisterLoad;
6616         context.SetRegisterPlusOffset (base_reg, address - Rn);
6617 
6618         uint64_t data = MemURead (context, address, 2, 0, &success);
6619         if (!success)
6620             return false;
6621 
6622         // if wback then R[n] = offset_addr;
6623         if (wback)
6624         {
6625             context.type = eContextAdjustBaseRegister;
6626             context.SetAddress (offset_addr);
6627             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6628                 return false;
6629         }
6630 
6631         // if UnalignedSupport() || address<0> = '0' then
6632         if (UnalignedSupport () || BitIsClear (address, 0))
6633         {
6634             // R[t] = ZeroExtend(data, 32);
6635             context.type = eContextRegisterLoad;
6636             context.SetRegisterPlusOffset (base_reg, address - Rn);
6637             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6638                 return false;
6639         }
6640         else // Can only apply before ARMv7
6641         {
6642             // R[t] = bits(32) UNKNOWN;
6643             WriteBits32Unknown (t);
6644         }
6645     }
6646     return true;
6647 }
6648 
6649 // LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory,
6650 // zero-extends it to form a 32-bit word, and writes it to a register.
6651 bool
EmulateLDRHLiteral(const uint32_t opcode,const ARMEncoding encoding)6652 EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding)
6653 {
6654 #if 0
6655     if ConditionPassed() then
6656         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6657         base = Align(PC,4);
6658         address = if add then (base + imm32) else (base - imm32);
6659         data = MemU[address,2];
6660         if UnalignedSupport() || address<0> = '0' then
6661             R[t] = ZeroExtend(data, 32);
6662         else // Can only apply before ARMv7
6663             R[t] = bits(32) UNKNOWN;
6664 #endif
6665 
6666     bool success = false;
6667 
6668     if (ConditionPassed(opcode))
6669     {
6670         uint32_t t;
6671         uint32_t imm32;
6672         bool add;
6673 
6674         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6675         switch (encoding)
6676         {
6677             case eEncodingT1:
6678                 // if Rt == '1111' then SEE "Unallocated memory hints";
6679                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6680                 t = Bits32 (opcode, 15, 12);
6681                 imm32 = Bits32 (opcode, 11, 0);
6682                 add = BitIsSet (opcode, 23);
6683 
6684                 // if t == 13 then UNPREDICTABLE;
6685                 if (t == 13)
6686                     return false;
6687 
6688                 break;
6689 
6690             case eEncodingA1:
6691             {
6692                 uint32_t imm4H = Bits32 (opcode, 11, 8);
6693                 uint32_t imm4L = Bits32 (opcode, 3, 0);
6694 
6695                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6696                 t = Bits32 (opcode, 15, 12);
6697                 imm32 = (imm4H << 4) | imm4L;
6698                 add = BitIsSet (opcode, 23);
6699 
6700                 // if t == 15 then UNPREDICTABLE;
6701                 if (t == 15)
6702                     return false;
6703                 break;
6704             }
6705 
6706             default:
6707                 return false;
6708         }
6709 
6710         // base = Align(PC,4);
6711         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6712         if (!success)
6713             return false;
6714 
6715         addr_t base = AlignPC (pc_value);
6716         addr_t address;
6717 
6718         // address = if add then (base + imm32) else (base - imm32);
6719         if (add)
6720             address = base + imm32;
6721         else
6722             address = base - imm32;
6723 
6724         // data = MemU[address,2];
6725         RegisterInfo base_reg;
6726         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
6727 
6728         EmulateInstruction::Context context;
6729         context.type = eContextRegisterLoad;
6730         context.SetRegisterPlusOffset (base_reg, address - base);
6731 
6732         uint64_t data = MemURead (context, address, 2, 0, &success);
6733         if (!success)
6734             return false;
6735 
6736 
6737         // if UnalignedSupport() || address<0> = '0' then
6738         if (UnalignedSupport () || BitIsClear (address, 0))
6739         {
6740             // R[t] = ZeroExtend(data, 32);
6741             context.type = eContextRegisterLoad;
6742             context.SetRegisterPlusOffset (base_reg, address - base);
6743             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6744                 return false;
6745 
6746         }
6747         else // Can only apply before ARMv7
6748         {
6749             // R[t] = bits(32) UNKNOWN;
6750             WriteBits32Unknown (t);
6751         }
6752     }
6753     return true;
6754 }
6755 
6756 // LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword
6757 // from memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6758 // be shifted left by 0, 1, 2, or 3 bits.
6759 bool
EmulateLDRHRegister(const uint32_t opcode,const ARMEncoding encoding)6760 EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding)
6761 {
6762 #if 0
6763     if ConditionPassed() then
6764         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6765         offset = Shift(R[m], shift_t, shift_n, APSR.C);
6766         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6767         address = if index then offset_addr else R[n];
6768         data = MemU[address,2];
6769         if wback then R[n] = offset_addr;
6770         if UnalignedSupport() || address<0> = '0' then
6771             R[t] = ZeroExtend(data, 32);
6772         else // Can only apply before ARMv7
6773             R[t] = bits(32) UNKNOWN;
6774 #endif
6775 
6776     bool success = false;
6777 
6778     if (ConditionPassed(opcode))
6779     {
6780         uint32_t t;
6781         uint32_t n;
6782         uint32_t m;
6783         bool index;
6784         bool add;
6785         bool wback;
6786         ARM_ShifterType shift_t;
6787         uint32_t shift_n;
6788 
6789         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6790         switch (encoding)
6791         {
6792             case eEncodingT1:
6793                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6794                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6795                 t = Bits32 (opcode, 2, 0);
6796                 n = Bits32 (opcode, 5, 3);
6797                 m = Bits32 (opcode, 8, 6);
6798 
6799                 // index = TRUE; add = TRUE; wback = FALSE;
6800                 index = true;
6801                 add = true;
6802                 wback = false;
6803 
6804                 // (shift_t, shift_n) = (SRType_LSL, 0);
6805                 shift_t = SRType_LSL;
6806                 shift_n = 0;
6807 
6808                 break;
6809 
6810             case eEncodingT2:
6811                 // if Rn == '1111' then SEE LDRH (literal);
6812                 // if Rt == '1111' then SEE "Unallocated memory hints";
6813                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6814                 t = Bits32 (opcode, 15, 12);
6815                 n = Bits32 (opcode, 19, 16);
6816                 m = Bits32 (opcode, 3, 0);
6817 
6818                 // index = TRUE; add = TRUE; wback = FALSE;
6819                 index = true;
6820                 add = true;
6821                 wback = false;
6822 
6823                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6824                 shift_t = SRType_LSL;
6825                 shift_n = Bits32 (opcode, 5, 4);
6826 
6827                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
6828                 if ((t == 13) || BadReg (m))
6829                     return false;
6830                 break;
6831 
6832             case eEncodingA1:
6833                 // if P == '0' && W == '1' then SEE LDRHT;
6834                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6835                 t = Bits32 (opcode, 15, 12);
6836                 n = Bits32 (opcode, 19, 16);
6837                 m = Bits32 (opcode, 3, 0);
6838 
6839                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6840                 index = BitIsSet (opcode, 24);
6841                 add = BitIsSet (opcode, 23);
6842                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6843 
6844                 // (shift_t, shift_n) = (SRType_LSL, 0);
6845                 shift_t = SRType_LSL;
6846                 shift_n = 0;
6847 
6848                 // if t == 15 || m == 15 then UNPREDICTABLE;
6849                 if ((t == 15) || (m == 15))
6850                     return false;
6851 
6852                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6853                 if (wback && ((n == 15) || (n == t)))
6854                     return false;
6855 
6856                 break;
6857 
6858             default:
6859                 return false;
6860         }
6861 
6862         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6863 
6864         uint64_t Rm  = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6865         if (!success)
6866             return false;
6867 
6868         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6869         if (!success)
6870             return false;
6871 
6872         addr_t offset_addr;
6873         addr_t address;
6874 
6875         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6876         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6877         if (!success)
6878             return false;
6879 
6880         if (add)
6881             offset_addr = Rn + offset;
6882         else
6883             offset_addr = Rn - offset;
6884 
6885         // address = if index then offset_addr else R[n];
6886         if (index)
6887             address = offset_addr;
6888         else
6889             address = Rn;
6890 
6891         // data = MemU[address,2];
6892         RegisterInfo base_reg;
6893         RegisterInfo offset_reg;
6894         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6895         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
6896 
6897         EmulateInstruction::Context context;
6898         context.type = eContextRegisterLoad;
6899         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6900         uint64_t data = MemURead (context, address, 2, 0, &success);
6901         if (!success)
6902             return false;
6903 
6904         // if wback then R[n] = offset_addr;
6905         if (wback)
6906         {
6907             context.type = eContextAdjustBaseRegister;
6908             context.SetAddress (offset_addr);
6909             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6910                 return false;
6911         }
6912 
6913         // if UnalignedSupport() || address<0> = '0' then
6914         if (UnalignedSupport() || BitIsClear (address, 0))
6915         {
6916             // R[t] = ZeroExtend(data, 32);
6917             context.type = eContextRegisterLoad;
6918             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6919             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6920                 return false;
6921         }
6922         else // Can only apply before ARMv7
6923         {
6924             // R[t] = bits(32) UNKNOWN;
6925             WriteBits32Unknown (t);
6926         }
6927     }
6928     return true;
6929 }
6930 
6931 // LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from
6932 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed,
6933 // or pre-indexed addressing.
6934 bool
EmulateLDRSBImmediate(const uint32_t opcode,const ARMEncoding encoding)6935 EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6936 {
6937 #if 0
6938     if ConditionPassed() then
6939         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6940         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6941         address = if index then offset_addr else R[n];
6942         R[t] = SignExtend(MemU[address,1], 32);
6943         if wback then R[n] = offset_addr;
6944 #endif
6945 
6946     bool success = false;
6947 
6948     if (ConditionPassed(opcode))
6949     {
6950         uint32_t t;
6951         uint32_t n;
6952         uint32_t imm32;
6953         bool index;
6954         bool add;
6955         bool wback;
6956 
6957         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6958         switch (encoding)
6959         {
6960             case eEncodingT1:
6961                 // if Rt == '1111' then SEE PLI;
6962                 // if Rn == '1111' then SEE LDRSB (literal);
6963                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6964                 t = Bits32 (opcode, 15, 12);
6965                 n = Bits32 (opcode, 19, 16);
6966                 imm32 = Bits32 (opcode, 11, 0);
6967 
6968                 // index = TRUE; add = TRUE; wback = FALSE;
6969                 index = true;
6970                 add = true;
6971                 wback = false;
6972 
6973                 // if t == 13 then UNPREDICTABLE;
6974                 if (t == 13)
6975                     return false;
6976 
6977                 break;
6978 
6979             case eEncodingT2:
6980                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
6981                 // if Rn == '1111' then SEE LDRSB (literal);
6982                 // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
6983                 // if P == '0' && W == '0' then UNDEFINED;
6984                 if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6985                     return false;
6986 
6987                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6988                 t = Bits32 (opcode, 15, 12);
6989                 n = Bits32 (opcode, 19, 16);
6990                 imm32 = Bits32 (opcode, 7, 0);
6991 
6992                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6993                 index = BitIsSet (opcode, 10);
6994                 add = BitIsSet (opcode, 9);
6995                 wback = BitIsSet (opcode, 8);
6996 
6997                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6998                   if (((t == 13) || ((t == 15)
6999                                      && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8))))
7000                       || (wback && (n == t)))
7001                     return false;
7002 
7003                 break;
7004 
7005             case eEncodingA1:
7006             {
7007                 // if Rn == '1111' then SEE LDRSB (literal);
7008                 // if P == '0' && W == '1' then SEE LDRSBT;
7009                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7010                 t = Bits32 (opcode, 15, 12);
7011                 n = Bits32 (opcode, 19, 16);
7012 
7013                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7014                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7015                 imm32 = (imm4H << 4) | imm4L;
7016 
7017                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7018                 index = BitIsSet (opcode, 24);
7019                 add = BitIsSet (opcode, 23);
7020                 wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
7021 
7022                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7023                 if ((t == 15) || (wback && (n == t)))
7024                     return false;
7025 
7026                 break;
7027             }
7028 
7029             default:
7030                 return false;
7031         }
7032 
7033         uint64_t Rn = ReadCoreReg (n, &success);
7034         if (!success)
7035             return false;
7036 
7037         addr_t offset_addr;
7038         addr_t address;
7039 
7040         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7041         if (add)
7042             offset_addr = Rn + imm32;
7043         else
7044             offset_addr = Rn - imm32;
7045 
7046         // address = if index then offset_addr else R[n];
7047         if (index)
7048             address = offset_addr;
7049         else
7050             address = Rn;
7051 
7052         // R[t] = SignExtend(MemU[address,1], 32);
7053         RegisterInfo base_reg;
7054         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7055 
7056         EmulateInstruction::Context context;
7057         context.type = eContextRegisterLoad;
7058         context.SetRegisterPlusOffset (base_reg, address - Rn);
7059 
7060         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7061         if (!success)
7062             return false;
7063 
7064         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7065         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7066             return false;
7067 
7068         // if wback then R[n] = offset_addr;
7069         if (wback)
7070         {
7071             context.type = eContextAdjustBaseRegister;
7072             context.SetAddress (offset_addr);
7073             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7074                 return false;
7075         }
7076     }
7077 
7078     return true;
7079 }
7080 
7081 // LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
7082 // sign-extends it to form a 32-bit word, and writes tit to a register.
7083 bool
EmulateLDRSBLiteral(const uint32_t opcode,const ARMEncoding encoding)7084 EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding)
7085 {
7086 #if 0
7087     if ConditionPassed() then
7088         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7089         base = Align(PC,4);
7090         address = if add then (base + imm32) else (base - imm32);
7091         R[t] = SignExtend(MemU[address,1], 32);
7092 #endif
7093 
7094     bool success = false;
7095 
7096     if (ConditionPassed(opcode))
7097     {
7098         uint32_t t;
7099         uint32_t imm32;
7100         bool add;
7101 
7102         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7103         switch (encoding)
7104         {
7105             case eEncodingT1:
7106                 // if Rt == '1111' then SEE PLI;
7107                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7108                 t = Bits32 (opcode, 15, 12);
7109                 imm32 = Bits32 (opcode, 11, 0);
7110                 add = BitIsSet (opcode, 23);
7111 
7112                 // if t == 13 then UNPREDICTABLE;
7113                 if (t == 13)
7114                     return false;
7115 
7116                 break;
7117 
7118             case eEncodingA1:
7119             {
7120                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7121                 t = Bits32 (opcode, 15, 12);
7122                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7123                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7124                 imm32 = (imm4H << 4) | imm4L;
7125                 add = BitIsSet (opcode, 23);
7126 
7127                 // if t == 15 then UNPREDICTABLE;
7128                 if (t == 15)
7129                     return false;
7130 
7131                 break;
7132             }
7133 
7134             default:
7135                 return false;
7136         }
7137 
7138         // base = Align(PC,4);
7139         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7140         if (!success)
7141             return false;
7142         uint64_t base = AlignPC (pc_value);
7143 
7144         // address = if add then (base + imm32) else (base - imm32);
7145         addr_t address;
7146         if (add)
7147             address = base + imm32;
7148         else
7149             address = base - imm32;
7150 
7151         // R[t] = SignExtend(MemU[address,1], 32);
7152         RegisterInfo base_reg;
7153         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7154 
7155         EmulateInstruction::Context context;
7156         context.type = eContextRegisterLoad;
7157         context.SetRegisterPlusOffset (base_reg, address - base);
7158 
7159         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7160         if (!success)
7161             return false;
7162 
7163         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7164         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7165             return false;
7166     }
7167     return true;
7168 }
7169 
7170 // LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from
7171 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7172 // shifted left by 0, 1, 2, or 3 bits.
7173 bool
EmulateLDRSBRegister(const uint32_t opcode,const ARMEncoding encoding)7174 EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding)
7175 {
7176 #if 0
7177     if ConditionPassed() then
7178         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7179         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7180         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7181         address = if index then offset_addr else R[n];
7182         R[t] = SignExtend(MemU[address,1], 32);
7183         if wback then R[n] = offset_addr;
7184 #endif
7185 
7186     bool success = false;
7187 
7188     if (ConditionPassed(opcode))
7189     {
7190         uint32_t t;
7191         uint32_t n;
7192         uint32_t m;
7193         bool index;
7194         bool add;
7195         bool wback;
7196         ARM_ShifterType shift_t;
7197         uint32_t shift_n;
7198 
7199         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7200         switch (encoding)
7201         {
7202             case eEncodingT1:
7203                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7204                 t = Bits32 (opcode, 2, 0);
7205                 n = Bits32 (opcode, 5, 3);
7206                 m = Bits32 (opcode, 8, 6);
7207 
7208                 // index = TRUE; add = TRUE; wback = FALSE;
7209                 index = true;
7210                 add = true;
7211                 wback = false;
7212 
7213                 // (shift_t, shift_n) = (SRType_LSL, 0);
7214                 shift_t = SRType_LSL;
7215                 shift_n = 0;
7216 
7217                 break;
7218 
7219             case eEncodingT2:
7220                 // if Rt == '1111' then SEE PLI;
7221                 // if Rn == '1111' then SEE LDRSB (literal);
7222                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7223                 t = Bits32 (opcode, 15, 12);
7224                 n = Bits32 (opcode, 19, 16);
7225                 m = Bits32 (opcode, 3, 0);
7226 
7227                 // index = TRUE; add = TRUE; wback = FALSE;
7228                 index = true;
7229                 add = true;
7230                 wback = false;
7231 
7232                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7233                 shift_t = SRType_LSL;
7234                 shift_n = Bits32 (opcode, 5, 4);
7235 
7236                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7237                 if ((t == 13) || BadReg (m))
7238                     return false;
7239                 break;
7240 
7241             case eEncodingA1:
7242                 // if P == '0' && W == '1' then SEE LDRSBT;
7243                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7244                 t = Bits32 (opcode, 15, 12);
7245                 n = Bits32 (opcode, 19, 16);
7246                 m = Bits32 (opcode, 3, 0);
7247 
7248                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7249                 index = BitIsSet (opcode, 24);
7250                 add = BitIsSet (opcode, 23);
7251                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7252 
7253                 // (shift_t, shift_n) = (SRType_LSL, 0);
7254                 shift_t = SRType_LSL;
7255                 shift_n = 0;
7256 
7257                 // if t == 15 || m == 15 then UNPREDICTABLE;
7258                 if ((t == 15) || (m == 15))
7259                     return false;
7260 
7261                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7262                 if (wback && ((n == 15) || (n == t)))
7263                     return false;
7264                 break;
7265 
7266             default:
7267                 return false;
7268         }
7269 
7270         uint64_t Rm =  ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7271         if (!success)
7272             return false;
7273 
7274         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7275         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7276         if (!success)
7277             return false;
7278 
7279         addr_t offset_addr;
7280         addr_t address;
7281 
7282         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7283         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7284         if (!success)
7285             return false;
7286 
7287         if (add)
7288             offset_addr = Rn + offset;
7289         else
7290             offset_addr = Rn - offset;
7291 
7292         // address = if index then offset_addr else R[n];
7293         if (index)
7294             address = offset_addr;
7295         else
7296             address = Rn;
7297 
7298         // R[t] = SignExtend(MemU[address,1], 32);
7299         RegisterInfo base_reg;
7300         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7301         RegisterInfo offset_reg;
7302         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7303 
7304         EmulateInstruction::Context context;
7305         context.type = eContextRegisterLoad;
7306         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7307 
7308         uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7309         if (!success)
7310             return false;
7311 
7312         int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7313         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7314             return false;
7315 
7316         // if wback then R[n] = offset_addr;
7317         if (wback)
7318         {
7319             context.type = eContextAdjustBaseRegister;
7320             context.SetAddress (offset_addr);
7321             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7322                 return false;
7323         }
7324     }
7325     return true;
7326 }
7327 
7328 // LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from
7329 // memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed, or
7330 // pre-indexed addressing.
7331 bool
EmulateLDRSHImmediate(const uint32_t opcode,const ARMEncoding encoding)7332 EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding)
7333 {
7334 #if 0
7335     if ConditionPassed() then
7336         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7337         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7338         address = if index then offset_addr else R[n];
7339         data = MemU[address,2];
7340         if wback then R[n] = offset_addr;
7341         if UnalignedSupport() || address<0> = '0' then
7342             R[t] = SignExtend(data, 32);
7343         else // Can only apply before ARMv7
7344             R[t] = bits(32) UNKNOWN;
7345 #endif
7346 
7347     bool success = false;
7348 
7349     if (ConditionPassed(opcode))
7350     {
7351         uint32_t t;
7352         uint32_t n;
7353         uint32_t imm32;
7354         bool index;
7355         bool add;
7356         bool wback;
7357 
7358         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7359         switch (encoding)
7360         {
7361             case eEncodingT1:
7362                 // if Rn == '1111' then SEE LDRSH (literal);
7363                 // if Rt == '1111' then SEE "Unallocated memory hints";
7364                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7365                 t = Bits32 (opcode, 15, 12);
7366                 n = Bits32 (opcode, 19, 16);
7367                 imm32 = Bits32 (opcode, 11, 0);
7368 
7369                 // index = TRUE; add = TRUE; wback = FALSE;
7370                 index = true;
7371                 add = true;
7372                 wback = false;
7373 
7374                 // if t == 13 then UNPREDICTABLE;
7375                 if (t == 13)
7376                     return false;
7377 
7378                 break;
7379 
7380             case eEncodingT2:
7381                 // if Rn == '1111' then SEE LDRSH (literal);
7382                 // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
7383                 // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7384                 // if P == '0' && W == '0' then UNDEFINED;
7385                   if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7386                   return false;
7387 
7388                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7389                 t = Bits32 (opcode, 15, 12);
7390                 n = Bits32 (opcode, 19, 16);
7391                 imm32 = Bits32 (opcode, 7, 0);
7392 
7393                 // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7394                 index = BitIsSet (opcode, 10);
7395                 add = BitIsSet (opcode, 9);
7396                 wback = BitIsSet (opcode, 8);
7397 
7398                 // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7399                 if (BadReg (t) || (wback && (n == t)))
7400                     return false;
7401 
7402                 break;
7403 
7404             case eEncodingA1:
7405             {
7406                 // if Rn == '1111' then SEE LDRSH (literal);
7407                 // if P == '0' && W == '1' then SEE LDRSHT;
7408                 // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7409                 t = Bits32 (opcode, 15, 12);
7410                 n = Bits32 (opcode, 19, 16);
7411                 uint32_t imm4H = Bits32 (opcode, 11,8);
7412                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7413                 imm32 = (imm4H << 4) | imm4L;
7414 
7415                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7416                 index = BitIsSet (opcode, 24);
7417                 add = BitIsSet (opcode, 23);
7418                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7419 
7420                 // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7421                 if ((t == 15) || (wback && (n == t)))
7422                     return false;
7423 
7424                 break;
7425             }
7426 
7427             default:
7428                 return false;
7429         }
7430 
7431         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7432         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7433         if (!success)
7434             return false;
7435 
7436         addr_t offset_addr;
7437         if (add)
7438             offset_addr = Rn + imm32;
7439         else
7440             offset_addr = Rn - imm32;
7441 
7442         // address = if index then offset_addr else R[n];
7443         addr_t address;
7444         if (index)
7445             address = offset_addr;
7446         else
7447             address = Rn;
7448 
7449         // data = MemU[address,2];
7450         RegisterInfo base_reg;
7451         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7452 
7453         EmulateInstruction::Context context;
7454         context.type = eContextRegisterLoad;
7455         context.SetRegisterPlusOffset (base_reg, address - Rn);
7456 
7457         uint64_t data = MemURead (context, address, 2, 0, &success);
7458         if (!success)
7459             return false;
7460 
7461         // if wback then R[n] = offset_addr;
7462         if (wback)
7463         {
7464             context.type = eContextAdjustBaseRegister;
7465             context.SetAddress (offset_addr);
7466             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7467                 return false;
7468         }
7469 
7470         // if UnalignedSupport() || address<0> = '0' then
7471         if (UnalignedSupport() || BitIsClear (address, 0))
7472         {
7473             // R[t] = SignExtend(data, 32);
7474             int64_t signed_data = llvm::SignExtend64<16>(data);
7475             context.type = eContextRegisterLoad;
7476             context.SetRegisterPlusOffset (base_reg, address - Rn);
7477             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7478                 return false;
7479         }
7480         else // Can only apply before ARMv7
7481         {
7482             // R[t] = bits(32) UNKNOWN;
7483             WriteBits32Unknown (t);
7484         }
7485     }
7486     return true;
7487 }
7488 
7489 // LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory,
7490 // sign-extends it to from a 32-bit word, and writes it to a register.
7491 bool
EmulateLDRSHLiteral(const uint32_t opcode,const ARMEncoding encoding)7492 EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding)
7493 {
7494 #if 0
7495     if ConditionPassed() then
7496         EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7497         base = Align(PC,4);
7498         address = if add then (base + imm32) else (base - imm32);
7499         data = MemU[address,2];
7500         if UnalignedSupport() || address<0> = '0' then
7501             R[t] = SignExtend(data, 32);
7502         else // Can only apply before ARMv7
7503             R[t] = bits(32) UNKNOWN;
7504 #endif
7505 
7506     bool success = false;
7507 
7508     if (ConditionPassed(opcode))
7509     {
7510         uint32_t t;
7511         uint32_t imm32;
7512         bool add;
7513 
7514         // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7515         switch (encoding)
7516         {
7517             case eEncodingT1:
7518                 // if Rt == '1111' then SEE "Unallocated memory hints";
7519                 // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7520                 t = Bits32  (opcode, 15, 12);
7521                 imm32 = Bits32 (opcode, 11, 0);
7522                 add = BitIsSet (opcode, 23);
7523 
7524                 // if t == 13 then UNPREDICTABLE;
7525                 if (t == 13)
7526                     return false;
7527 
7528                 break;
7529 
7530             case eEncodingA1:
7531             {
7532                 // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7533                 t = Bits32 (opcode, 15, 12);
7534                 uint32_t imm4H = Bits32 (opcode, 11, 8);
7535                 uint32_t imm4L = Bits32 (opcode, 3, 0);
7536                 imm32 = (imm4H << 4) | imm4L;
7537                 add = BitIsSet (opcode, 23);
7538 
7539                 // if t == 15 then UNPREDICTABLE;
7540                 if (t == 15)
7541                     return false;
7542 
7543                 break;
7544             }
7545             default:
7546                 return false;
7547         }
7548 
7549         // base = Align(PC,4);
7550         uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7551         if (!success)
7552             return false;
7553 
7554         uint64_t base = AlignPC (pc_value);
7555 
7556         addr_t address;
7557         // address = if add then (base + imm32) else (base - imm32);
7558         if (add)
7559             address = base + imm32;
7560         else
7561             address = base - imm32;
7562 
7563         // data = MemU[address,2];
7564         RegisterInfo base_reg;
7565         GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7566 
7567         EmulateInstruction::Context context;
7568         context.type = eContextRegisterLoad;
7569         context.SetRegisterPlusOffset (base_reg, imm32);
7570 
7571         uint64_t data = MemURead (context, address, 2, 0, &success);
7572         if (!success)
7573             return false;
7574 
7575         // if UnalignedSupport() || address<0> = '0' then
7576         if (UnalignedSupport() || BitIsClear (address, 0))
7577         {
7578             // R[t] = SignExtend(data, 32);
7579             int64_t signed_data = llvm::SignExtend64<16>(data);
7580             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7581                 return false;
7582         }
7583         else // Can only apply before ARMv7
7584         {
7585             // R[t] = bits(32) UNKNOWN;
7586             WriteBits32Unknown (t);
7587         }
7588     }
7589     return true;
7590 }
7591 
7592 // LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword
7593 // from memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7594 // shifted left by 0, 1, 2, or 3 bits.
7595 bool
EmulateLDRSHRegister(const uint32_t opcode,const ARMEncoding encoding)7596 EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding)
7597 {
7598 #if 0
7599     if ConditionPassed() then
7600         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7601         offset = Shift(R[m], shift_t, shift_n, APSR.C);
7602         offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7603         address = if index then offset_addr else R[n];
7604         data = MemU[address,2];
7605         if wback then R[n] = offset_addr;
7606         if UnalignedSupport() || address<0> = '0' then
7607             R[t] = SignExtend(data, 32);
7608         else // Can only apply before ARMv7
7609             R[t] = bits(32) UNKNOWN;
7610 #endif
7611 
7612     bool success = false;
7613 
7614     if (ConditionPassed(opcode))
7615     {
7616         uint32_t t;
7617         uint32_t n;
7618         uint32_t m;
7619         bool index;
7620         bool add;
7621         bool wback;
7622         ARM_ShifterType shift_t;
7623         uint32_t shift_n;
7624 
7625         // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7626         switch (encoding)
7627         {
7628             case eEncodingT1:
7629                 // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
7630                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7631                 t = Bits32 (opcode, 2, 0);
7632                 n = Bits32 (opcode, 5, 3);
7633                 m = Bits32 (opcode, 8, 6);
7634 
7635                 // index = TRUE; add = TRUE; wback = FALSE;
7636                 index = true;
7637                 add = true;
7638                 wback = false;
7639 
7640                 // (shift_t, shift_n) = (SRType_LSL, 0);
7641                 shift_t = SRType_LSL;
7642                 shift_n = 0;
7643 
7644                 break;
7645 
7646             case eEncodingT2:
7647                 // if Rn == '1111' then SEE LDRSH (literal);
7648                 // if Rt == '1111' then SEE "Unallocated memory hints";
7649                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7650                 t = Bits32 (opcode, 15, 12);
7651                 n = Bits32 (opcode, 19, 16);
7652                 m = Bits32 (opcode, 3, 0);
7653 
7654                 // index = TRUE; add = TRUE; wback = FALSE;
7655                 index = true;
7656                 add = true;
7657                 wback = false;
7658 
7659                 // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7660                 shift_t = SRType_LSL;
7661                 shift_n = Bits32 (opcode, 5, 4);
7662 
7663                 // if t == 13 || BadReg(m) then UNPREDICTABLE;
7664                 if ((t == 13) || BadReg (m))
7665                     return false;
7666 
7667                 break;
7668 
7669             case eEncodingA1:
7670                 // if P == '0' && W == '1' then SEE LDRSHT;
7671                 // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7672                 t = Bits32 (opcode, 15, 12);
7673                 n = Bits32 (opcode, 19, 16);
7674                 m = Bits32 (opcode, 3, 0);
7675 
7676                 // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7677                 index = BitIsSet (opcode, 24);
7678                 add = BitIsSet (opcode, 23);
7679                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7680 
7681                 // (shift_t, shift_n) = (SRType_LSL, 0);
7682                 shift_t = SRType_LSL;
7683                 shift_n = 0;
7684 
7685                 // if t == 15 || m == 15 then UNPREDICTABLE;
7686                 if ((t == 15) || (m == 15))
7687                     return false;
7688 
7689                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7690                 if (wback && ((n == 15) || (n == t)))
7691                     return false;
7692 
7693                 break;
7694 
7695             default:
7696                 return false;
7697         }
7698 
7699         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7700         if (!success)
7701             return false;
7702 
7703         uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7704         if (!success)
7705             return false;
7706 
7707         // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7708         addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7709         if (!success)
7710             return false;
7711 
7712         addr_t offset_addr;
7713         addr_t address;
7714 
7715         // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7716         if (add)
7717             offset_addr = Rn + offset;
7718         else
7719             offset_addr = Rn - offset;
7720 
7721         // address = if index then offset_addr else R[n];
7722         if (index)
7723             address = offset_addr;
7724         else
7725             address = Rn;
7726 
7727         // data = MemU[address,2];
7728         RegisterInfo base_reg;
7729         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7730 
7731         RegisterInfo offset_reg;
7732         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7733 
7734         EmulateInstruction::Context context;
7735         context.type = eContextRegisterLoad;
7736         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7737 
7738         uint64_t data = MemURead (context, address, 2, 0, &success);
7739         if (!success)
7740             return false;
7741 
7742         // if wback then R[n] = offset_addr;
7743         if (wback)
7744         {
7745             context.type = eContextAdjustBaseRegister;
7746             context.SetAddress (offset_addr);
7747             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7748                 return false;
7749         }
7750 
7751         // if UnalignedSupport() || address<0> = '0' then
7752         if (UnalignedSupport() || BitIsClear (address, 0))
7753         {
7754             // R[t] = SignExtend(data, 32);
7755             context.type = eContextRegisterLoad;
7756             context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7757 
7758             int64_t signed_data = llvm::SignExtend64<16>(data);
7759             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7760                 return false;
7761         }
7762         else // Can only apply before ARMv7
7763         {
7764             // R[t] = bits(32) UNKNOWN;
7765             WriteBits32Unknown (t);
7766         }
7767     }
7768     return true;
7769 }
7770 
7771 // SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7772 // register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7773 bool
EmulateSXTB(const uint32_t opcode,const ARMEncoding encoding)7774 EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding)
7775 {
7776 #if 0
7777     if ConditionPassed() then
7778         EncodingSpecificOperations();
7779         rotated = ROR(R[m], rotation);
7780         R[d] = SignExtend(rotated<7:0>, 32);
7781 #endif
7782 
7783     bool success = false;
7784 
7785     if (ConditionPassed(opcode))
7786     {
7787         uint32_t d;
7788         uint32_t m;
7789         uint32_t rotation;
7790 
7791         // EncodingSpecificOperations();
7792         switch (encoding)
7793         {
7794             case eEncodingT1:
7795                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7796                 d = Bits32 (opcode, 2, 0);
7797                 m = Bits32 (opcode, 5, 3);
7798                 rotation = 0;
7799 
7800                 break;
7801 
7802             case eEncodingT2:
7803                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7804                 d = Bits32 (opcode, 11, 8);
7805                 m = Bits32 (opcode, 3, 0);
7806                 rotation = Bits32 (opcode, 5, 4) << 3;
7807 
7808                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7809                 if (BadReg (d) || BadReg (m))
7810                     return false;
7811 
7812                 break;
7813 
7814             case eEncodingA1:
7815                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7816                 d = Bits32 (opcode, 15, 12);
7817                 m = Bits32 (opcode, 3, 0);
7818                 rotation = Bits32 (opcode, 11, 10) << 3;
7819 
7820                 // if d == 15 || m == 15 then UNPREDICTABLE;
7821                 if ((d == 15) || (m == 15))
7822                     return false;
7823 
7824                 break;
7825 
7826             default:
7827                 return false;
7828         }
7829 
7830         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7831         if (!success)
7832             return false;
7833 
7834         // rotated = ROR(R[m], rotation);
7835         uint64_t rotated = ROR (Rm, rotation, &success);
7836         if (!success)
7837             return false;
7838 
7839         // R[d] = SignExtend(rotated<7:0>, 32);
7840         int64_t data = llvm::SignExtend64<8>(rotated);
7841 
7842         RegisterInfo source_reg;
7843         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7844 
7845         EmulateInstruction::Context context;
7846         context.type = eContextRegisterLoad;
7847         context.SetRegister (source_reg);
7848 
7849         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7850             return false;
7851     }
7852     return true;
7853 }
7854 
7855 // SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7856 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7857 bool
EmulateSXTH(const uint32_t opcode,const ARMEncoding encoding)7858 EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding)
7859 {
7860 #if 0
7861     if ConditionPassed() then
7862         EncodingSpecificOperations();
7863         rotated = ROR(R[m], rotation);
7864         R[d] = SignExtend(rotated<15:0>, 32);
7865 #endif
7866 
7867     bool success = false;
7868 
7869     if (ConditionPassed(opcode))
7870     {
7871         uint32_t d;
7872         uint32_t m;
7873         uint32_t rotation;
7874 
7875         // EncodingSpecificOperations();
7876         switch (encoding)
7877         {
7878             case eEncodingT1:
7879                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7880                 d = Bits32 (opcode, 2, 0);
7881                 m = Bits32 (opcode, 5, 3);
7882                 rotation = 0;
7883 
7884                 break;
7885 
7886             case eEncodingT2:
7887                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7888                 d = Bits32 (opcode, 11, 8);
7889                 m = Bits32 (opcode, 3, 0);
7890                 rotation = Bits32 (opcode, 5, 4) << 3;
7891 
7892                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7893                 if (BadReg (d) || BadReg (m))
7894                     return false;
7895 
7896                 break;
7897 
7898             case eEncodingA1:
7899                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7900                 d = Bits32 (opcode, 15, 12);
7901                 m = Bits32 (opcode, 3, 0);
7902                 rotation = Bits32 (opcode, 11, 10) << 3;
7903 
7904                 // if d == 15 || m == 15 then UNPREDICTABLE;
7905                 if ((d == 15) || (m == 15))
7906                     return false;
7907 
7908                 break;
7909 
7910             default:
7911                 return false;
7912         }
7913 
7914         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7915         if (!success)
7916             return false;
7917 
7918         // rotated = ROR(R[m], rotation);
7919         uint64_t rotated = ROR (Rm, rotation, &success);
7920         if (!success)
7921             return false;
7922 
7923         // R[d] = SignExtend(rotated<15:0>, 32);
7924         RegisterInfo source_reg;
7925         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7926 
7927         EmulateInstruction::Context context;
7928         context.type = eContextRegisterLoad;
7929         context.SetRegister (source_reg);
7930 
7931         int64_t data = llvm::SignExtend64<16> (rotated);
7932         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7933             return false;
7934     }
7935 
7936     return true;
7937 }
7938 
7939 // UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination
7940 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7941 bool
EmulateUXTB(const uint32_t opcode,const ARMEncoding encoding)7942 EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding)
7943 {
7944 #if 0
7945     if ConditionPassed() then
7946         EncodingSpecificOperations();
7947         rotated = ROR(R[m], rotation);
7948         R[d] = ZeroExtend(rotated<7:0>, 32);
7949 #endif
7950 
7951     bool success = false;
7952 
7953     if (ConditionPassed(opcode))
7954     {
7955         uint32_t d;
7956         uint32_t m;
7957         uint32_t rotation;
7958 
7959         // EncodingSpecificOperations();
7960         switch (encoding)
7961         {
7962             case eEncodingT1:
7963                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7964                 d = Bits32 (opcode, 2, 0);
7965                 m = Bits32 (opcode, 5, 3);
7966                 rotation = 0;
7967 
7968                 break;
7969 
7970             case eEncodingT2:
7971                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7972                 d = Bits32 (opcode, 11, 8);
7973                 m = Bits32 (opcode, 3, 0);
7974                   rotation = Bits32 (opcode, 5, 4) << 3;
7975 
7976                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7977                 if (BadReg (d) || BadReg (m))
7978                   return false;
7979 
7980                 break;
7981 
7982             case eEncodingA1:
7983                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7984                 d = Bits32 (opcode, 15, 12);
7985                 m = Bits32 (opcode, 3, 0);
7986                 rotation = Bits32 (opcode, 11, 10) << 3;
7987 
7988                 // if d == 15 || m == 15 then UNPREDICTABLE;
7989                 if ((d == 15) || (m == 15))
7990                     return false;
7991 
7992                 break;
7993 
7994             default:
7995                 return false;
7996         }
7997 
7998         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7999         if (!success)
8000             return false;
8001 
8002         // rotated = ROR(R[m], rotation);
8003         uint64_t rotated = ROR (Rm, rotation, &success);
8004         if (!success)
8005             return false;
8006 
8007         // R[d] = ZeroExtend(rotated<7:0>, 32);
8008         RegisterInfo source_reg;
8009         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8010 
8011         EmulateInstruction::Context context;
8012         context.type = eContextRegisterLoad;
8013         context.SetRegister (source_reg);
8014 
8015         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0)))
8016             return false;
8017     }
8018     return true;
8019 }
8020 
8021 // UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination
8022 // register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
8023 bool
EmulateUXTH(const uint32_t opcode,const ARMEncoding encoding)8024 EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding)
8025 {
8026 #if 0
8027     if ConditionPassed() then
8028         EncodingSpecificOperations();
8029         rotated = ROR(R[m], rotation);
8030         R[d] = ZeroExtend(rotated<15:0>, 32);
8031 #endif
8032 
8033     bool success = false;
8034 
8035     if (ConditionPassed(opcode))
8036     {
8037         uint32_t d;
8038         uint32_t m;
8039         uint32_t rotation;
8040 
8041         switch (encoding)
8042         {
8043             case eEncodingT1:
8044                 // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8045                 d = Bits32 (opcode, 2, 0);
8046                 m = Bits32 (opcode, 5, 3);
8047                 rotation = 0;
8048 
8049                 break;
8050 
8051             case eEncodingT2:
8052                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8053                 d = Bits32 (opcode, 11, 8);
8054                 m = Bits32 (opcode, 3, 0);
8055                 rotation = Bits32 (opcode, 5, 4) << 3;
8056 
8057                 // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8058                 if (BadReg (d) || BadReg (m))
8059                   return false;
8060 
8061                 break;
8062 
8063             case eEncodingA1:
8064                 // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8065                 d = Bits32 (opcode, 15, 12);
8066                 m = Bits32 (opcode, 3, 0);
8067                 rotation = Bits32 (opcode, 11, 10) << 3;
8068 
8069                 // if d == 15 || m == 15 then UNPREDICTABLE;
8070                 if ((d == 15) || (m == 15))
8071                     return false;
8072 
8073                 break;
8074 
8075             default:
8076                 return false;
8077         }
8078 
8079         uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8080         if (!success)
8081             return false;
8082 
8083         // rotated = ROR(R[m], rotation);
8084         uint64_t rotated = ROR (Rm, rotation, &success);
8085         if (!success)
8086             return false;
8087 
8088         // R[d] = ZeroExtend(rotated<15:0>, 32);
8089         RegisterInfo source_reg;
8090         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8091 
8092         EmulateInstruction::Context context;
8093         context.type = eContextRegisterLoad;
8094         context.SetRegister (source_reg);
8095 
8096         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0)))
8097             return false;
8098     }
8099     return true;
8100 }
8101 
8102 // RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following
8103 // word respectively.
8104 bool
EmulateRFE(const uint32_t opcode,const ARMEncoding encoding)8105 EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding)
8106 {
8107 #if 0
8108     if ConditionPassed() then
8109         EncodingSpecificOperations();
8110         if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8111             UNPREDICTABLE;
8112         else
8113             address = if increment then R[n] else R[n]-8;
8114             if wordhigher then address = address+4;
8115             CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8116             BranchWritePC(MemA[address,4]);
8117             if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8118 #endif
8119 
8120     bool success = false;
8121 
8122     if (ConditionPassed(opcode))
8123     {
8124         uint32_t n;
8125         bool wback;
8126         bool increment;
8127         bool wordhigher;
8128 
8129         // EncodingSpecificOperations();
8130         switch (encoding)
8131         {
8132             case eEncodingT1:
8133                 // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE;
8134                 n = Bits32 (opcode, 19, 16);
8135                 wback = BitIsSet (opcode, 21);
8136                 increment = false;
8137                 wordhigher = false;
8138 
8139                 // if n == 15 then UNPREDICTABLE;
8140                 if (n == 15)
8141                     return false;
8142 
8143                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8144                 if (InITBlock() && !LastInITBlock())
8145                     return false;
8146 
8147                 break;
8148 
8149             case eEncodingT2:
8150                 // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8151                 n = Bits32 (opcode, 19, 16);
8152                 wback = BitIsSet (opcode, 21);
8153                 increment = true;
8154                 wordhigher = false;
8155 
8156                 // if n == 15 then UNPREDICTABLE;
8157                 if (n == 15)
8158                     return false;
8159 
8160                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8161                 if (InITBlock() && !LastInITBlock())
8162                     return false;
8163 
8164                 break;
8165 
8166             case eEncodingA1:
8167                 // n = UInt(Rn);
8168                 n = Bits32 (opcode, 19, 16);
8169 
8170                 // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8171                 wback = BitIsSet (opcode, 21);
8172                 increment = BitIsSet (opcode, 23);
8173                 wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23));
8174 
8175                 // if n == 15 then UNPREDICTABLE;
8176                 if (n == 15)
8177                     return false;
8178 
8179                 break;
8180 
8181             default:
8182                 return false;
8183         }
8184 
8185         // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8186         if (!CurrentModeIsPrivileged ())
8187             // UNPREDICTABLE;
8188             return false;
8189         else
8190         {
8191             uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8192             if (!success)
8193                 return false;
8194 
8195             addr_t address;
8196             // address = if increment then R[n] else R[n]-8;
8197             if (increment)
8198                 address = Rn;
8199             else
8200                 address = Rn - 8;
8201 
8202             // if wordhigher then address = address+4;
8203             if (wordhigher)
8204                 address = address + 4;
8205 
8206             // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8207             RegisterInfo base_reg;
8208             GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8209 
8210             EmulateInstruction::Context context;
8211             context.type = eContextReturnFromException;
8212             context.SetRegisterPlusOffset (base_reg, address - Rn);
8213 
8214             uint64_t data = MemARead (context, address + 4, 4, 0, &success);
8215             if (!success)
8216                 return false;
8217 
8218             CPSRWriteByInstr (data, 15, true);
8219 
8220             // BranchWritePC(MemA[address,4]);
8221             uint64_t data2 = MemARead (context, address, 4, 0, &success);
8222             if (!success)
8223                 return false;
8224 
8225             BranchWritePC (context, data2);
8226 
8227             // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8228             if (wback)
8229             {
8230                 context.type = eContextAdjustBaseRegister;
8231                 if (increment)
8232                 {
8233                     context.SetOffset (8);
8234                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8))
8235                         return false;
8236                 }
8237                 else
8238                 {
8239                     context.SetOffset (-8);
8240                     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8))
8241                         return false;
8242                 }
8243             } // if wback
8244         }
8245     } // if ConditionPassed()
8246     return true;
8247 }
8248 
8249 // Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
8250 // and writes the result to the destination register.  It can optionally update the condition flags based on
8251 // the result.
8252 bool
EmulateEORImm(const uint32_t opcode,const ARMEncoding encoding)8253 EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding)
8254 {
8255 #if 0
8256     // ARM pseudo code...
8257     if ConditionPassed() then
8258         EncodingSpecificOperations();
8259         result = R[n] EOR imm32;
8260         if d == 15 then         // Can only occur for ARM encoding
8261             ALUWritePC(result); // setflags is always FALSE here
8262         else
8263             R[d] = result;
8264             if setflags then
8265                 APSR.N = result<31>;
8266                 APSR.Z = IsZeroBit(result);
8267                 APSR.C = carry;
8268                 // APSR.V unchanged
8269 #endif
8270 
8271     bool success = false;
8272 
8273     if (ConditionPassed(opcode))
8274     {
8275         uint32_t Rd, Rn;
8276         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8277         bool setflags;
8278         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8279         switch (encoding)
8280         {
8281         case eEncodingT1:
8282             Rd = Bits32(opcode, 11, 8);
8283             Rn = Bits32(opcode, 19, 16);
8284             setflags = BitIsSet(opcode, 20);
8285             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8286             // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8287             if (Rd == 15 && setflags)
8288                 return EmulateTEQImm (opcode, eEncodingT1);
8289             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8290                 return false;
8291             break;
8292         case eEncodingA1:
8293             Rd = Bits32(opcode, 15, 12);
8294             Rn = Bits32(opcode, 19, 16);
8295             setflags = BitIsSet(opcode, 20);
8296             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8297 
8298             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8299             if (Rd == 15 && setflags)
8300                 return EmulateSUBSPcLrEtc (opcode, encoding);
8301             break;
8302         default:
8303             return false;
8304         }
8305 
8306         // Read the first operand.
8307         uint32_t val1 = ReadCoreReg(Rn, &success);
8308         if (!success)
8309             return false;
8310 
8311         uint32_t result = val1 ^ imm32;
8312 
8313         EmulateInstruction::Context context;
8314         context.type = EmulateInstruction::eContextImmediate;
8315         context.SetNoArgs ();
8316 
8317         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8318             return false;
8319     }
8320     return true;
8321 }
8322 
8323 // Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an
8324 // optionally-shifted register value, and writes the result to the destination register.
8325 // It can optionally update the condition flags based on the result.
8326 bool
EmulateEORReg(const uint32_t opcode,const ARMEncoding encoding)8327 EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding)
8328 {
8329 #if 0
8330     // ARM pseudo code...
8331     if ConditionPassed() then
8332         EncodingSpecificOperations();
8333         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8334         result = R[n] EOR shifted;
8335         if d == 15 then         // Can only occur for ARM encoding
8336             ALUWritePC(result); // setflags is always FALSE here
8337         else
8338             R[d] = result;
8339             if setflags then
8340                 APSR.N = result<31>;
8341                 APSR.Z = IsZeroBit(result);
8342                 APSR.C = carry;
8343                 // APSR.V unchanged
8344 #endif
8345 
8346     bool success = false;
8347 
8348     if (ConditionPassed(opcode))
8349     {
8350         uint32_t Rd, Rn, Rm;
8351         ARM_ShifterType shift_t;
8352         uint32_t shift_n; // the shift applied to the value read from Rm
8353         bool setflags;
8354         uint32_t carry;
8355         switch (encoding)
8356         {
8357         case eEncodingT1:
8358             Rd = Rn = Bits32(opcode, 2, 0);
8359             Rm = Bits32(opcode, 5, 3);
8360             setflags = !InITBlock();
8361             shift_t = SRType_LSL;
8362             shift_n = 0;
8363             break;
8364         case eEncodingT2:
8365             Rd = Bits32(opcode, 11, 8);
8366             Rn = Bits32(opcode, 19, 16);
8367             Rm = Bits32(opcode, 3, 0);
8368             setflags = BitIsSet(opcode, 20);
8369             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8370             // if Rd == '1111' && S == '1' then SEE TEQ (register);
8371             if (Rd == 15 && setflags)
8372                 return EmulateTEQReg (opcode, eEncodingT1);
8373             if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8374                 return false;
8375             break;
8376         case eEncodingA1:
8377             Rd = Bits32(opcode, 15, 12);
8378             Rn = Bits32(opcode, 19, 16);
8379             Rm = Bits32(opcode, 3, 0);
8380             setflags = BitIsSet(opcode, 20);
8381             shift_n = DecodeImmShiftARM(opcode, shift_t);
8382 
8383             // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8384             if (Rd == 15 && setflags)
8385                 return EmulateSUBSPcLrEtc (opcode, encoding);
8386             break;
8387         default:
8388             return false;
8389         }
8390 
8391         // Read the first operand.
8392         uint32_t val1 = ReadCoreReg(Rn, &success);
8393         if (!success)
8394             return false;
8395 
8396         // Read the second operand.
8397         uint32_t val2 = ReadCoreReg(Rm, &success);
8398         if (!success)
8399             return false;
8400 
8401         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8402         if (!success)
8403             return false;
8404         uint32_t result = val1 ^ shifted;
8405 
8406         EmulateInstruction::Context context;
8407         context.type = EmulateInstruction::eContextImmediate;
8408         context.SetNoArgs ();
8409 
8410         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8411             return false;
8412     }
8413     return true;
8414 }
8415 
8416 // Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and
8417 // writes the result to the destination register.  It can optionally update the condition flags based
8418 // on the result.
8419 bool
EmulateORRImm(const uint32_t opcode,const ARMEncoding encoding)8420 EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding)
8421 {
8422 #if 0
8423     // ARM pseudo code...
8424     if ConditionPassed() then
8425         EncodingSpecificOperations();
8426         result = R[n] OR imm32;
8427         if d == 15 then         // Can only occur for ARM encoding
8428             ALUWritePC(result); // setflags is always FALSE here
8429         else
8430             R[d] = result;
8431             if setflags then
8432                 APSR.N = result<31>;
8433                 APSR.Z = IsZeroBit(result);
8434                 APSR.C = carry;
8435                 // APSR.V unchanged
8436 #endif
8437 
8438     bool success = false;
8439 
8440     if (ConditionPassed(opcode))
8441     {
8442         uint32_t Rd, Rn;
8443         uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8444         bool setflags;
8445         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8446         switch (encoding)
8447         {
8448         case eEncodingT1:
8449             Rd = Bits32(opcode, 11, 8);
8450             Rn = Bits32(opcode, 19, 16);
8451             setflags = BitIsSet(opcode, 20);
8452             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8453             // if Rn == '1111' then SEE MOV (immediate);
8454             if (Rn == 15)
8455                 return EmulateMOVRdImm (opcode, eEncodingT2);
8456             if (BadReg(Rd) || Rn == 13)
8457                 return false;
8458             break;
8459         case eEncodingA1:
8460             Rd = Bits32(opcode, 15, 12);
8461             Rn = Bits32(opcode, 19, 16);
8462             setflags = BitIsSet(opcode, 20);
8463             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8464 
8465             if (Rd == 15 && setflags)
8466                 return EmulateSUBSPcLrEtc (opcode, encoding);
8467             break;
8468         default:
8469             return false;
8470         }
8471 
8472         // Read the first operand.
8473         uint32_t val1 = ReadCoreReg(Rn, &success);
8474         if (!success)
8475             return false;
8476 
8477         uint32_t result = val1 | imm32;
8478 
8479         EmulateInstruction::Context context;
8480         context.type = EmulateInstruction::eContextImmediate;
8481         context.SetNoArgs ();
8482 
8483         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8484             return false;
8485     }
8486     return true;
8487 }
8488 
8489 // Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register
8490 // value, and writes the result to the destination register.  It can optionally update the condition flags based
8491 // on the result.
8492 bool
EmulateORRReg(const uint32_t opcode,const ARMEncoding encoding)8493 EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding)
8494 {
8495 #if 0
8496     // ARM pseudo code...
8497     if ConditionPassed() then
8498         EncodingSpecificOperations();
8499         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8500         result = R[n] OR shifted;
8501         if d == 15 then         // Can only occur for ARM encoding
8502             ALUWritePC(result); // setflags is always FALSE here
8503         else
8504             R[d] = result;
8505             if setflags then
8506                 APSR.N = result<31>;
8507                 APSR.Z = IsZeroBit(result);
8508                 APSR.C = carry;
8509                 // APSR.V unchanged
8510 #endif
8511 
8512     bool success = false;
8513 
8514     if (ConditionPassed(opcode))
8515     {
8516         uint32_t Rd, Rn, Rm;
8517         ARM_ShifterType shift_t;
8518         uint32_t shift_n; // the shift applied to the value read from Rm
8519         bool setflags;
8520         uint32_t carry;
8521         switch (encoding)
8522         {
8523         case eEncodingT1:
8524             Rd = Rn = Bits32(opcode, 2, 0);
8525             Rm = Bits32(opcode, 5, 3);
8526             setflags = !InITBlock();
8527             shift_t = SRType_LSL;
8528             shift_n = 0;
8529             break;
8530         case eEncodingT2:
8531             Rd = Bits32(opcode, 11, 8);
8532             Rn = Bits32(opcode, 19, 16);
8533             Rm = Bits32(opcode, 3, 0);
8534             setflags = BitIsSet(opcode, 20);
8535             shift_n = DecodeImmShiftThumb(opcode, shift_t);
8536             // if Rn == '1111' then SEE MOV (register);
8537             if (Rn == 15)
8538                 return EmulateMOVRdRm (opcode, eEncodingT3);
8539             if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
8540                 return false;
8541             break;
8542         case eEncodingA1:
8543             Rd = Bits32(opcode, 15, 12);
8544             Rn = Bits32(opcode, 19, 16);
8545             Rm = Bits32(opcode, 3, 0);
8546             setflags = BitIsSet(opcode, 20);
8547             shift_n = DecodeImmShiftARM(opcode, shift_t);
8548 
8549             if (Rd == 15 && setflags)
8550                 return EmulateSUBSPcLrEtc (opcode, encoding);
8551             break;
8552         default:
8553             return false;
8554         }
8555 
8556         // Read the first operand.
8557         uint32_t val1 = ReadCoreReg(Rn, &success);
8558         if (!success)
8559             return false;
8560 
8561         // Read the second operand.
8562         uint32_t val2 = ReadCoreReg(Rm, &success);
8563         if (!success)
8564             return false;
8565 
8566         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8567         if (!success)
8568             return false;
8569         uint32_t result = val1 | shifted;
8570 
8571         EmulateInstruction::Context context;
8572         context.type = EmulateInstruction::eContextImmediate;
8573         context.SetNoArgs ();
8574 
8575         if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8576             return false;
8577     }
8578     return true;
8579 }
8580 
8581 // Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to
8582 // the destination register. It can optionally update the condition flags based on the result.
8583 bool
EmulateRSBImm(const uint32_t opcode,const ARMEncoding encoding)8584 EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding)
8585 {
8586 #if 0
8587     // ARM pseudo code...
8588     if ConditionPassed() then
8589         EncodingSpecificOperations();
8590         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
8591         if d == 15 then         // Can only occur for ARM encoding
8592             ALUWritePC(result); // setflags is always FALSE here
8593         else
8594             R[d] = result;
8595             if setflags then
8596                 APSR.N = result<31>;
8597                 APSR.Z = IsZeroBit(result);
8598                 APSR.C = carry;
8599                 APSR.V = overflow;
8600 #endif
8601 
8602     bool success = false;
8603 
8604     uint32_t Rd; // the destination register
8605     uint32_t Rn; // the first operand
8606     bool setflags;
8607     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8608     switch (encoding) {
8609     case eEncodingT1:
8610         Rd = Bits32(opcode, 2, 0);
8611         Rn = Bits32(opcode, 5, 3);
8612         setflags = !InITBlock();
8613         imm32 = 0;
8614         break;
8615     case eEncodingT2:
8616         Rd = Bits32(opcode, 11, 8);
8617         Rn = Bits32(opcode, 19, 16);
8618         setflags = BitIsSet(opcode, 20);
8619         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8620         if (BadReg(Rd) || BadReg(Rn))
8621             return false;
8622         break;
8623     case eEncodingA1:
8624         Rd = Bits32(opcode, 15, 12);
8625         Rn = Bits32(opcode, 19, 16);
8626         setflags = BitIsSet(opcode, 20);
8627         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8628 
8629         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8630         if (Rd == 15 && setflags)
8631             return EmulateSUBSPcLrEtc (opcode, encoding);
8632         break;
8633     default:
8634         return false;
8635     }
8636     // Read the register value from the operand register Rn.
8637     uint32_t reg_val = ReadCoreReg(Rn, &success);
8638     if (!success)
8639         return false;
8640 
8641     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
8642 
8643     EmulateInstruction::Context context;
8644     context.type = EmulateInstruction::eContextImmediate;
8645     context.SetNoArgs ();
8646 
8647     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8648         return false;
8649 
8650     return true;
8651 }
8652 
8653 // Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the
8654 // result to the destination register. It can optionally update the condition flags based on the result.
8655 bool
EmulateRSBReg(const uint32_t opcode,const ARMEncoding encoding)8656 EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding)
8657 {
8658 #if 0
8659     // ARM pseudo code...
8660     if ConditionPassed() then
8661         EncodingSpecificOperations();
8662         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8663         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
8664         if d == 15 then         // Can only occur for ARM encoding
8665             ALUWritePC(result); // setflags is always FALSE here
8666         else
8667             R[d] = result;
8668             if setflags then
8669                 APSR.N = result<31>;
8670                 APSR.Z = IsZeroBit(result);
8671                 APSR.C = carry;
8672                 APSR.V = overflow;
8673 #endif
8674 
8675     bool success = false;
8676 
8677     uint32_t Rd; // the destination register
8678     uint32_t Rn; // the first operand
8679     uint32_t Rm; // the second operand
8680     bool setflags;
8681     ARM_ShifterType shift_t;
8682     uint32_t shift_n; // the shift applied to the value read from Rm
8683     switch (encoding) {
8684     case eEncodingT1:
8685         Rd = Bits32(opcode, 11, 8);
8686         Rn = Bits32(opcode, 19, 16);
8687         Rm = Bits32(opcode, 3, 0);
8688         setflags = BitIsSet(opcode, 20);
8689         shift_n = DecodeImmShiftThumb(opcode, shift_t);
8690         // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
8691         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8692             return false;
8693         break;
8694     case eEncodingA1:
8695         Rd = Bits32(opcode, 15, 12);
8696         Rn = Bits32(opcode, 19, 16);
8697         Rm = Bits32(opcode, 3, 0);
8698         setflags = BitIsSet(opcode, 20);
8699         shift_n = DecodeImmShiftARM(opcode, shift_t);
8700 
8701         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8702         if (Rd == 15 && setflags)
8703             return EmulateSUBSPcLrEtc (opcode, encoding);
8704         break;
8705     default:
8706         return false;
8707     }
8708     // Read the register value from register Rn.
8709     uint32_t val1 = ReadCoreReg(Rn, &success);
8710     if (!success)
8711         return false;
8712 
8713     // Read the register value from register Rm.
8714     uint32_t val2 = ReadCoreReg(Rm, &success);
8715     if (!success)
8716         return false;
8717 
8718     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8719     if (!success)
8720         return false;
8721     AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
8722 
8723     EmulateInstruction::Context context;
8724     context.type = EmulateInstruction::eContextImmediate;
8725     context.SetNoArgs();
8726     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8727         return false;
8728 
8729     return true;
8730 }
8731 
8732 // Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from
8733 // an immediate value, and writes the result to the destination register. It can optionally update the condition
8734 // flags based on the result.
8735 bool
EmulateRSCImm(const uint32_t opcode,const ARMEncoding encoding)8736 EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding)
8737 {
8738 #if 0
8739     // ARM pseudo code...
8740     if ConditionPassed() then
8741         EncodingSpecificOperations();
8742         (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
8743         if d == 15 then
8744             ALUWritePC(result); // setflags is always FALSE here
8745         else
8746             R[d] = result;
8747             if setflags then
8748                 APSR.N = result<31>;
8749                 APSR.Z = IsZeroBit(result);
8750                 APSR.C = carry;
8751                 APSR.V = overflow;
8752 #endif
8753 
8754     bool success = false;
8755 
8756     uint32_t Rd; // the destination register
8757     uint32_t Rn; // the first operand
8758     bool setflags;
8759     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8760     switch (encoding) {
8761     case eEncodingA1:
8762         Rd = Bits32(opcode, 15, 12);
8763         Rn = Bits32(opcode, 19, 16);
8764         setflags = BitIsSet(opcode, 20);
8765         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8766 
8767         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8768         if (Rd == 15 && setflags)
8769             return EmulateSUBSPcLrEtc  (opcode, encoding);
8770         break;
8771     default:
8772         return false;
8773     }
8774     // Read the register value from the operand register Rn.
8775     uint32_t reg_val = ReadCoreReg(Rn, &success);
8776     if (!success)
8777         return false;
8778 
8779     AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
8780 
8781     EmulateInstruction::Context context;
8782     context.type = EmulateInstruction::eContextImmediate;
8783     context.SetNoArgs ();
8784 
8785     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8786         return false;
8787 
8788     return true;
8789 }
8790 
8791 // Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an
8792 // optionally-shifted register value, and writes the result to the destination register. It can optionally update the
8793 // condition flags based on the result.
8794 bool
EmulateRSCReg(const uint32_t opcode,const ARMEncoding encoding)8795 EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding)
8796 {
8797 #if 0
8798     // ARM pseudo code...
8799     if ConditionPassed() then
8800         EncodingSpecificOperations();
8801         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8802         (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
8803         if d == 15 then
8804             ALUWritePC(result); // setflags is always FALSE here
8805         else
8806             R[d] = result;
8807             if setflags then
8808                 APSR.N = result<31>;
8809                 APSR.Z = IsZeroBit(result);
8810                 APSR.C = carry;
8811                 APSR.V = overflow;
8812 #endif
8813 
8814     bool success = false;
8815 
8816     uint32_t Rd; // the destination register
8817     uint32_t Rn; // the first operand
8818     uint32_t Rm; // the second operand
8819     bool setflags;
8820     ARM_ShifterType shift_t;
8821     uint32_t shift_n; // the shift applied to the value read from Rm
8822     switch (encoding) {
8823     case eEncodingA1:
8824         Rd = Bits32(opcode, 15, 12);
8825         Rn = Bits32(opcode, 19, 16);
8826         Rm = Bits32(opcode, 3, 0);
8827         setflags = BitIsSet(opcode, 20);
8828         shift_n = DecodeImmShiftARM(opcode, shift_t);
8829 
8830         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8831         if (Rd == 15 && setflags)
8832             return EmulateSUBSPcLrEtc (opcode, encoding);
8833         break;
8834     default:
8835         return false;
8836     }
8837     // Read the register value from register Rn.
8838     uint32_t val1 = ReadCoreReg(Rn, &success);
8839     if (!success)
8840         return false;
8841 
8842     // Read the register value from register Rm.
8843     uint32_t val2 = ReadCoreReg(Rm, &success);
8844     if (!success)
8845         return false;
8846 
8847     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8848     if (!success)
8849         return false;
8850     AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
8851 
8852     EmulateInstruction::Context context;
8853     context.type = EmulateInstruction::eContextImmediate;
8854     context.SetNoArgs();
8855     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8856         return false;
8857 
8858     return true;
8859 }
8860 
8861 // Subtract with Carry (immediate) subtracts an immediate value and the value of
8862 // NOT (Carry flag) from a register value, and writes the result to the destination register.
8863 // It can optionally update the condition flags based on the result.
8864 bool
EmulateSBCImm(const uint32_t opcode,const ARMEncoding encoding)8865 EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding)
8866 {
8867 #if 0
8868     // ARM pseudo code...
8869     if ConditionPassed() then
8870         EncodingSpecificOperations();
8871         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
8872         if d == 15 then         // Can only occur for ARM encoding
8873             ALUWritePC(result); // setflags is always FALSE here
8874         else
8875             R[d] = result;
8876             if setflags then
8877                 APSR.N = result<31>;
8878                 APSR.Z = IsZeroBit(result);
8879                 APSR.C = carry;
8880                 APSR.V = overflow;
8881 #endif
8882 
8883     bool success = false;
8884 
8885     uint32_t Rd; // the destination register
8886     uint32_t Rn; // the first operand
8887     bool setflags;
8888     uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8889     switch (encoding) {
8890     case eEncodingT1:
8891         Rd = Bits32(opcode, 11, 8);
8892         Rn = Bits32(opcode, 19, 16);
8893         setflags = BitIsSet(opcode, 20);
8894         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8895         if (BadReg(Rd) || BadReg(Rn))
8896             return false;
8897         break;
8898     case eEncodingA1:
8899         Rd = Bits32(opcode, 15, 12);
8900         Rn = Bits32(opcode, 19, 16);
8901         setflags = BitIsSet(opcode, 20);
8902         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8903 
8904         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8905         if (Rd == 15 && setflags)
8906             return EmulateSUBSPcLrEtc (opcode, encoding);
8907         break;
8908     default:
8909         return false;
8910     }
8911     // Read the register value from the operand register Rn.
8912     uint32_t reg_val = ReadCoreReg(Rn, &success);
8913     if (!success)
8914         return false;
8915 
8916     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
8917 
8918     EmulateInstruction::Context context;
8919     context.type = EmulateInstruction::eContextImmediate;
8920     context.SetNoArgs ();
8921 
8922     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8923         return false;
8924 
8925     return true;
8926 }
8927 
8928 // Subtract with Carry (register) subtracts an optionally-shifted register value and the value of
8929 // NOT (Carry flag) from a register value, and writes the result to the destination register.
8930 // It can optionally update the condition flags based on the result.
8931 bool
EmulateSBCReg(const uint32_t opcode,const ARMEncoding encoding)8932 EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding)
8933 {
8934 #if 0
8935     // ARM pseudo code...
8936     if ConditionPassed() then
8937         EncodingSpecificOperations();
8938         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8939         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
8940         if d == 15 then         // Can only occur for ARM encoding
8941             ALUWritePC(result); // setflags is always FALSE here
8942         else
8943             R[d] = result;
8944             if setflags then
8945                 APSR.N = result<31>;
8946                 APSR.Z = IsZeroBit(result);
8947                 APSR.C = carry;
8948                 APSR.V = overflow;
8949 #endif
8950 
8951     bool success = false;
8952 
8953     uint32_t Rd; // the destination register
8954     uint32_t Rn; // the first operand
8955     uint32_t Rm; // the second operand
8956     bool setflags;
8957     ARM_ShifterType shift_t;
8958     uint32_t shift_n; // the shift applied to the value read from Rm
8959     switch (encoding) {
8960     case eEncodingT1:
8961         Rd = Rn = Bits32(opcode, 2, 0);
8962         Rm = Bits32(opcode, 5, 3);
8963         setflags = !InITBlock();
8964         shift_t = SRType_LSL;
8965         shift_n = 0;
8966         break;
8967     case eEncodingT2:
8968         Rd = Bits32(opcode, 11, 8);
8969         Rn = Bits32(opcode, 19, 16);
8970         Rm = Bits32(opcode, 3, 0);
8971         setflags = BitIsSet(opcode, 20);
8972         shift_n = DecodeImmShiftThumb(opcode, shift_t);
8973         if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8974             return false;
8975         break;
8976     case eEncodingA1:
8977         Rd = Bits32(opcode, 15, 12);
8978         Rn = Bits32(opcode, 19, 16);
8979         Rm = Bits32(opcode, 3, 0);
8980         setflags = BitIsSet(opcode, 20);
8981         shift_n = DecodeImmShiftARM(opcode, shift_t);
8982 
8983         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8984         if (Rd == 15 && setflags)
8985             return EmulateSUBSPcLrEtc (opcode, encoding);
8986         break;
8987     default:
8988         return false;
8989     }
8990     // Read the register value from register Rn.
8991     uint32_t val1 = ReadCoreReg(Rn, &success);
8992     if (!success)
8993         return false;
8994 
8995     // Read the register value from register Rm.
8996     uint32_t val2 = ReadCoreReg(Rm, &success);
8997     if (!success)
8998         return false;
8999 
9000     uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
9001     if (!success)
9002         return false;
9003     AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
9004 
9005     EmulateInstruction::Context context;
9006     context.type = EmulateInstruction::eContextImmediate;
9007     context.SetNoArgs();
9008     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9009         return false;
9010 
9011     return true;
9012 }
9013 
9014 // This instruction subtracts an immediate value from a register value, and writes the result
9015 // to the destination register.  It can optionally update the condition flags based on the result.
9016 bool
EmulateSUBImmThumb(const uint32_t opcode,const ARMEncoding encoding)9017 EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding)
9018 {
9019 #if 0
9020     // ARM pseudo code...
9021     if ConditionPassed() then
9022         EncodingSpecificOperations();
9023         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9024         R[d] = result;
9025         if setflags then
9026             APSR.N = result<31>;
9027             APSR.Z = IsZeroBit(result);
9028             APSR.C = carry;
9029             APSR.V = overflow;
9030 #endif
9031 
9032     bool success = false;
9033 
9034     uint32_t Rd; // the destination register
9035     uint32_t Rn; // the first operand
9036     bool setflags;
9037     uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9038     switch (encoding) {
9039     case eEncodingT1:
9040         Rd = Bits32(opcode, 2, 0);
9041         Rn = Bits32(opcode, 5, 3);
9042         setflags = !InITBlock();
9043         imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9044         break;
9045     case eEncodingT2:
9046         Rd = Rn = Bits32(opcode, 10, 8);
9047         setflags = !InITBlock();
9048         imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9049         break;
9050     case eEncodingT3:
9051         Rd = Bits32(opcode, 11, 8);
9052         Rn = Bits32(opcode, 19, 16);
9053         setflags = BitIsSet(opcode, 20);
9054         imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9055 
9056         // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9057         if (Rd == 15 && setflags)
9058             return EmulateCMPImm (opcode, eEncodingT2);
9059 
9060         // if Rn == '1101' then SEE SUB (SP minus immediate);
9061         if (Rn == 13)
9062             return EmulateSUBSPImm (opcode, eEncodingT2);
9063 
9064         // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9065         if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9066             return false;
9067         break;
9068     case eEncodingT4:
9069         Rd = Bits32(opcode, 11, 8);
9070         Rn = Bits32(opcode, 19, 16);
9071         setflags = BitIsSet(opcode, 20);
9072         imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9073 
9074         // if Rn == '1111' then SEE ADR;
9075         if (Rn == 15)
9076             return EmulateADR (opcode, eEncodingT2);
9077 
9078         // if Rn == '1101' then SEE SUB (SP minus immediate);
9079         if (Rn == 13)
9080             return EmulateSUBSPImm (opcode, eEncodingT3);
9081 
9082         if (BadReg(Rd))
9083             return false;
9084         break;
9085     default:
9086         return false;
9087     }
9088     // Read the register value from the operand register Rn.
9089     uint32_t reg_val = ReadCoreReg(Rn, &success);
9090     if (!success)
9091         return false;
9092 
9093     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9094 
9095     EmulateInstruction::Context context;
9096     context.type = EmulateInstruction::eContextImmediate;
9097     context.SetNoArgs ();
9098 
9099     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9100         return false;
9101 
9102     return true;
9103 }
9104 
9105 // This instruction subtracts an immediate value from a register value, and writes the result
9106 // to the destination register.  It can optionally update the condition flags based on the result.
9107 bool
EmulateSUBImmARM(const uint32_t opcode,const ARMEncoding encoding)9108 EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9109 {
9110 #if 0
9111     // ARM pseudo code...
9112     if ConditionPassed() then
9113         EncodingSpecificOperations();
9114         (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9115         if d == 15 then
9116             ALUWritePC(result); // setflags is always FALSE here
9117         else
9118             R[d] = result;
9119             if setflags then
9120                 APSR.N = result<31>;
9121                 APSR.Z = IsZeroBit(result);
9122                 APSR.C = carry;
9123                 APSR.V = overflow;
9124 #endif
9125 
9126     bool success = false;
9127 
9128     uint32_t Rd; // the destination register
9129     uint32_t Rn; // the first operand
9130     bool setflags;
9131     uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9132     switch (encoding) {
9133     case eEncodingA1:
9134         Rd = Bits32(opcode, 15, 12);
9135         Rn = Bits32(opcode, 19, 16);
9136         setflags = BitIsSet(opcode, 20);
9137         imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9138 
9139         // if Rn == '1111' && S == '0' then SEE ADR;
9140         if (Rn == 15 && !setflags)
9141             return EmulateADR (opcode, eEncodingA2);
9142 
9143         // if Rn == '1101' then SEE SUB (SP minus immediate);
9144         if (Rn == 13)
9145             return EmulateSUBSPImm (opcode, eEncodingA1);
9146 
9147         // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9148         if (Rd == 15 && setflags)
9149             return EmulateSUBSPcLrEtc (opcode, encoding);
9150         break;
9151     default:
9152         return false;
9153     }
9154     // Read the register value from the operand register Rn.
9155     uint32_t reg_val = ReadCoreReg(Rn, &success);
9156     if (!success)
9157         return false;
9158 
9159     AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9160 
9161     EmulateInstruction::Context context;
9162     context.type = EmulateInstruction::eContextImmediate;
9163     context.SetNoArgs ();
9164 
9165     if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9166         return false;
9167 
9168     return true;
9169 }
9170 
9171 // Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an
9172 // immediate value.  It updates the condition flags based on the result, and discards the result.
9173 bool
EmulateTEQImm(const uint32_t opcode,const ARMEncoding encoding)9174 EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding)
9175 {
9176 #if 0
9177     // ARM pseudo code...
9178     if ConditionPassed() then
9179         EncodingSpecificOperations();
9180         result = R[n] EOR imm32;
9181         APSR.N = result<31>;
9182         APSR.Z = IsZeroBit(result);
9183         APSR.C = carry;
9184         // APSR.V unchanged
9185 #endif
9186 
9187     bool success = false;
9188 
9189     if (ConditionPassed(opcode))
9190     {
9191         uint32_t Rn;
9192         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9193         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9194         switch (encoding)
9195         {
9196         case eEncodingT1:
9197             Rn = Bits32(opcode, 19, 16);
9198             imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9199             if (BadReg(Rn))
9200                 return false;
9201             break;
9202         case eEncodingA1:
9203             Rn = Bits32(opcode, 19, 16);
9204             imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9205             break;
9206         default:
9207             return false;
9208         }
9209 
9210         // Read the first operand.
9211         uint32_t val1 = ReadCoreReg(Rn, &success);
9212         if (!success)
9213             return false;
9214 
9215         uint32_t result = val1 ^ imm32;
9216 
9217         EmulateInstruction::Context context;
9218         context.type = EmulateInstruction::eContextImmediate;
9219         context.SetNoArgs ();
9220 
9221         if (!WriteFlags(context, result, carry))
9222             return false;
9223     }
9224     return true;
9225 }
9226 
9227 // Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an
9228 // optionally-shifted register value.  It updates the condition flags based on the result, and discards
9229 // the result.
9230 bool
EmulateTEQReg(const uint32_t opcode,const ARMEncoding encoding)9231 EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding)
9232 {
9233 #if 0
9234     // ARM pseudo code...
9235     if ConditionPassed() then
9236         EncodingSpecificOperations();
9237         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9238         result = R[n] EOR shifted;
9239         APSR.N = result<31>;
9240         APSR.Z = IsZeroBit(result);
9241         APSR.C = carry;
9242         // APSR.V unchanged
9243 #endif
9244 
9245     bool success = false;
9246 
9247     if (ConditionPassed(opcode))
9248     {
9249         uint32_t Rn, Rm;
9250         ARM_ShifterType shift_t;
9251         uint32_t shift_n; // the shift applied to the value read from Rm
9252         uint32_t carry;
9253         switch (encoding)
9254         {
9255         case eEncodingT1:
9256             Rn = Bits32(opcode, 19, 16);
9257             Rm = Bits32(opcode, 3, 0);
9258             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9259             if (BadReg(Rn) || BadReg(Rm))
9260                 return false;
9261             break;
9262         case eEncodingA1:
9263             Rn = Bits32(opcode, 19, 16);
9264             Rm = Bits32(opcode, 3, 0);
9265             shift_n = DecodeImmShiftARM(opcode, shift_t);
9266             break;
9267         default:
9268             return false;
9269         }
9270 
9271         // Read the first operand.
9272         uint32_t val1 = ReadCoreReg(Rn, &success);
9273         if (!success)
9274             return false;
9275 
9276         // Read the second operand.
9277         uint32_t val2 = ReadCoreReg(Rm, &success);
9278         if (!success)
9279             return false;
9280 
9281         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9282         if (!success)
9283             return false;
9284         uint32_t result = val1 ^ shifted;
9285 
9286         EmulateInstruction::Context context;
9287         context.type = EmulateInstruction::eContextImmediate;
9288         context.SetNoArgs ();
9289 
9290         if (!WriteFlags(context, result, carry))
9291             return false;
9292     }
9293     return true;
9294 }
9295 
9296 // Test (immediate) performs a bitwise AND operation on a register value and an immediate value.
9297 // It updates the condition flags based on the result, and discards the result.
9298 bool
EmulateTSTImm(const uint32_t opcode,const ARMEncoding encoding)9299 EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding)
9300 {
9301 #if 0
9302     // ARM pseudo code...
9303     if ConditionPassed() then
9304         EncodingSpecificOperations();
9305         result = R[n] AND imm32;
9306         APSR.N = result<31>;
9307         APSR.Z = IsZeroBit(result);
9308         APSR.C = carry;
9309         // APSR.V unchanged
9310 #endif
9311 
9312     bool success = false;
9313 
9314     if (ConditionPassed(opcode))
9315     {
9316         uint32_t Rn;
9317         uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9318         uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9319         switch (encoding)
9320         {
9321         case eEncodingT1:
9322             Rn = Bits32(opcode, 19, 16);
9323             imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9324             if (BadReg(Rn))
9325                 return false;
9326             break;
9327         case eEncodingA1:
9328             Rn = Bits32(opcode, 19, 16);
9329             imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9330             break;
9331         default:
9332             return false;
9333         }
9334 
9335         // Read the first operand.
9336         uint32_t val1 = ReadCoreReg(Rn, &success);
9337         if (!success)
9338             return false;
9339 
9340         uint32_t result = val1 & imm32;
9341 
9342         EmulateInstruction::Context context;
9343         context.type = EmulateInstruction::eContextImmediate;
9344         context.SetNoArgs ();
9345 
9346         if (!WriteFlags(context, result, carry))
9347             return false;
9348     }
9349     return true;
9350 }
9351 
9352 // Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value.
9353 // It updates the condition flags based on the result, and discards the result.
9354 bool
EmulateTSTReg(const uint32_t opcode,const ARMEncoding encoding)9355 EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding)
9356 {
9357 #if 0
9358     // ARM pseudo code...
9359     if ConditionPassed() then
9360         EncodingSpecificOperations();
9361         (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9362         result = R[n] AND shifted;
9363         APSR.N = result<31>;
9364         APSR.Z = IsZeroBit(result);
9365         APSR.C = carry;
9366         // APSR.V unchanged
9367 #endif
9368 
9369     bool success = false;
9370 
9371     if (ConditionPassed(opcode))
9372     {
9373         uint32_t Rn, Rm;
9374         ARM_ShifterType shift_t;
9375         uint32_t shift_n; // the shift applied to the value read from Rm
9376         uint32_t carry;
9377         switch (encoding)
9378         {
9379         case eEncodingT1:
9380             Rn = Bits32(opcode, 2, 0);
9381             Rm = Bits32(opcode, 5, 3);
9382             shift_t = SRType_LSL;
9383             shift_n = 0;
9384             break;
9385         case eEncodingT2:
9386             Rn = Bits32(opcode, 19, 16);
9387             Rm = Bits32(opcode, 3, 0);
9388             shift_n = DecodeImmShiftThumb(opcode, shift_t);
9389             if (BadReg(Rn) || BadReg(Rm))
9390                 return false;
9391             break;
9392         case eEncodingA1:
9393             Rn = Bits32(opcode, 19, 16);
9394             Rm = Bits32(opcode, 3, 0);
9395             shift_n = DecodeImmShiftARM(opcode, shift_t);
9396             break;
9397         default:
9398             return false;
9399         }
9400 
9401         // Read the first operand.
9402         uint32_t val1 = ReadCoreReg(Rn, &success);
9403         if (!success)
9404             return false;
9405 
9406         // Read the second operand.
9407         uint32_t val2 = ReadCoreReg(Rm, &success);
9408         if (!success)
9409             return false;
9410 
9411         uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9412         if (!success)
9413             return false;
9414         uint32_t result = val1 & shifted;
9415 
9416         EmulateInstruction::Context context;
9417         context.type = EmulateInstruction::eContextImmediate;
9418         context.SetNoArgs ();
9419 
9420         if (!WriteFlags(context, result, carry))
9421             return false;
9422     }
9423     return true;
9424 }
9425 
9426 // A8.6.216 SUB (SP minus register)
9427 bool
EmulateSUBSPReg(const uint32_t opcode,const ARMEncoding encoding)9428 EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding)
9429 {
9430 #if 0
9431     if ConditionPassed() then
9432         EncodingSpecificOperations();
9433         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9434         (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9435         if d == 15 then // Can only occur for ARM encoding
9436             ALUWritePC(result); // setflags is always FALSE here
9437         else
9438             R[d] = result;
9439             if setflags then
9440                 APSR.N = result<31>;
9441                 APSR.Z = IsZeroBit(result);
9442                 APSR.C = carry;
9443                 APSR.V = overflow;
9444 #endif
9445 
9446     bool success = false;
9447 
9448     if (ConditionPassed(opcode))
9449     {
9450         uint32_t d;
9451         uint32_t m;
9452         bool setflags;
9453         ARM_ShifterType shift_t;
9454         uint32_t shift_n;
9455 
9456         switch (encoding)
9457         {
9458             case eEncodingT1:
9459                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9460                 d = Bits32 (opcode, 11, 8);
9461                 m = Bits32 (opcode, 3, 0);
9462                 setflags = BitIsSet (opcode, 20);
9463 
9464                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9465                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9466 
9467                 // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE;
9468                 if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
9469                     return false;
9470 
9471                 // if d == 15 || BadReg(m) then UNPREDICTABLE;
9472                 if ((d == 15) || BadReg (m))
9473                     return false;
9474                 break;
9475 
9476             case eEncodingA1:
9477                 // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9478                 d = Bits32 (opcode, 15, 12);
9479                 m = Bits32 (opcode, 3, 0);
9480                 setflags = BitIsSet (opcode, 20);
9481 
9482                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9483                 if (d == 15 && setflags)
9484                     EmulateSUBSPcLrEtc (opcode, encoding);
9485 
9486                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9487                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9488                 break;
9489 
9490             default:
9491                 return false;
9492         }
9493 
9494         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9495         uint32_t Rm = ReadCoreReg (m, &success);
9496         if (!success)
9497             return false;
9498 
9499         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9500         if (!success)
9501             return false;
9502 
9503         // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9504         uint32_t sp_val = ReadCoreReg (SP_REG, &success);
9505         if (!success)
9506             return false;
9507 
9508         AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1);
9509 
9510         EmulateInstruction::Context context;
9511         context.type = eContextArithmetic;
9512         RegisterInfo sp_reg;
9513         GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
9514         RegisterInfo dwarf_reg;
9515         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
9516         context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
9517 
9518         if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9519             return false;
9520     }
9521     return true;
9522 }
9523 
9524 
9525 // A8.6.7 ADD (register-shifted register)
9526 bool
EmulateADDRegShift(const uint32_t opcode,const ARMEncoding encoding)9527 EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding)
9528 {
9529 #if 0
9530     if ConditionPassed() then
9531         EncodingSpecificOperations();
9532         shift_n = UInt(R[s]<7:0>);
9533         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9534         (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9535         R[d] = result;
9536         if setflags then
9537             APSR.N = result<31>;
9538             APSR.Z = IsZeroBit(result);
9539             APSR.C = carry;
9540             APSR.V = overflow;
9541 #endif
9542 
9543     bool success = false;
9544 
9545     if (ConditionPassed(opcode))
9546     {
9547         uint32_t d;
9548         uint32_t n;
9549         uint32_t m;
9550         uint32_t s;
9551         bool setflags;
9552         ARM_ShifterType shift_t;
9553 
9554         switch (encoding)
9555         {
9556             case eEncodingA1:
9557                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
9558                 d = Bits32 (opcode, 15, 12);
9559                 n = Bits32 (opcode, 19, 16);
9560                 m = Bits32 (opcode, 3, 0);
9561                 s = Bits32 (opcode, 11, 8);
9562 
9563                 // setflags = (S == �1�); shift_t = DecodeRegShift(type);
9564                 setflags = BitIsSet (opcode, 20);
9565                 shift_t = DecodeRegShift (Bits32 (opcode, 6, 5));
9566 
9567                 // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
9568                 if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
9569                     return false;
9570                 break;
9571 
9572             default:
9573                 return false;
9574         }
9575 
9576         // shift_n = UInt(R[s]<7:0>);
9577         uint32_t Rs = ReadCoreReg (s, &success);
9578         if (!success)
9579             return false;
9580 
9581         uint32_t shift_n = Bits32 (Rs, 7, 0);
9582 
9583         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9584         uint32_t Rm = ReadCoreReg (m, &success);
9585         if (!success)
9586             return false;
9587 
9588         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9589         if (!success)
9590             return false;
9591 
9592         // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9593         uint32_t Rn = ReadCoreReg (n, &success);
9594         if (!success)
9595             return false;
9596 
9597         AddWithCarryResult res = AddWithCarry (Rn, shifted, 0);
9598 
9599         // R[d] = result;
9600         EmulateInstruction::Context context;
9601         context.type = eContextArithmetic;
9602         RegisterInfo reg_n;
9603         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9604         RegisterInfo reg_m;
9605         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9606 
9607         context.SetRegisterRegisterOperands (reg_n, reg_m);
9608 
9609         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result))
9610             return false;
9611 
9612         // if setflags then
9613             // APSR.N = result<31>;
9614             // APSR.Z = IsZeroBit(result);
9615             // APSR.C = carry;
9616             // APSR.V = overflow;
9617         if (setflags)
9618             return WriteFlags (context, res.result, res.carry_out, res.overflow);
9619     }
9620     return true;
9621 }
9622 
9623 // A8.6.213 SUB (register)
9624 bool
EmulateSUBReg(const uint32_t opcode,const ARMEncoding encoding)9625 EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding)
9626 {
9627 #if 0
9628     if ConditionPassed() then
9629         EncodingSpecificOperations();
9630         shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9631         (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9632         if d == 15 then // Can only occur for ARM encoding
9633             ALUWritePC(result); // setflags is always FALSE here
9634         else
9635             R[d] = result;
9636             if setflags then
9637                 APSR.N = result<31>;
9638                 APSR.Z = IsZeroBit(result);
9639                 APSR.C = carry;
9640                 APSR.V = overflow;
9641 #endif
9642 
9643     bool success = false;
9644 
9645     if (ConditionPassed(opcode))
9646     {
9647         uint32_t d;
9648         uint32_t n;
9649         uint32_t m;
9650         bool setflags;
9651         ARM_ShifterType shift_t;
9652         uint32_t shift_n;
9653 
9654         switch (encoding)
9655         {
9656             case eEncodingT1:
9657                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
9658                 d = Bits32 (opcode, 2, 0);
9659                 n = Bits32 (opcode, 5, 3);
9660                 m = Bits32 (opcode, 8, 6);
9661                 setflags = !InITBlock();
9662 
9663                 // (shift_t, shift_n) = (SRType_LSL, 0);
9664                 shift_t = SRType_LSL;
9665                 shift_n = 0;
9666 
9667                 break;
9668 
9669             case eEncodingT2:
9670                 // if Rd == �1111� && S == �1� then SEE CMP (register);
9671                 // if Rn == �1101� then SEE SUB (SP minus register);
9672                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9673                 d = Bits32 (opcode, 11, 8);
9674                 n = Bits32 (opcode, 19, 16);
9675                 m = Bits32 (opcode, 3, 0);
9676                 setflags = BitIsSet (opcode, 20);
9677 
9678                 // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9679                 shift_n = DecodeImmShiftThumb (opcode, shift_t);
9680 
9681                 // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE;
9682                 if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m))
9683                     return false;
9684 
9685                 break;
9686 
9687             case eEncodingA1:
9688                 // if Rn == �1101� then SEE SUB (SP minus register);
9689                 // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9690                 d = Bits32 (opcode, 15, 12);
9691                 n = Bits32 (opcode, 19, 16);
9692                 m = Bits32 (opcode, 3, 0);
9693                 setflags = BitIsSet (opcode, 20);
9694 
9695                 // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9696                 if ((d == 15) && setflags)
9697                     EmulateSUBSPcLrEtc (opcode, encoding);
9698 
9699                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9700                 shift_n = DecodeImmShiftARM (opcode, shift_t);
9701 
9702                 break;
9703 
9704             default:
9705                 return false;
9706         }
9707 
9708         // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9709         uint32_t Rm = ReadCoreReg (m, &success);
9710         if (!success)
9711             return false;
9712 
9713         uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9714         if (!success)
9715             return false;
9716 
9717         // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9718         uint32_t Rn = ReadCoreReg (n, &success);
9719         if (!success)
9720             return false;
9721 
9722         AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1);
9723 
9724         // if d == 15 then // Can only occur for ARM encoding
9725             // ALUWritePC(result); // setflags is always FALSE here
9726         // else
9727             // R[d] = result;
9728             // if setflags then
9729                 // APSR.N = result<31>;
9730                 // APSR.Z = IsZeroBit(result);
9731                 // APSR.C = carry;
9732                 // APSR.V = overflow;
9733 
9734         EmulateInstruction::Context context;
9735         context.type = eContextArithmetic;
9736         RegisterInfo reg_n;
9737         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9738         RegisterInfo reg_m;
9739         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9740         context.SetRegisterRegisterOperands (reg_n, reg_m);
9741 
9742         if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9743             return false;
9744     }
9745     return true;
9746 }
9747 
9748 // A8.6.202 STREX
9749 // Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a
9750 // word from a register to memory if the executing processor has exclusive access to the memory addressed.
9751 bool
EmulateSTREX(const uint32_t opcode,const ARMEncoding encoding)9752 EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding)
9753 {
9754 #if 0
9755     if ConditionPassed() then
9756         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9757         address = R[n] + imm32;
9758         if ExclusiveMonitorsPass(address,4) then
9759             MemA[address,4] = R[t];
9760             R[d] = 0;
9761         else
9762             R[d] = 1;
9763 #endif
9764 
9765     bool success = false;
9766 
9767     if (ConditionPassed(opcode))
9768     {
9769         uint32_t d;
9770         uint32_t t;
9771         uint32_t n;
9772         uint32_t imm32;
9773         const uint32_t addr_byte_size = GetAddressByteSize();
9774 
9775         switch (encoding)
9776         {
9777             case eEncodingT1:
9778                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
9779                 d = Bits32 (opcode, 11, 8);
9780                 t = Bits32 (opcode, 15, 12);
9781                 n = Bits32 (opcode, 19, 16);
9782                 imm32 = Bits32 (opcode, 7, 0) << 2;
9783 
9784                 // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
9785                 if (BadReg (d) || BadReg (t) || (n == 15))
9786                   return false;
9787 
9788                 // if d == n || d == t then UNPREDICTABLE;
9789                 if ((d == n) || (d == t))
9790                   return false;
9791 
9792                 break;
9793 
9794             case eEncodingA1:
9795                 // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset
9796                 d = Bits32 (opcode, 15, 12);
9797                 t = Bits32 (opcode, 3, 0);
9798                 n = Bits32 (opcode, 19, 16);
9799                 imm32 = 0;
9800 
9801                 // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
9802                 if ((d == 15) || (t == 15) || (n == 15))
9803                     return false;
9804 
9805                 // if d == n || d == t then UNPREDICTABLE;
9806                 if ((d == n) || (d == t))
9807                     return false;
9808 
9809                 break;
9810 
9811             default:
9812                 return false;
9813         }
9814 
9815         // address = R[n] + imm32;
9816         uint32_t Rn = ReadCoreReg (n, &success);
9817         if (!success)
9818             return false;
9819 
9820         addr_t address = Rn + imm32;
9821 
9822         RegisterInfo base_reg;
9823         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9824         RegisterInfo data_reg;
9825         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9826         EmulateInstruction::Context context;
9827         context.type = eContextRegisterStore;
9828         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32);
9829 
9830         // if ExclusiveMonitorsPass(address,4) then
9831         // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this
9832         //                                                         always return true.
9833         if (true)
9834         {
9835             // MemA[address,4] = R[t];
9836             uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
9837             if (!success)
9838                 return false;
9839 
9840             if (!MemAWrite (context, address, Rt, addr_byte_size))
9841                 return false;
9842 
9843             // R[d] = 0;
9844             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0))
9845                 return false;
9846         }
9847         else
9848         {
9849             // R[d] = 1;
9850             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
9851                 return false;
9852         }
9853     }
9854     return true;
9855 }
9856 
9857 // A8.6.197 STRB (immediate, ARM)
9858 bool
EmulateSTRBImmARM(const uint32_t opcode,const ARMEncoding encoding)9859 EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9860 {
9861 #if 0
9862     if ConditionPassed() then
9863         EncodingSpecificOperations();
9864         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9865         address = if index then offset_addr else R[n];
9866         MemU[address,1] = R[t]<7:0>;
9867         if wback then R[n] = offset_addr;
9868 #endif
9869 
9870     bool success = false;
9871 
9872     if (ConditionPassed(opcode))
9873     {
9874         uint32_t t;
9875         uint32_t n;
9876         uint32_t imm32;
9877         bool index;
9878         bool add;
9879         bool wback;
9880 
9881         switch (encoding)
9882         {
9883             case eEncodingA1:
9884                 // if P == �0� && W == �1� then SEE STRBT;
9885                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9886                 t = Bits32 (opcode, 15, 12);
9887                 n = Bits32 (opcode, 19, 16);
9888                 imm32 = Bits32 (opcode, 11, 0);
9889 
9890                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9891                 index = BitIsSet (opcode, 24);
9892                 add = BitIsSet (opcode, 23);
9893                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9894 
9895                 // if t == 15 then UNPREDICTABLE;
9896                 if (t == 15)
9897                     return false;
9898 
9899                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9900                 if (wback && ((n == 15) || (n == t)))
9901                     return false;
9902 
9903                 break;
9904 
9905             default:
9906                 return false;
9907         }
9908 
9909         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9910         uint32_t Rn = ReadCoreReg (n, &success);
9911         if (!success)
9912             return false;
9913 
9914         addr_t offset_addr;
9915         if (add)
9916             offset_addr = Rn + imm32;
9917         else
9918             offset_addr = Rn - imm32;
9919 
9920         // address = if index then offset_addr else R[n];
9921         addr_t address;
9922         if (index)
9923             address = offset_addr;
9924         else
9925             address = Rn;
9926 
9927         // MemU[address,1] = R[t]<7:0>;
9928         uint32_t Rt = ReadCoreReg (t, &success);
9929         if (!success)
9930             return false;
9931 
9932         RegisterInfo base_reg;
9933         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9934         RegisterInfo data_reg;
9935         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9936         EmulateInstruction::Context context;
9937         context.type = eContextRegisterStore;
9938         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
9939 
9940         if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1))
9941             return false;
9942 
9943         // if wback then R[n] = offset_addr;
9944         if (wback)
9945         {
9946             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
9947                 return false;
9948         }
9949     }
9950     return true;
9951 }
9952 
9953 // A8.6.194 STR (immediate, ARM)
9954 bool
EmulateSTRImmARM(const uint32_t opcode,const ARMEncoding encoding)9955 EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding)
9956 {
9957 #if 0
9958     if ConditionPassed() then
9959         EncodingSpecificOperations();
9960         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9961         address = if index then offset_addr else R[n];
9962         MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
9963         if wback then R[n] = offset_addr;
9964 #endif
9965 
9966     bool success = false;
9967 
9968     if (ConditionPassed(opcode))
9969     {
9970         uint32_t t;
9971         uint32_t n;
9972         uint32_t imm32;
9973         bool index;
9974         bool add;
9975         bool wback;
9976 
9977         const uint32_t addr_byte_size = GetAddressByteSize();
9978 
9979         switch (encoding)
9980         {
9981             case eEncodingA1:
9982                 // if P == �0� && W == �1� then SEE STRT;
9983                 // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH;
9984                 // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9985                 t = Bits32 (opcode, 15, 12);
9986                 n = Bits32 (opcode, 19, 16);
9987                 imm32 = Bits32 (opcode, 11, 0);
9988 
9989                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9990                 index = BitIsSet (opcode, 24);
9991                 add = BitIsSet (opcode, 23);
9992                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9993 
9994                 // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9995                 if (wback && ((n == 15) || (n == t)))
9996                     return false;
9997 
9998                 break;
9999 
10000             default:
10001                 return false;
10002         }
10003 
10004         // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10005         uint32_t Rn = ReadCoreReg (n, &success);
10006         if (!success)
10007             return false;
10008 
10009         addr_t offset_addr;
10010         if (add)
10011             offset_addr = Rn + imm32;
10012         else
10013             offset_addr = Rn - imm32;
10014 
10015         // address = if index then offset_addr else R[n];
10016         addr_t address;
10017         if (index)
10018             address = offset_addr;
10019         else
10020             address = Rn;
10021 
10022         RegisterInfo base_reg;
10023         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10024         RegisterInfo data_reg;
10025         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10026         EmulateInstruction::Context context;
10027         context.type = eContextRegisterStore;
10028         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10029 
10030         // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10031         uint32_t Rt = ReadCoreReg (t, &success);
10032         if (!success)
10033             return false;
10034 
10035         if (t == 15)
10036         {
10037             uint32_t pc_value = ReadCoreReg (PC_REG, &success);
10038             if (!success)
10039                 return false;
10040 
10041             if (!MemUWrite (context, address, pc_value, addr_byte_size))
10042                 return false;
10043         }
10044         else
10045         {
10046             if (!MemUWrite (context, address, Rt, addr_byte_size))
10047                   return false;
10048         }
10049 
10050         // if wback then R[n] = offset_addr;
10051         if (wback)
10052         {
10053             context.type = eContextAdjustBaseRegister;
10054             context.SetImmediate (offset_addr);
10055 
10056             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10057                 return false;
10058         }
10059     }
10060     return true;
10061 }
10062 
10063 // A8.6.66 LDRD (immediate)
10064 // Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two
10065 // words from memory, and writes them to two registers.  It can use offset, post-indexed, or pre-indexed addressing.
10066 bool
EmulateLDRDImmediate(const uint32_t opcode,const ARMEncoding encoding)10067 EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding)
10068 {
10069 #if 0
10070     if ConditionPassed() then
10071         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10072         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10073         address = if index then offset_addr else R[n];
10074         R[t] = MemA[address,4];
10075         R[t2] = MemA[address+4,4];
10076         if wback then R[n] = offset_addr;
10077 #endif
10078 
10079     bool success = false;
10080 
10081     if (ConditionPassed(opcode))
10082     {
10083         uint32_t t;
10084         uint32_t t2;
10085         uint32_t n;
10086         uint32_t imm32;
10087         bool index;
10088         bool add;
10089         bool wback;
10090 
10091         switch (encoding)
10092         {
10093             case eEncodingT1:
10094                 //if P == �0� && W == �0� then SEE �Related encodings�;
10095                 //if Rn == �1111� then SEE LDRD (literal);
10096                 //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10097                 t = Bits32 (opcode, 15, 12);
10098                 t2 = Bits32 (opcode, 11, 8);
10099                 n = Bits32 (opcode, 19, 16);
10100                 imm32 = Bits32 (opcode, 7, 0) << 2;
10101 
10102                 //index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10103                 index = BitIsSet (opcode, 24);
10104                 add = BitIsSet (opcode, 23);
10105                 wback = BitIsSet (opcode, 21);
10106 
10107                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10108                 if (wback && ((n == t) || (n == t2)))
10109                     return false;
10110 
10111                 //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10112                 if (BadReg (t) || BadReg (t2) || (t == t2))
10113                     return false;
10114 
10115                 break;
10116 
10117             case eEncodingA1:
10118                 //if Rn == �1111� then SEE LDRD (literal);
10119                 //if Rt<0> == �1� then UNPREDICTABLE;
10120                 //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10121                 t = Bits32 (opcode, 15, 12);
10122                 if (BitIsSet (t, 0))
10123                     return false;
10124                 t2 = t + 1;
10125                 n = Bits32 (opcode, 19, 16);
10126                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10127 
10128                 //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10129                 index = BitIsSet (opcode, 24);
10130                 add = BitIsSet (opcode, 23);
10131                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10132 
10133                 //if P == �0� && W == �1� then UNPREDICTABLE;
10134                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10135                     return false;
10136 
10137                 //if wback && (n == t || n == t2) then UNPREDICTABLE;
10138                 if (wback && ((n == t) || (n == t2)))
10139                     return false;
10140 
10141                 //if t2 == 15 then UNPREDICTABLE;
10142                 if (t2 == 15)
10143                     return false;
10144 
10145                 break;
10146 
10147             default:
10148                 return false;
10149         }
10150 
10151         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10152         uint32_t Rn = ReadCoreReg (n, &success);
10153         if (!success)
10154             return false;
10155 
10156         addr_t offset_addr;
10157         if (add)
10158                   offset_addr = Rn + imm32;
10159         else
10160             offset_addr = Rn - imm32;
10161 
10162         //address = if index then offset_addr else R[n];
10163         addr_t address;
10164         if (index)
10165             address = offset_addr;
10166         else
10167             address = Rn;
10168 
10169         //R[t] = MemA[address,4];
10170         RegisterInfo base_reg;
10171         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10172 
10173         EmulateInstruction::Context context;
10174         context.type = eContextRegisterLoad;
10175         context.SetRegisterPlusOffset (base_reg, address - Rn);
10176 
10177         const uint32_t addr_byte_size = GetAddressByteSize();
10178         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10179         if (!success)
10180             return false;
10181 
10182         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10183             return false;
10184 
10185         //R[t2] = MemA[address+4,4];
10186 
10187         context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10188         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10189         if (!success)
10190             return false;
10191 
10192         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10193             return false;
10194 
10195         //if wback then R[n] = offset_addr;
10196         if (wback)
10197         {
10198             context.type = eContextAdjustBaseRegister;
10199             context.SetAddress (offset_addr);
10200 
10201             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10202                 return false;
10203         }
10204     }
10205     return true;
10206 }
10207 
10208 // A8.6.68 LDRD (register)
10209 // Load Register Dual (register) calculates an address from a base register value and a register offset, loads two
10210 // words from memory, and writes them to two registers.  It can use offset, post-indexed or pre-indexed addressing.
10211 bool
EmulateLDRDRegister(const uint32_t opcode,const ARMEncoding encoding)10212 EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding)
10213 {
10214 #if 0
10215     if ConditionPassed() then
10216         EncodingSpecificOperations();
10217         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10218         address = if index then offset_addr else R[n];
10219         R[t] = MemA[address,4];
10220         R[t2] = MemA[address+4,4];
10221         if wback then R[n] = offset_addr;
10222 #endif
10223 
10224     bool success = false;
10225 
10226     if (ConditionPassed(opcode))
10227     {
10228         uint32_t t;
10229         uint32_t t2;
10230         uint32_t n;
10231         uint32_t m;
10232         bool index;
10233         bool add;
10234         bool wback;
10235 
10236         switch (encoding)
10237         {
10238             case eEncodingA1:
10239                 // if Rt<0> == �1� then UNPREDICTABLE;
10240                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10241                 t = Bits32 (opcode, 15, 12);
10242                 if (BitIsSet (t, 0))
10243                     return false;
10244                 t2 = t + 1;
10245                 n = Bits32 (opcode, 19, 16);
10246                 m = Bits32 (opcode, 3, 0);
10247 
10248                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10249                 index = BitIsSet (opcode, 24);
10250                 add = BitIsSet (opcode, 23);
10251                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10252 
10253                 // if P == �0� && W == �1� then UNPREDICTABLE;
10254                   if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10255                   return false;
10256 
10257                 // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10258                   if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10259                   return false;
10260 
10261                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10262                   if (wback && ((n == 15) || (n == t) || (n == t2)))
10263                   return false;
10264 
10265                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10266                 if ((ArchVersion() < 6) && wback && (m == n))
10267                   return false;
10268                 break;
10269 
10270             default:
10271                 return false;
10272         }
10273 
10274         uint32_t Rn = ReadCoreReg (n, &success);
10275         if (!success)
10276             return false;
10277         RegisterInfo base_reg;
10278         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10279 
10280         uint32_t Rm = ReadCoreReg (m, &success);
10281         if (!success)
10282             return false;
10283         RegisterInfo offset_reg;
10284         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10285 
10286         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10287         addr_t offset_addr;
10288         if (add)
10289             offset_addr = Rn + Rm;
10290         else
10291             offset_addr = Rn - Rm;
10292 
10293         // address = if index then offset_addr else R[n];
10294         addr_t address;
10295         if (index)
10296             address = offset_addr;
10297         else
10298             address = Rn;
10299 
10300         EmulateInstruction::Context context;
10301         context.type = eContextRegisterLoad;
10302         context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
10303 
10304         // R[t] = MemA[address,4];
10305         const uint32_t addr_byte_size = GetAddressByteSize();
10306         uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10307         if (!success)
10308             return false;
10309 
10310         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10311             return false;
10312 
10313         // R[t2] = MemA[address+4,4];
10314 
10315         data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10316         if (!success)
10317             return false;
10318 
10319         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10320             return false;
10321 
10322         // if wback then R[n] = offset_addr;
10323         if (wback)
10324         {
10325             context.type = eContextAdjustBaseRegister;
10326             context.SetAddress (offset_addr);
10327 
10328             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10329                 return false;
10330         }
10331     }
10332     return true;
10333 }
10334 
10335 // A8.6.200 STRD (immediate)
10336 // Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and
10337 // stores two words from two registers to memory.  It can use offset, post-indexed, or pre-indexed addressing.
10338 bool
EmulateSTRDImm(const uint32_t opcode,const ARMEncoding encoding)10339 EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding)
10340 {
10341 #if 0
10342     if ConditionPassed() then
10343         EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10344         offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10345         address = if index then offset_addr else R[n];
10346         MemA[address,4] = R[t];
10347         MemA[address+4,4] = R[t2];
10348         if wback then R[n] = offset_addr;
10349 #endif
10350 
10351     bool success = false;
10352 
10353     if (ConditionPassed(opcode))
10354     {
10355         uint32_t t;
10356         uint32_t t2;
10357         uint32_t n;
10358         uint32_t imm32;
10359         bool index;
10360         bool add;
10361         bool wback;
10362 
10363         switch (encoding)
10364         {
10365             case eEncodingT1:
10366                 // if P == �0� && W == �0� then SEE �Related encodings�;
10367                 // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10368                 t = Bits32 (opcode, 15, 12);
10369                 t2 = Bits32 (opcode, 11, 8);
10370                 n = Bits32 (opcode, 19, 16);
10371                 imm32 = Bits32 (opcode, 7, 0) << 2;
10372 
10373                 // index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10374                 index = BitIsSet (opcode, 24);
10375                 add = BitIsSet (opcode, 23);
10376                 wback = BitIsSet (opcode, 21);
10377 
10378                 // if wback && (n == t || n == t2) then UNPREDICTABLE;
10379                 if (wback && ((n == t) || (n == t2)))
10380                     return false;
10381 
10382                 // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10383                 if ((n == 15) || BadReg (t) || BadReg (t2))
10384                     return false;
10385 
10386                 break;
10387 
10388             case eEncodingA1:
10389                 // if Rt<0> == �1� then UNPREDICTABLE;
10390                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10391                 t = Bits32 (opcode, 15, 12);
10392                 if (BitIsSet (t, 0))
10393                     return false;
10394 
10395                 t2 = t + 1;
10396                 n = Bits32 (opcode, 19, 16);
10397                 imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10398 
10399                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10400                 index = BitIsSet (opcode, 24);
10401                 add = BitIsSet (opcode, 23);
10402                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10403 
10404                 // if P == �0� && W == �1� then UNPREDICTABLE;
10405                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10406                     return false;
10407 
10408                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10409                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10410                     return false;
10411 
10412                 // if t2 == 15 then UNPREDICTABLE;
10413                 if (t2 == 15)
10414                     return false;
10415 
10416                 break;
10417 
10418             default:
10419                 return false;
10420         }
10421 
10422         RegisterInfo base_reg;
10423         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10424 
10425         uint32_t Rn = ReadCoreReg (n, &success);
10426         if (!success)
10427             return false;
10428 
10429         //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10430         addr_t offset_addr;
10431         if (add)
10432             offset_addr = Rn + imm32;
10433         else
10434             offset_addr = Rn - imm32;
10435 
10436         //address = if index then offset_addr else R[n];
10437         addr_t address;
10438         if (index)
10439             address = offset_addr;
10440         else
10441             address = Rn;
10442 
10443         //MemA[address,4] = R[t];
10444         RegisterInfo data_reg;
10445         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10446 
10447         uint32_t data = ReadCoreReg (t, &success);
10448         if (!success)
10449             return false;
10450 
10451         EmulateInstruction::Context context;
10452         context.type = eContextRegisterStore;
10453         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10454 
10455         const uint32_t addr_byte_size = GetAddressByteSize();
10456 
10457         if (!MemAWrite (context, address, data, addr_byte_size))
10458             return false;
10459 
10460         //MemA[address+4,4] = R[t2];
10461         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10462         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10463 
10464         data = ReadCoreReg (t2, &success);
10465         if (!success)
10466             return false;
10467 
10468         if (!MemAWrite (context, address + 4, data, addr_byte_size))
10469             return false;
10470 
10471         //if wback then R[n] = offset_addr;
10472         if (wback)
10473         {
10474             context.type = eContextAdjustBaseRegister;
10475             context.SetAddress (offset_addr);
10476 
10477             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10478                 return false;
10479         }
10480     }
10481     return true;
10482 }
10483 
10484 
10485 // A8.6.201 STRD (register)
10486 bool
EmulateSTRDReg(const uint32_t opcode,const ARMEncoding encoding)10487 EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding)
10488 {
10489 #if 0
10490     if ConditionPassed() then
10491         EncodingSpecificOperations();
10492         offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10493         address = if index then offset_addr else R[n];
10494         MemA[address,4] = R[t];
10495         MemA[address+4,4] = R[t2];
10496         if wback then R[n] = offset_addr;
10497 #endif
10498 
10499     bool success = false;
10500 
10501     if (ConditionPassed(opcode))
10502     {
10503         uint32_t t;
10504         uint32_t t2;
10505         uint32_t n;
10506         uint32_t m;
10507         bool index;
10508         bool add;
10509         bool wback;
10510 
10511         switch (encoding)
10512         {
10513             case eEncodingA1:
10514                 // if Rt<0> == �1� then UNPREDICTABLE;
10515                 // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10516                 t = Bits32 (opcode, 15, 12);
10517                 if (BitIsSet (t, 0))
10518                    return false;
10519 
10520                 t2 = t+1;
10521                 n = Bits32 (opcode, 19, 16);
10522                 m = Bits32 (opcode, 3, 0);
10523 
10524                 // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10525                 index = BitIsSet (opcode, 24);
10526                 add = BitIsSet (opcode, 23);
10527                 wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10528 
10529                 // if P == �0� && W == �1� then UNPREDICTABLE;
10530                 if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10531                    return false;
10532 
10533                 // if t2 == 15 || m == 15 then UNPREDICTABLE;
10534                 if ((t2 == 15) || (m == 15))
10535                    return false;
10536 
10537                 // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10538                 if (wback && ((n == 15) || (n == t) || (n == t2)))
10539                    return false;
10540 
10541                 // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10542                 if ((ArchVersion() < 6) && wback && (m == n))
10543                    return false;
10544 
10545                 break;
10546 
10547             default:
10548                 return false;
10549         }
10550 
10551         RegisterInfo base_reg;
10552         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10553         RegisterInfo offset_reg;
10554         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10555         RegisterInfo data_reg;
10556 
10557         uint32_t Rn = ReadCoreReg (n, &success);
10558         if (!success)
10559             return false;
10560 
10561         uint32_t Rm = ReadCoreReg (m, &success);
10562         if (!success)
10563             return false;
10564 
10565         // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10566         addr_t offset_addr;
10567         if (add)
10568             offset_addr = Rn + Rm;
10569         else
10570             offset_addr = Rn - Rm;
10571 
10572         // address = if index then offset_addr else R[n];
10573         addr_t address;
10574         if (index)
10575             address = offset_addr;
10576         else
10577             address = Rn;
10578                           // MemA[address,4] = R[t];
10579         uint32_t Rt = ReadCoreReg (t, &success);
10580         if (!success)
10581             return false;
10582 
10583         EmulateInstruction::Context context;
10584         context.type = eContextRegisterStore;
10585         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10586         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10587 
10588         const uint32_t addr_byte_size = GetAddressByteSize();
10589 
10590         if (!MemAWrite (context, address, Rt, addr_byte_size))
10591             return false;
10592 
10593         // MemA[address+4,4] = R[t2];
10594         uint32_t Rt2 = ReadCoreReg (t2, &success);
10595         if (!success)
10596             return false;
10597 
10598         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10599 
10600         context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10601 
10602         if (!MemAWrite (context, address + 4, Rt2, addr_byte_size))
10603             return false;
10604 
10605         // if wback then R[n] = offset_addr;
10606         if (wback)
10607         {
10608             context.type = eContextAdjustBaseRegister;
10609             context.SetAddress (offset_addr);
10610 
10611             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10612                 return false;
10613 
10614         }
10615     }
10616     return true;
10617 }
10618 
10619 // A8.6.319 VLDM
10620 // Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from
10621 // an ARM core register.
10622 bool
EmulateVLDM(const uint32_t opcode,const ARMEncoding encoding)10623 EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding)
10624 {
10625 #if 0
10626     if ConditionPassed() then
10627         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10628         address = if add then R[n] else R[n]-imm32;
10629         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10630         for r = 0 to regs-1
10631             if single_regs then
10632                 S[d+r] = MemA[address,4]; address = address+4;
10633             else
10634                 word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10635                 // Combine the word-aligned words in the correct order for current endianness.
10636                 D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10637 #endif
10638 
10639     bool success = false;
10640 
10641     if (ConditionPassed(opcode))
10642     {
10643         bool single_regs;
10644         bool add;
10645         bool wback;
10646         uint32_t d;
10647         uint32_t n;
10648         uint32_t imm32;
10649         uint32_t regs;
10650 
10651         switch (encoding)
10652         {
10653             case eEncodingT1:
10654             case eEncodingA1:
10655                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10656                 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10657                 // if P == �1� && W == �0� then SEE VLDR;
10658                 // if P == U && W == �1� then UNDEFINED;
10659                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10660                     return false;
10661 
10662                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10663                 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10664                 single_regs = false;
10665                 add = BitIsSet (opcode, 23);
10666                 wback = BitIsSet (opcode, 21);
10667 
10668                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10669                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10670                 n = Bits32 (opcode, 19, 16);
10671                 imm32 = Bits32 (opcode, 7, 0) << 2;
10672 
10673                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�.
10674                 regs = Bits32 (opcode, 7, 0) / 2;
10675 
10676                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10677                 if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
10678                     return false;
10679 
10680                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10681                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10682                     return false;
10683 
10684                 break;
10685 
10686             case eEncodingT2:
10687             case eEncodingA2:
10688                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10689                 // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10690                 // if P == �1� && W == �0� then SEE VLDR;
10691                 // if P == U && W == �1� then UNDEFINED;
10692                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10693                     return false;
10694 
10695                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10696                 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10697                 single_regs = true;
10698                 add = BitIsSet (opcode, 23);
10699                 wback = BitIsSet (opcode, 21);
10700                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10701                 n = Bits32 (opcode, 19, 16);
10702 
10703                 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10704                 imm32 = Bits32 (opcode, 7, 0) << 2;
10705                 regs = Bits32 (opcode, 7, 0);
10706 
10707                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10708                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10709                     return false;
10710 
10711                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10712                 if ((regs == 0) || ((d + regs) > 32))
10713                     return false;
10714                 break;
10715 
10716             default:
10717                 return false;
10718         }
10719 
10720         RegisterInfo base_reg;
10721         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10722 
10723         uint32_t Rn = ReadCoreReg (n, &success);
10724         if (!success)
10725             return false;
10726 
10727         // address = if add then R[n] else R[n]-imm32;
10728         addr_t address;
10729         if (add)
10730             address = Rn;
10731         else
10732             address = Rn - imm32;
10733 
10734         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10735         EmulateInstruction::Context context;
10736 
10737         if (wback)
10738         {
10739             uint32_t value;
10740             if (add)
10741                 value = Rn + imm32;
10742             else
10743                 value = Rn - imm32;
10744 
10745             context.type = eContextAdjustBaseRegister;
10746             context.SetImmediateSigned (value - Rn);
10747             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10748                 return false;
10749 
10750         }
10751 
10752         const uint32_t addr_byte_size = GetAddressByteSize();
10753         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10754 
10755         context.type = eContextRegisterLoad;
10756 
10757         // for r = 0 to regs-1
10758         for (uint32_t r = 0; r < regs; ++r)
10759         {
10760             if (single_regs)
10761             {
10762                 // S[d+r] = MemA[address,4]; address = address+4;
10763                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10764 
10765                 uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10766                 if (!success)
10767                     return false;
10768 
10769                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10770                     return false;
10771 
10772                 address = address + 4;
10773             }
10774             else
10775             {
10776                 // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10777                 context.SetRegisterPlusOffset (base_reg, address - Rn);
10778                 uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10779                 if (!success)
10780                     return false;
10781 
10782                 context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10783                 uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10784                 if (!success)
10785                     return false;
10786 
10787                 address = address + 8;
10788                 // // Combine the word-aligned words in the correct order for current endianness.
10789                 // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10790                 uint64_t data;
10791                 if (GetByteOrder() == eByteOrderBig)
10792                 {
10793                     data = word1;
10794                     data = (data << 32) | word2;
10795                 }
10796                 else
10797                 {
10798                     data = word2;
10799                     data = (data << 32) | word1;
10800                 }
10801 
10802                 if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10803                     return false;
10804             }
10805         }
10806     }
10807     return true;
10808 }
10809 
10810 // A8.6.399 VSTM
10811 // Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an
10812 // ARM core register.
10813 bool
EmulateVSTM(const uint32_t opcode,const ARMEncoding encoding)10814 EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding)
10815 {
10816 #if 0
10817     if ConditionPassed() then
10818         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10819         address = if add then R[n] else R[n]-imm32;
10820         if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10821         for r = 0 to regs-1
10822             if single_regs then
10823                 MemA[address,4] = S[d+r]; address = address+4;
10824             else
10825                 // Store as two word-aligned words in the correct order for current endianness.
10826                 MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10827                 MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10828                 address = address+8;
10829 #endif
10830 
10831     bool success = false;
10832 
10833     if (ConditionPassed (opcode))
10834     {
10835         bool single_regs;
10836         bool add;
10837         bool wback;
10838         uint32_t d;
10839         uint32_t n;
10840         uint32_t imm32;
10841         uint32_t regs;
10842 
10843         switch (encoding)
10844         {
10845             case eEncodingT1:
10846             case eEncodingA1:
10847                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10848                 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10849                 // if P == �1� && W == �0� then SEE VSTR;
10850                 // if P == U && W == �1� then UNDEFINED;
10851                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10852                     return false;
10853 
10854                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10855                 // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10856                 single_regs = false;
10857                 add = BitIsSet (opcode, 23);
10858                 wback = BitIsSet (opcode, 21);
10859 
10860                 // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10861                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10862                 n = Bits32 (opcode, 19, 16);
10863                 imm32 = Bits32 (opcode, 7, 0) << 2;
10864 
10865                 // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�.
10866                 regs = Bits32 (opcode, 7, 0) / 2;
10867 
10868                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10869                 if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10870                     return false;
10871 
10872                 // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10873                 if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10874                     return false;
10875 
10876                 break;
10877 
10878             case eEncodingT2:
10879             case eEncodingA2:
10880                 // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10881                 // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10882                 // if P == �1� && W == �0� then SEE VSTR;
10883                 // if P == U && W == �1� then UNDEFINED;
10884                 if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10885                     return false;
10886 
10887                 // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10888                 // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10889                 single_regs = true;
10890                 add = BitIsSet (opcode, 23);
10891                 wback = BitIsSet (opcode, 21);
10892                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10893                 n = Bits32 (opcode, 19, 16);
10894 
10895                 // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10896                 imm32 = Bits32 (opcode, 7, 0) << 2;
10897                 regs = Bits32 (opcode, 7, 0);
10898 
10899                 // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10900                 if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM)))
10901                     return false;
10902 
10903                 // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10904                 if ((regs == 0) || ((d + regs) > 32))
10905                     return false;
10906 
10907                 break;
10908 
10909             default:
10910                 return false;
10911         }
10912 
10913         RegisterInfo base_reg;
10914         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10915 
10916         uint32_t Rn = ReadCoreReg (n, &success);
10917         if (!success)
10918             return false;
10919 
10920         // address = if add then R[n] else R[n]-imm32;
10921         addr_t address;
10922         if (add)
10923             address = Rn;
10924         else
10925             address = Rn - imm32;
10926 
10927         EmulateInstruction::Context context;
10928         // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10929         if (wback)
10930         {
10931             uint32_t value;
10932             if (add)
10933                 value = Rn + imm32;
10934             else
10935                 value = Rn - imm32;
10936 
10937             context.type = eContextAdjustBaseRegister;
10938             context.SetRegisterPlusOffset (base_reg, value - Rn);
10939 
10940             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10941                 return false;
10942         }
10943 
10944         const uint32_t addr_byte_size = GetAddressByteSize();
10945         uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10946 
10947         context.type = eContextRegisterStore;
10948         // for r = 0 to regs-1
10949         for (uint32_t r = 0; r < regs; ++r)
10950         {
10951 
10952             if (single_regs)
10953             {
10954                 // MemA[address,4] = S[d+r]; address = address+4;
10955                 uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10956                 if (!success)
10957                     return false;
10958 
10959                 RegisterInfo data_reg;
10960                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
10961                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10962                 if (!MemAWrite (context, address, data, addr_byte_size))
10963                     return false;
10964 
10965                 address = address + 4;
10966             }
10967             else
10968             {
10969                 // // Store as two word-aligned words in the correct order for current endianness.
10970                 // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10971                 // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10972                 uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10973                 if (!success)
10974                     return false;
10975 
10976                 RegisterInfo data_reg;
10977                 GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
10978 
10979                 if (GetByteOrder() == eByteOrderBig)
10980                 {
10981                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10982                     if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
10983                         return false;
10984 
10985                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10986                     if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size))
10987                         return false;
10988                 }
10989                 else
10990                 {
10991                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10992                     if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
10993                         return false;
10994 
10995                     context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10996                     if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
10997                         return false;
10998                 }
10999                 // address = address+8;
11000                 address = address + 8;
11001             }
11002         }
11003     }
11004     return true;
11005 }
11006 
11007 // A8.6.320
11008 // This instruciton loads a single extension register fronm memory, using an address from an ARM core register, with
11009 // an optional offset.
11010 bool
EmulateVLDR(const uint32_t opcode,ARMEncoding encoding)11011 EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
11012 {
11013 #if 0
11014     if ConditionPassed() then
11015         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11016         base = if n == 15 then Align(PC,4) else R[n];
11017         address = if add then (base + imm32) else (base - imm32);
11018         if single_reg then
11019             S[d] = MemA[address,4];
11020         else
11021             word1 = MemA[address,4]; word2 = MemA[address+4,4];
11022             // Combine the word-aligned words in the correct order for current endianness.
11023             D[d] = if BigEndian() then word1:word2 else word2:word1;
11024 #endif
11025 
11026     bool success = false;
11027 
11028     if (ConditionPassed (opcode))
11029     {
11030         bool single_reg;
11031         bool add;
11032         uint32_t imm32;
11033         uint32_t d;
11034         uint32_t n;
11035 
11036         switch (encoding)
11037         {
11038             case eEncodingT1:
11039             case eEncodingA1:
11040                 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11041                 single_reg = false;
11042                 add = BitIsSet (opcode, 23);
11043                 imm32 = Bits32 (opcode, 7, 0) << 2;
11044 
11045                 // d = UInt(D:Vd); n = UInt(Rn);
11046                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11047                 n = Bits32 (opcode, 19, 16);
11048 
11049                 break;
11050 
11051             case eEncodingT2:
11052             case eEncodingA2:
11053                 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11054                 single_reg = true;
11055                 add = BitIsSet (opcode, 23);
11056                 imm32 = Bits32 (opcode, 7, 0) << 2;
11057 
11058                 // d = UInt(Vd:D); n = UInt(Rn);
11059                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11060                 n = Bits32 (opcode, 19, 16);
11061 
11062                 break;
11063 
11064             default:
11065                 return false;
11066         }
11067         RegisterInfo base_reg;
11068         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11069 
11070         uint32_t Rn = ReadCoreReg (n, &success);
11071         if (!success)
11072             return false;
11073 
11074         // base = if n == 15 then Align(PC,4) else R[n];
11075         uint32_t base;
11076         if (n == 15)
11077             base = AlignPC (Rn);
11078         else
11079             base = Rn;
11080 
11081         // address = if add then (base + imm32) else (base - imm32);
11082         addr_t address;
11083         if (add)
11084             address = base + imm32;
11085         else
11086             address = base - imm32;
11087 
11088         const uint32_t addr_byte_size = GetAddressByteSize();
11089         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11090 
11091         EmulateInstruction::Context context;
11092         context.type = eContextRegisterLoad;
11093         context.SetRegisterPlusOffset (base_reg, address - base);
11094 
11095         if (single_reg)
11096         {
11097             // S[d] = MemA[address,4];
11098             uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
11099             if (!success)
11100                 return false;
11101 
11102             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data))
11103                 return false;
11104         }
11105         else
11106         {
11107             // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11108             uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
11109             if (!success)
11110                 return false;
11111 
11112             context.SetRegisterPlusOffset (base_reg, (address + 4) - base);
11113             uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
11114             if (!success)
11115                 return false;
11116             // // Combine the word-aligned words in the correct order for current endianness.
11117             // D[d] = if BigEndian() then word1:word2 else word2:word1;
11118             uint64_t data64;
11119             if (GetByteOrder() == eByteOrderBig)
11120             {
11121                 data64 = word1;
11122                 data64 = (data64 << 32) | word2;
11123             }
11124             else
11125             {
11126                 data64 = word2;
11127                 data64 = (data64 << 32) | word1;
11128             }
11129 
11130             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64))
11131                 return false;
11132         }
11133     }
11134     return true;
11135 }
11136 
11137 // A8.6.400 VSTR
11138 // This instruction stores a signle extension register to memory, using an address from an ARM core register, with an
11139 // optional offset.
11140 bool
EmulateVSTR(const uint32_t opcode,ARMEncoding encoding)11141 EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
11142 {
11143 #if 0
11144     if ConditionPassed() then
11145         EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11146         address = if add then (R[n] + imm32) else (R[n] - imm32);
11147         if single_reg then
11148             MemA[address,4] = S[d];
11149         else
11150             // Store as two word-aligned words in the correct order for current endianness.
11151             MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11152             MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11153 #endif
11154 
11155     bool success = false;
11156 
11157     if (ConditionPassed (opcode))
11158     {
11159         bool single_reg;
11160         bool add;
11161         uint32_t imm32;
11162         uint32_t d;
11163         uint32_t n;
11164 
11165         switch (encoding)
11166         {
11167             case eEncodingT1:
11168             case eEncodingA1:
11169                 // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11170                 single_reg = false;
11171                 add = BitIsSet (opcode, 23);
11172                 imm32 = Bits32 (opcode, 7, 0) << 2;
11173 
11174                 // d = UInt(D:Vd); n = UInt(Rn);
11175                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11176                 n = Bits32 (opcode, 19, 16);
11177 
11178                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11179                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11180                     return false;
11181 
11182                 break;
11183 
11184             case eEncodingT2:
11185             case eEncodingA2:
11186                 // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11187                 single_reg = true;
11188                 add = BitIsSet (opcode, 23);
11189                 imm32 = Bits32 (opcode, 7, 0) << 2;
11190 
11191                 // d = UInt(Vd:D); n = UInt(Rn);
11192                 d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11193                 n = Bits32 (opcode, 19, 16);
11194 
11195                 // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11196                 if ((n == 15) && (CurrentInstrSet() != eModeARM))
11197                     return false;
11198 
11199                 break;
11200 
11201             default:
11202                 return false;
11203         }
11204 
11205         RegisterInfo base_reg;
11206         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11207 
11208         uint32_t Rn = ReadCoreReg (n, &success);
11209         if (!success)
11210             return false;
11211 
11212         // address = if add then (R[n] + imm32) else (R[n] - imm32);
11213         addr_t address;
11214         if (add)
11215             address = Rn + imm32;
11216         else
11217             address = Rn - imm32;
11218 
11219         const uint32_t addr_byte_size = GetAddressByteSize();
11220         uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11221 
11222         RegisterInfo data_reg;
11223         GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg);
11224         EmulateInstruction::Context context;
11225         context.type = eContextRegisterStore;
11226         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11227 
11228         if (single_reg)
11229         {
11230             // MemA[address,4] = S[d];
11231             uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11232             if (!success)
11233                 return false;
11234 
11235             if (!MemAWrite (context, address, data, addr_byte_size))
11236                 return false;
11237         }
11238         else
11239         {
11240             // // Store as two word-aligned words in the correct order for current endianness.
11241             // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11242             // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11243             uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11244             if (!success)
11245                 return false;
11246 
11247             if (GetByteOrder() == eByteOrderBig)
11248             {
11249                 if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11250                     return false;
11251 
11252                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11253                 if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size))
11254                     return false;
11255             }
11256             else
11257             {
11258                 if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11259                     return false;
11260 
11261                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11262                 if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11263                     return false;
11264             }
11265         }
11266     }
11267     return true;
11268 }
11269 
11270 // A8.6.307 VLDI1 (multiple single elements)
11271 // This instruction loads elements from memory into one, two, three or four registers, without de-interleaving.  Every
11272 // element of each register is loaded.
11273 bool
EmulateVLD1Multiple(const uint32_t opcode,ARMEncoding encoding)11274 EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding)
11275 {
11276 #if 0
11277     if ConditionPassed() then
11278         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11279         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11280         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11281         for r = 0 to regs-1
11282             for e = 0 to elements-1
11283                 Elem[D[d+r],e,esize] = MemU[address,ebytes];
11284                 address = address + ebytes;
11285 #endif
11286 
11287     bool success = false;
11288 
11289     if (ConditionPassed (opcode))
11290     {
11291         uint32_t regs;
11292         uint32_t alignment;
11293         uint32_t ebytes;
11294         uint32_t esize;
11295         uint32_t elements;
11296         uint32_t d;
11297         uint32_t n;
11298         uint32_t m;
11299         bool wback;
11300         bool register_index;
11301 
11302         switch (encoding)
11303         {
11304             case eEncodingT1:
11305             case eEncodingA1:
11306             {
11307                 // case type of
11308                     // when �0111�
11309                         // regs = 1; if align<1> == �1� then UNDEFINED;
11310                     // when �1010�
11311                         // regs = 2; if align == �11� then UNDEFINED;
11312                     // when �0110�
11313                         // regs = 3; if align<1> == �1� then UNDEFINED;
11314                     // when �0010�
11315                         // regs = 4;
11316                     // otherwise
11317                         // SEE �Related encodings�;
11318                 uint32_t type = Bits32 (opcode, 11, 8);
11319                 uint32_t align = Bits32 (opcode, 5, 4);
11320                 if (type == 7) // '0111'
11321                 {
11322                     regs = 1;
11323                     if (BitIsSet (align, 1))
11324                         return false;
11325                 }
11326                 else if (type == 10) // '1010'
11327                 {
11328                     regs = 2;
11329                     if (align == 3)
11330                         return false;
11331 
11332                 }
11333                 else if (type == 6) // '0110'
11334                 {
11335                     regs = 3;
11336                     if (BitIsSet (align, 1))
11337                         return false;
11338                 }
11339                 else if (type == 2) // '0010'
11340                 {
11341                     regs = 4;
11342                 }
11343                 else
11344                     return false;
11345 
11346                 // alignment = if align == �00� then 1 else 4 << UInt(align);
11347                 if (align == 0)
11348                     alignment = 1;
11349                 else
11350                     alignment = 4 << align;
11351 
11352                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11353                 ebytes = 1 << Bits32 (opcode, 7, 6);
11354                 esize = 8 * ebytes;
11355                 elements = 8 / ebytes;
11356 
11357                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11358                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11359                 n = Bits32 (opcode, 19, 15);
11360                 m = Bits32 (opcode, 3, 0);
11361 
11362                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11363                 wback = (m != 15);
11364                 register_index = ((m != 15) && (m != 13));
11365 
11366                 // if d+regs > 32 then UNPREDICTABLE;
11367                 if ((d + regs) > 32)
11368                     return false;
11369             }
11370                 break;
11371 
11372             default:
11373                 return false;
11374         }
11375 
11376         RegisterInfo base_reg;
11377         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11378 
11379         uint32_t Rn = ReadCoreReg (n, &success);
11380         if (!success)
11381             return false;
11382 
11383         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11384         addr_t address = Rn;
11385         if ((address % alignment) != 0)
11386             return false;
11387 
11388         EmulateInstruction::Context context;
11389         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11390         if (wback)
11391         {
11392             uint32_t Rm = ReadCoreReg (m, &success);
11393             if (!success)
11394                 return false;
11395 
11396             uint32_t offset;
11397             if (register_index)
11398                 offset = Rm;
11399             else
11400                 offset = 8 * regs;
11401 
11402             uint32_t value = Rn + offset;
11403             context.type = eContextAdjustBaseRegister;
11404             context.SetRegisterPlusOffset (base_reg, offset);
11405 
11406             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11407                 return false;
11408 
11409         }
11410 
11411         // for r = 0 to regs-1
11412         for (uint32_t r = 0; r < regs; ++r)
11413         {
11414             // for e = 0 to elements-1
11415             uint64_t assembled_data = 0;
11416             for (uint32_t e = 0; e < elements; ++e)
11417             {
11418                 // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11419                 context.type = eContextRegisterLoad;
11420                 context.SetRegisterPlusOffset (base_reg, address - Rn);
11421                 uint64_t data = MemURead (context, address, ebytes, 0, &success);
11422                 if (!success)
11423                     return false;
11424 
11425                 assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data
11426 
11427                 // address = address + ebytes;
11428                 address = address + ebytes;
11429             }
11430             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data))
11431                 return false;
11432         }
11433     }
11434     return true;
11435 }
11436 
11437 // A8.6.308 VLD1 (single element to one lane)
11438 //
11439 bool
EmulateVLD1Single(const uint32_t opcode,const ARMEncoding encoding)11440 EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding)
11441 {
11442 #if 0
11443     if ConditionPassed() then
11444         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11445         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11446         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11447         Elem[D[d],index,esize] = MemU[address,ebytes];
11448 #endif
11449 
11450     bool success = false;
11451 
11452     if (ConditionPassed (opcode))
11453     {
11454         uint32_t ebytes;
11455         uint32_t esize;
11456         uint32_t index;
11457         uint32_t alignment;
11458         uint32_t d;
11459         uint32_t n;
11460         uint32_t m;
11461         bool wback;
11462         bool register_index;
11463 
11464         switch (encoding)
11465         {
11466             case eEncodingT1:
11467             case eEncodingA1:
11468             {
11469                 uint32_t size = Bits32 (opcode, 11, 10);
11470                 uint32_t index_align = Bits32 (opcode, 7, 4);
11471                 // if size == �11� then SEE VLD1 (single element to all lanes);
11472                 if (size == 3)
11473                    return EmulateVLD1SingleAll (opcode, encoding);
11474                 // case size of
11475                 if (size == 0) // when '00'
11476                 {
11477                     // if index_align<0> != �0� then UNDEFINED;
11478                     if (BitIsClear (index_align, 0))
11479                         return false;
11480 
11481                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11482                     ebytes = 1;
11483                     esize = 8;
11484                     index = Bits32 (index_align, 3, 1);
11485                     alignment = 1;
11486                 }
11487                 else if (size == 1) // when �01�
11488                 {
11489                     // if index_align<1> != �0� then UNDEFINED;
11490                     if (BitIsClear (index_align, 1))
11491                         return false;
11492 
11493                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11494                     ebytes = 2;
11495                     esize = 16;
11496                     index = Bits32 (index_align, 3, 2);
11497 
11498                     // alignment = if index_align<0> == �0� then 1 else 2;
11499                     if (BitIsClear (index_align, 0))
11500                         alignment = 1;
11501                     else
11502                         alignment = 2;
11503                 }
11504                 else if (size == 2) // when �10�
11505                 {
11506                     // if index_align<2> != �0� then UNDEFINED;
11507                     if (BitIsClear (index_align, 2))
11508                         return false;
11509 
11510                     // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11511                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11512                         return false;
11513 
11514                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11515                     ebytes = 4;
11516                     esize = 32;
11517                     index = Bit32 (index_align, 3);
11518 
11519                     // alignment = if index_align<1:0> == �00� then 1 else 4;
11520                     if (Bits32 (index_align, 1, 0) == 0)
11521                         alignment = 1;
11522                     else
11523                         alignment = 4;
11524                 }
11525                 else
11526                 {
11527                     return false;
11528                 }
11529                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11530                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11531                 n = Bits32 (opcode, 19, 16);
11532                 m = Bits32 (opcode, 3, 0);
11533 
11534                 // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
11535                 wback = (m != 15);
11536                 register_index = ((m != 15) && (m != 13));
11537 
11538                 if (n == 15)
11539                     return false;
11540 
11541             }
11542                 break;
11543 
11544             default:
11545                 return false;
11546         }
11547 
11548         RegisterInfo base_reg;
11549         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11550 
11551         uint32_t Rn = ReadCoreReg (n, &success);
11552         if (!success)
11553             return false;
11554 
11555         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11556         addr_t address = Rn;
11557         if ((address % alignment) != 0)
11558             return false;
11559 
11560         EmulateInstruction::Context context;
11561         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11562         if (wback)
11563         {
11564             uint32_t Rm = ReadCoreReg (m, &success);
11565             if (!success)
11566                 return false;
11567 
11568             uint32_t offset;
11569             if (register_index)
11570                 offset = Rm;
11571             else
11572                 offset = ebytes;
11573 
11574             uint32_t value = Rn + offset;
11575 
11576             context.type = eContextAdjustBaseRegister;
11577             context.SetRegisterPlusOffset (base_reg, offset);
11578 
11579             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11580                 return false;
11581         }
11582 
11583         // Elem[D[d],index,esize] = MemU[address,ebytes];
11584         uint32_t element = MemURead (context, address, esize, 0, &success);
11585         if (!success)
11586             return false;
11587 
11588         element = element << (index * esize);
11589 
11590         uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11591         if (!success)
11592             return false;
11593 
11594         uint64_t all_ones = -1;
11595         uint64_t mask = all_ones << ((index+1) * esize);  // mask is all 1's to left of where 'element' goes, & all 0's
11596                                                           // at element & to the right of element.
11597         if (index > 0)
11598             mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes.
11599                                                                      // now mask should be 0's where element goes & 1's
11600                                                                      // everywhere else.
11601 
11602         uint64_t masked_reg = reg_data & mask;  // Take original reg value & zero out 'element' bits
11603         reg_data = masked_reg & element;        // Put 'element' into those bits in reg_data.
11604 
11605         context.type = eContextRegisterLoad;
11606         if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data))
11607             return false;
11608     }
11609     return true;
11610 }
11611 
11612 // A8.6.391 VST1 (multiple single elements)
11613 // Vector Store (multiple single elements) stores elements to memory from one, two, three, or four regsiters, without
11614 // interleaving.  Every element of each register is stored.
11615 bool
EmulateVST1Multiple(const uint32_t opcode,ARMEncoding encoding)11616 EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding)
11617 {
11618 #if 0
11619     if ConditionPassed() then
11620         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11621         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11622         if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11623         for r = 0 to regs-1
11624             for e = 0 to elements-1
11625                 MemU[address,ebytes] = Elem[D[d+r],e,esize];
11626                 address = address + ebytes;
11627 #endif
11628 
11629     bool success = false;
11630 
11631     if (ConditionPassed (opcode))
11632     {
11633         uint32_t regs;
11634         uint32_t alignment;
11635         uint32_t ebytes;
11636         uint32_t esize;
11637         uint32_t elements;
11638         uint32_t d;
11639         uint32_t n;
11640         uint32_t m;
11641         bool wback;
11642         bool register_index;
11643 
11644         switch (encoding)
11645         {
11646             case eEncodingT1:
11647             case eEncodingA1:
11648             {
11649                 uint32_t type = Bits32 (opcode, 11, 8);
11650                 uint32_t align = Bits32 (opcode, 5, 4);
11651 
11652                 // case type of
11653                 if (type == 7)    // when �0111�
11654                 {
11655                     // regs = 1; if align<1> == �1� then UNDEFINED;
11656                     regs = 1;
11657                     if (BitIsSet (align, 1))
11658                         return false;
11659                 }
11660                 else if (type == 10) // when �1010�
11661                 {
11662                     // regs = 2; if align == �11� then UNDEFINED;
11663                     regs = 2;
11664                     if (align == 3)
11665                         return false;
11666                 }
11667                 else if (type == 6) // when �0110�
11668                 {
11669                     // regs = 3; if align<1> == �1� then UNDEFINED;
11670                     regs = 3;
11671                     if (BitIsSet (align, 1))
11672                         return false;
11673                 }
11674                 else if (type == 2) // when �0010�
11675                     // regs = 4;
11676                     regs = 4;
11677                 else // otherwise
11678                     // SEE �Related encodings�;
11679                     return false;
11680 
11681                 // alignment = if align == �00� then 1 else 4 << UInt(align);
11682                 if (align == 0)
11683                     alignment = 1;
11684                 else
11685                     alignment = 4 << align;
11686 
11687                 // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11688                 ebytes = 1 << Bits32 (opcode,7, 6);
11689                 esize = 8 * ebytes;
11690                 elements = 8 / ebytes;
11691 
11692                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11693                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11694                 n = Bits32 (opcode, 19, 16);
11695                 m = Bits32 (opcode, 3, 0);
11696 
11697                 // wback = (m != 15); register_index = (m != 15 && m != 13);
11698                 wback = (m != 15);
11699                 register_index = ((m != 15) && (m != 13));
11700 
11701                 // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11702                 if ((d + regs) > 32)
11703                     return false;
11704 
11705                 if (n == 15)
11706                     return false;
11707 
11708             }
11709                 break;
11710 
11711             default:
11712                 return false;
11713         }
11714 
11715         RegisterInfo base_reg;
11716         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11717 
11718         uint32_t Rn = ReadCoreReg (n, &success);
11719         if (!success)
11720             return false;
11721 
11722         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11723         addr_t address = Rn;
11724         if ((address % alignment) != 0)
11725             return false;
11726 
11727         EmulateInstruction::Context context;
11728         // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11729         if (wback)
11730         {
11731             uint32_t Rm = ReadCoreReg (m, &success);
11732             if (!success)
11733                 return false;
11734 
11735             uint32_t offset;
11736             if (register_index)
11737                 offset = Rm;
11738             else
11739                 offset = 8 * regs;
11740 
11741             context.type = eContextAdjustBaseRegister;
11742             context.SetRegisterPlusOffset (base_reg, offset);
11743 
11744             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11745                 return false;
11746         }
11747 
11748         RegisterInfo data_reg;
11749         context.type = eContextRegisterStore;
11750         // for r = 0 to regs-1
11751         for (uint32_t r = 0; r < regs; ++r)
11752         {
11753             GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
11754             uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
11755             if (!success)
11756                 return false;
11757 
11758              // for e = 0 to elements-1
11759             for (uint32_t e = 0; e < elements; ++e)
11760             {
11761                 // MemU[address,ebytes] = Elem[D[d+r],e,esize];
11762                 uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize);
11763 
11764                 context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11765                 if (!MemUWrite (context, address, word, ebytes))
11766                     return false;
11767 
11768                 // address = address + ebytes;
11769                 address = address + ebytes;
11770             }
11771         }
11772     }
11773     return true;
11774 }
11775 
11776 // A8.6.392 VST1 (single element from one lane)
11777 // This instruction stores one element to memory from one element of a register.
11778 bool
EmulateVST1Single(const uint32_t opcode,ARMEncoding encoding)11779 EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding)
11780 {
11781 #if 0
11782     if ConditionPassed() then
11783         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11784         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11785         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11786         MemU[address,ebytes] = Elem[D[d],index,esize];
11787 #endif
11788 
11789     bool success = false;
11790 
11791     if (ConditionPassed (opcode))
11792     {
11793         uint32_t ebytes;
11794         uint32_t esize;
11795         uint32_t index;
11796         uint32_t alignment;
11797         uint32_t d;
11798         uint32_t n;
11799         uint32_t m;
11800         bool wback;
11801         bool register_index;
11802 
11803         switch (encoding)
11804         {
11805             case eEncodingT1:
11806             case eEncodingA1:
11807             {
11808                 uint32_t size = Bits32 (opcode, 11, 10);
11809                 uint32_t index_align = Bits32 (opcode, 7, 4);
11810 
11811                 // if size == �11� then UNDEFINED;
11812                 if (size == 3)
11813                     return false;
11814 
11815                 // case size of
11816                 if (size == 0) // when �00�
11817                 {
11818                     // if index_align<0> != �0� then UNDEFINED;
11819                     if (BitIsClear (index_align, 0))
11820                         return false;
11821                     // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11822                     ebytes = 1;
11823                     esize = 8;
11824                     index = Bits32 (index_align, 3, 1);
11825                     alignment = 1;
11826                 }
11827                 else if (size == 1) // when �01�
11828                 {
11829                     // if index_align<1> != �0� then UNDEFINED;
11830                     if (BitIsClear (index_align, 1))
11831                         return false;
11832 
11833                     // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11834                     ebytes = 2;
11835                     esize = 16;
11836                     index = Bits32 (index_align, 3, 2);
11837 
11838                     // alignment = if index_align<0> == �0� then 1 else 2;
11839                     if (BitIsClear (index_align, 0))
11840                         alignment = 1;
11841                     else
11842                         alignment = 2;
11843                 }
11844                 else if (size == 2) // when �10�
11845                 {
11846                     // if index_align<2> != �0� then UNDEFINED;
11847                     if (BitIsClear (index_align, 2))
11848                         return false;
11849 
11850                     // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11851                     if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11852                         return false;
11853 
11854                     // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11855                     ebytes = 4;
11856                     esize = 32;
11857                     index = Bit32 (index_align, 3);
11858 
11859                     // alignment = if index_align<1:0> == �00� then 1 else 4;
11860                     if (Bits32 (index_align, 1, 0) == 0)
11861                         alignment = 1;
11862                     else
11863                         alignment = 4;
11864                 }
11865                 else
11866                 {
11867                     return false;
11868                 }
11869                 // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11870                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11871                 n = Bits32 (opcode, 19, 16);
11872                 m = Bits32 (opcode, 3, 0);
11873 
11874                 // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15 then UNPREDICTABLE;
11875                 wback = (m != 15);
11876                 register_index = ((m != 15) && (m != 13));
11877 
11878                 if (n == 15)
11879                     return false;
11880             }
11881                 break;
11882 
11883             default:
11884                 return false;
11885         }
11886 
11887         RegisterInfo base_reg;
11888         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11889 
11890         uint32_t Rn = ReadCoreReg (n, &success);
11891         if (!success)
11892             return false;
11893 
11894         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11895         addr_t address = Rn;
11896         if ((address % alignment) != 0)
11897             return false;
11898 
11899         EmulateInstruction::Context context;
11900         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11901         if (wback)
11902         {
11903             uint32_t Rm = ReadCoreReg (m, &success);
11904             if (!success)
11905                 return false;
11906 
11907             uint32_t offset;
11908             if (register_index)
11909                 offset = Rm;
11910             else
11911                 offset = ebytes;
11912 
11913             context.type = eContextAdjustBaseRegister;
11914             context.SetRegisterPlusOffset (base_reg, offset);
11915 
11916             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11917                 return false;
11918         }
11919 
11920         // MemU[address,ebytes] = Elem[D[d],index,esize];
11921         uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11922         if (!success)
11923             return false;
11924 
11925         uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1,  index * esize);
11926 
11927         RegisterInfo data_reg;
11928         GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg);
11929         context.type = eContextRegisterStore;
11930         context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11931 
11932         if (!MemUWrite (context, address, word, ebytes))
11933             return false;
11934     }
11935     return true;
11936 }
11937 
11938 // A8.6.309 VLD1 (single element to all lanes)
11939 // This instruction loads one element from memory into every element of one or two vectors.
11940 bool
EmulateVLD1SingleAll(const uint32_t opcode,const ARMEncoding encoding)11941 EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding)
11942 {
11943 #if 0
11944     if ConditionPassed() then
11945         EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11946         address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11947         if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11948         replicated_element = Replicate(MemU[address,ebytes], elements);
11949         for r = 0 to regs-1
11950             D[d+r] = replicated_element;
11951 #endif
11952 
11953     bool success = false;
11954 
11955     if (ConditionPassed (opcode))
11956     {
11957         uint32_t ebytes;
11958         uint32_t elements;
11959         uint32_t regs;
11960         uint32_t alignment;
11961         uint32_t d;
11962         uint32_t n;
11963         uint32_t m;
11964         bool wback;
11965         bool register_index;
11966 
11967         switch (encoding)
11968         {
11969             case eEncodingT1:
11970             case eEncodingA1:
11971             {
11972                 //if size == �11� || (size == �00� && a == �1�) then UNDEFINED;
11973                 uint32_t size = Bits32 (opcode, 7, 6);
11974                 if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4)))
11975                     return false;
11976 
11977                 //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2;
11978                 ebytes = 1 << size;
11979                 elements = 8 / ebytes;
11980                 if (BitIsClear (opcode, 5))
11981                     regs = 1;
11982                 else
11983                     regs = 2;
11984 
11985                 //alignment = if a == �0� then 1 else ebytes;
11986                 if (BitIsClear (opcode, 4))
11987                     alignment = 1;
11988                 else
11989                     alignment = ebytes;
11990 
11991                 //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11992                 d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11993                 n = Bits32 (opcode, 19, 16);
11994                 m = Bits32 (opcode, 3, 0);
11995 
11996                 //wback = (m != 15); register_index = (m != 15 && m != 13);
11997                 wback = (m != 15);
11998                 register_index = ((m != 15) && (m != 13));
11999 
12000                 //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
12001                 if ((d + regs) > 32)
12002                     return false;
12003 
12004                 if (n == 15)
12005                     return false;
12006             }
12007             break;
12008 
12009             default:
12010                 return false;
12011         }
12012 
12013         RegisterInfo base_reg;
12014         GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12015 
12016         uint32_t Rn = ReadCoreReg (n, &success);
12017         if (!success)
12018             return false;
12019 
12020         // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12021         addr_t address = Rn;
12022         if ((address % alignment) != 0)
12023             return false;
12024 
12025         EmulateInstruction::Context context;
12026         // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12027         if (wback)
12028         {
12029             uint32_t Rm = ReadCoreReg (m, &success);
12030             if (!success)
12031                 return false;
12032 
12033             uint32_t offset;
12034             if (register_index)
12035                 offset = Rm;
12036             else
12037                 offset = ebytes;
12038 
12039             context.type = eContextAdjustBaseRegister;
12040             context.SetRegisterPlusOffset (base_reg, offset);
12041 
12042             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
12043                 return false;
12044         }
12045 
12046         // replicated_element = Replicate(MemU[address,ebytes], elements);
12047 
12048         context.type = eContextRegisterLoad;
12049         uint64_t word = MemURead (context, address, ebytes, 0, &success);
12050         if (!success)
12051             return false;
12052 
12053         uint64_t replicated_element = 0;
12054         uint32_t esize = ebytes * 8;
12055         for (uint32_t e = 0; e < elements; ++e)
12056             replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0);
12057 
12058         // for r = 0 to regs-1
12059         for (uint32_t r = 0; r < regs; ++r)
12060         {
12061             // D[d+r] = replicated_element;
12062             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element))
12063                 return false;
12064         }
12065     }
12066     return true;
12067 }
12068 
12069 // B6.2.13 SUBS PC, LR and related instructions
12070 //The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack.  It subtracts the
12071 // immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR.
12072 bool
EmulateSUBSPcLrEtc(const uint32_t opcode,const ARMEncoding encoding)12073 EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding)
12074 {
12075 #if 0
12076     if ConditionPassed() then
12077         EncodingSpecificOperations();
12078         if CurrentInstrSet() == InstrSet_ThumbEE then
12079             UNPREDICTABLE;
12080         operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12081         case opcode of
12082             when0000result = R[n] AND operand2; // AND
12083             when0001result = R[n] EOR operand2; // EOR
12084             when0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12085             when0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12086             when0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12087             when0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12088             when0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12089             when0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12090             when1100result = R[n] OR operand2; // ORR
12091             when1101result = operand2; // MOV
12092             when1110result = R[n] AND NOT(operand2); // BIC
12093             when1111result = NOT(operand2); // MVN
12094         CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12095         BranchWritePC(result);
12096 #endif
12097 
12098     bool success = false;
12099 
12100     if (ConditionPassed (opcode))
12101     {
12102         uint32_t n;
12103         uint32_t m;
12104         uint32_t imm32;
12105         bool register_form;
12106         ARM_ShifterType shift_t;
12107         uint32_t shift_n;
12108         uint32_t code;
12109 
12110         switch (encoding)
12111         {
12112             case eEncodingT1:
12113                 // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
12114                 // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB
12115                 n = 14;
12116                 imm32 = Bits32 (opcode, 7, 0);
12117                 register_form = false;
12118                 code = 2;
12119 
12120                 // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12121                 if (InITBlock() && !LastInITBlock())
12122                     return false;
12123 
12124                 break;
12125 
12126             case eEncodingA1:
12127                 // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12128                 n = Bits32 (opcode, 19, 16);
12129                 imm32 = ARMExpandImm (opcode);
12130                 register_form = false;
12131                 code = Bits32 (opcode, 24, 21);
12132 
12133                 break;
12134 
12135             case eEncodingA2:
12136                 // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12137                 n = Bits32 (opcode, 19, 16);
12138                 m = Bits32 (opcode, 3, 0);
12139                 register_form = true;
12140 
12141                 // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12142                 shift_n = DecodeImmShiftARM (opcode, shift_t);
12143 
12144                 break;
12145 
12146             default:
12147                 return false;
12148         }
12149 
12150         // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12151         uint32_t operand2;
12152         if (register_form)
12153         {
12154             uint32_t Rm = ReadCoreReg (m, &success);
12155             if (!success)
12156                 return false;
12157 
12158             operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success);
12159             if (!success)
12160                 return false;
12161         }
12162         else
12163         {
12164             operand2 = imm32;
12165         }
12166 
12167         uint32_t Rn = ReadCoreReg (n, &success);
12168         if (!success)
12169             return false;
12170 
12171         AddWithCarryResult result;
12172 
12173         // case opcode of
12174         switch (code)
12175         {
12176             case 0: // when �0000�
12177                 // result = R[n] AND operand2; // AND
12178                 result.result = Rn & operand2;
12179                 break;
12180 
12181             case 1: // when �0001�
12182                 // result = R[n] EOR operand2; // EOR
12183                 result.result = Rn ^ operand2;
12184                 break;
12185 
12186             case 2: // when �0010�
12187                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12188                 result = AddWithCarry (Rn, ~(operand2), 1);
12189                 break;
12190 
12191             case 3: // when �0011�
12192                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12193                 result = AddWithCarry (~(Rn), operand2, 1);
12194                 break;
12195 
12196             case 4: // when �0100�
12197                 // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12198                 result = AddWithCarry (Rn, operand2, 0);
12199                 break;
12200 
12201             case 5: // when �0101�
12202                 // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12203                 result = AddWithCarry (Rn, operand2, APSR_C);
12204                 break;
12205 
12206             case 6: // when �0110�
12207                 // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12208                 result = AddWithCarry (Rn, ~(operand2), APSR_C);
12209                 break;
12210 
12211             case 7: // when �0111�
12212                 // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12213                 result = AddWithCarry (~(Rn), operand2, APSR_C);
12214                 break;
12215 
12216             case 10: // when �1100�
12217                 // result = R[n] OR operand2; // ORR
12218                 result.result = Rn | operand2;
12219                 break;
12220 
12221             case 11: // when �1101�
12222                 // result = operand2; // MOV
12223                 result.result = operand2;
12224                 break;
12225 
12226             case 12: // when �1110�
12227                 // result = R[n] AND NOT(operand2); // BIC
12228                 result.result = Rn & ~(operand2);
12229                 break;
12230 
12231             case 15: // when �1111�
12232                 // result = NOT(operand2); // MVN
12233                 result.result = ~(operand2);
12234                 break;
12235 
12236             default:
12237                 return false;
12238         }
12239         // CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12240 
12241         // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for
12242         // the best.
12243         uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12244         if (!success)
12245             return false;
12246 
12247         CPSRWriteByInstr (spsr, 15, true);
12248 
12249         // BranchWritePC(result);
12250         EmulateInstruction::Context context;
12251         context.type = eContextAdjustPC;
12252         context.SetImmediate (result.result);
12253 
12254         BranchWritePC (context, result.result);
12255     }
12256     return true;
12257 }
12258 
12259 EmulateInstructionARM::ARMOpcode*
GetARMOpcodeForInstruction(const uint32_t opcode,uint32_t arm_isa)12260 EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12261 {
12262     static ARMOpcode
12263     g_arm_opcodes[] =
12264     {
12265         //----------------------------------------------------------------------
12266         // Prologue instructions
12267         //----------------------------------------------------------------------
12268 
12269         // push register(s)
12270         { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12271         { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
12272 
12273         // set r7 to point to a stack offset
12274         { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
12275         { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12276         // copy the stack pointer to ip
12277         { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
12278         { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
12279         { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12280 
12281         // adjust the stack pointer
12282         { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12283         { 0x0fef0010, 0x004d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12284 
12285         // push one register
12286         // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12287         { 0x0e5f0000, 0x040d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
12288 
12289         // vector push consecutive extension register(s)
12290         { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12291         { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12292 
12293         //----------------------------------------------------------------------
12294         // Epilogue instructions
12295         //----------------------------------------------------------------------
12296 
12297         { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12298         { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12299         { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12300         { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12301 
12302         //----------------------------------------------------------------------
12303         // Supervisor Call (previously Software Interrupt)
12304         //----------------------------------------------------------------------
12305         { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12306 
12307         //----------------------------------------------------------------------
12308         // Branch instructions
12309         //----------------------------------------------------------------------
12310         { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
12311         // To resolve ambiguity, "blx <label>" should come before "bl <label>".
12312         { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12313         { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12314         { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12315         // for example, "bx lr"
12316         { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12317         // bxj
12318         { 0x0ffffff0, 0x012fff20, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12319 
12320         //----------------------------------------------------------------------
12321         // Data-processing instructions
12322         //----------------------------------------------------------------------
12323         // adc (immediate)
12324         { 0x0fe00000, 0x02a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12325         // adc (register)
12326         { 0x0fe00010, 0x00a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12327         // add (immediate)
12328         { 0x0fe00000, 0x02800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
12329         // add (register)
12330         { 0x0fe00010, 0x00800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12331         // add (register-shifted register)
12332         { 0x0fe00090, 0x00800010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12333         // adr
12334         { 0x0fff0000, 0x028f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12335         { 0x0fff0000, 0x024f0000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12336         // and (immediate)
12337         { 0x0fe00000, 0x02000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12338         // and (register)
12339         { 0x0fe00010, 0x00000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12340         // bic (immediate)
12341         { 0x0fe00000, 0x03c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12342         // bic (register)
12343         { 0x0fe00010, 0x01c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12344         // eor (immediate)
12345         { 0x0fe00000, 0x02200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12346         // eor (register)
12347         { 0x0fe00010, 0x00200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12348         // orr (immediate)
12349         { 0x0fe00000, 0x03800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12350         // orr (register)
12351         { 0x0fe00010, 0x01800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12352         // rsb (immediate)
12353         { 0x0fe00000, 0x02600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12354         // rsb (register)
12355         { 0x0fe00010, 0x00600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12356         // rsc (immediate)
12357         { 0x0fe00000, 0x02e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12358         // rsc (register)
12359         { 0x0fe00010, 0x00e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12360         // sbc (immediate)
12361         { 0x0fe00000, 0x02c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12362         // sbc (register)
12363         { 0x0fe00010, 0x00c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12364         // sub (immediate, ARM)
12365         { 0x0fe00000, 0x02400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
12366         // sub (sp minus immediate)
12367         { 0x0fef0000, 0x024d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12368         // sub (register)
12369         { 0x0fe00010, 0x00400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12370         // teq (immediate)
12371         { 0x0ff0f000, 0x03300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12372         // teq (register)
12373         { 0x0ff0f010, 0x01300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12374         // tst (immediate)
12375         { 0x0ff0f000, 0x03100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12376         // tst (register)
12377         { 0x0ff0f010, 0x01100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12378 
12379         // mov (immediate)
12380         { 0x0fef0000, 0x03a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12381         { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
12382         // mov (register)
12383         { 0x0fef0ff0, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12384         // mvn (immediate)
12385         { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12386         // mvn (register)
12387         { 0x0fef0010, 0x01e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12388         // cmn (immediate)
12389         { 0x0ff0f000, 0x03700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12390         // cmn (register)
12391         { 0x0ff0f010, 0x01700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12392         // cmp (immediate)
12393         { 0x0ff0f000, 0x03500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
12394         // cmp (register)
12395         { 0x0ff0f010, 0x01500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
12396         // asr (immediate)
12397         { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
12398         // asr (register)
12399         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
12400         // lsl (immediate)
12401         { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
12402         // lsl (register)
12403         { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
12404         // lsr (immediate)
12405         { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
12406         // lsr (register)
12407         { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
12408         // rrx is a special case encoding of ror (immediate)
12409         { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
12410         // ror (immediate)
12411         { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
12412         // ror (register)
12413         { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
12414         // mul
12415         { 0x0fe000f0, 0x00000090, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
12416 
12417         // subs pc, lr and related instructions
12418         { 0x0e10f000, 0x0210f000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" },
12419         { 0x0e10f010, 0x0010f000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" },
12420 
12421         //----------------------------------------------------------------------
12422         // Load instructions
12423         //----------------------------------------------------------------------
12424         { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12425         { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
12426         { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12427         { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
12428         { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
12429         { 0x0e500010, 0x06100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
12430         { 0x0e5f0000, 0x045f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
12431         { 0xfe500010, 0x06500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
12432         { 0x0e5f00f0, 0x005f00b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12433         { 0x0e5000f0, 0x001000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"  },
12434         { 0x0e5000f0, 0x005000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
12435         { 0x0e5f00f0, 0x005f00d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
12436         { 0x0e5000f0, 0x001000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12437         { 0x0e5000f0, 0x005000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
12438         { 0x0e5f00f0, 0x005f00f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12439         { 0x0e5000f0, 0x001000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12440         { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
12441         { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12442         { 0x0e100f00, 0x0c100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12443         { 0x0e100f00, 0x0c100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12444         { 0x0f300f00, 0x0d100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12445         { 0x0f300f00, 0x0d100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12446         { 0xffb00000, 0xf4200000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12447         { 0xffb00300, 0xf4a00000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12448         { 0xffb00f00, 0xf4a00c00, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12449 
12450         //----------------------------------------------------------------------
12451         // Store instructions
12452         //----------------------------------------------------------------------
12453         { 0x0fd00000, 0x08800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12454         { 0x0fd00000, 0x08000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
12455         { 0x0fd00000, 0x09000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12456         { 0x0fd00000, 0x09800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
12457         { 0x0e500010, 0x06000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
12458         { 0x0e5000f0, 0x000000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
12459         { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
12460         { 0x0e500000, 0x04400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12461         { 0x0e500000, 0x04000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12462         { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
12463         { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12464         { 0x0e100f00, 0x0c000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12465         { 0x0e100f00, 0x0c000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12466         { 0x0f300f00, 0x0d000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
12467         { 0x0f300f00, 0x0d000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
12468         { 0xffb00000, 0xf4000000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12469         { 0xffb00300, 0xf4800000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12470 
12471         //----------------------------------------------------------------------
12472         // Other instructions
12473         //----------------------------------------------------------------------
12474         { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
12475         { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
12476         { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
12477         { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
12478         { 0xfe500000, 0xf8100000, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
12479 
12480     };
12481     static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode);
12482 
12483     for (size_t i=0; i<k_num_arm_opcodes; ++i)
12484     {
12485         if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
12486             (g_arm_opcodes[i].variants & arm_isa) != 0)
12487             return &g_arm_opcodes[i];
12488     }
12489     return NULL;
12490 }
12491 
12492 
12493 EmulateInstructionARM::ARMOpcode*
GetThumbOpcodeForInstruction(const uint32_t opcode,uint32_t arm_isa)12494 EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12495 {
12496 
12497     static ARMOpcode
12498     g_thumb_opcodes[] =
12499     {
12500         //----------------------------------------------------------------------
12501         // Prologue instructions
12502         //----------------------------------------------------------------------
12503 
12504         // push register(s)
12505         { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12506         { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
12507         { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
12508 
12509         // set r7 to point to a stack offset
12510         { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
12511         // copy the stack pointer to r7
12512         { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
12513         // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
12514         { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
12515 
12516         // PC-relative load into register (see also EmulateADDSPRm)
12517         { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
12518 
12519         // adjust the stack pointer
12520         { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
12521         { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
12522         { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
12523         { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
12524         { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12525 
12526         // vector push consecutive extension register(s)
12527         { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12528         { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12529 
12530         //----------------------------------------------------------------------
12531         // Epilogue instructions
12532         //----------------------------------------------------------------------
12533 
12534         { 0xfffff800, 0x0000a800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
12535         { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
12536         { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12537         { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
12538         { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
12539         { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12540         { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12541 
12542         //----------------------------------------------------------------------
12543         // Supervisor Call (previously Software Interrupt)
12544         //----------------------------------------------------------------------
12545         { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
12546 
12547         //----------------------------------------------------------------------
12548         // If Then makes up to four following instructions conditional.
12549         //----------------------------------------------------------------------
12550         // The next 5 opcode _must_ come before the if then instruction
12551         { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"},
12552         { 0xffffffff, 0x0000bf10, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
12553         { 0xffffffff, 0x0000bf20, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
12554         { 0xffffffff, 0x0000bf30, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
12555         { 0xffffffff, 0x0000bf40, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
12556         { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
12557 
12558         //----------------------------------------------------------------------
12559         // Branch instructions
12560         //----------------------------------------------------------------------
12561         // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
12562         { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
12563         { 0xfffff800, 0x0000e000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
12564         { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
12565         { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
12566         // J1 == J2 == 1
12567         { 0xf800d000, 0xf000d000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12568         // J1 == J2 == 1
12569         { 0xf800d001, 0xf000c000, ARMV5_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12570         { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12571         // for example, "bx lr"
12572         { 0xffffff87, 0x00004700, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12573         // bxj
12574         { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12575         // compare and branch
12576         { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
12577         // table branch byte
12578         { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
12579         // table branch halfword
12580         { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
12581 
12582         //----------------------------------------------------------------------
12583         // Data-processing instructions
12584         //----------------------------------------------------------------------
12585         // adc (immediate)
12586         { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
12587         // adc (register)
12588         { 0xffffffc0, 0x00004140, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
12589         { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12590         // add (register)
12591         { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
12592         // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
12593         { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
12594         // adr
12595         { 0xfffff800, 0x0000a000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12596         { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12597         { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12598         // and (immediate)
12599         { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
12600         // and (register)
12601         { 0xffffffc0, 0x00004000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
12602         { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12603         // bic (immediate)
12604         { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
12605         // bic (register)
12606         { 0xffffffc0, 0x00004380, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
12607         { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12608         // eor (immediate)
12609         { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
12610         // eor (register)
12611         { 0xffffffc0, 0x00004040, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
12612         { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12613         // orr (immediate)
12614         { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
12615         // orr (register)
12616         { 0xffffffc0, 0x00004300, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
12617         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12618         // rsb (immediate)
12619         { 0xffffffc0, 0x00004240, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
12620         { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
12621         // rsb (register)
12622         { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12623         // sbc (immediate)
12624         { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12625         // sbc (register)
12626         { 0xffffffc0, 0x00004180, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
12627         { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12628         // add (immediate, Thumb)
12629         { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
12630         { 0xfffff800, 0x00003000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
12631         { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
12632         { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
12633         // sub (immediate, Thumb)
12634         { 0xfffffe00, 0x00001e00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
12635         { 0xfffff800, 0x00003800, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
12636         { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
12637         { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
12638         // sub (sp minus immediate)
12639         { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
12640         { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
12641         // sub (register)
12642         { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
12643         { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
12644         // teq (immediate)
12645         { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
12646         // teq (register)
12647         { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12648         // tst (immediate)
12649         { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
12650         // tst (register)
12651         { 0xffffffc0, 0x00004200, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
12652         { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
12653 
12654 
12655         // move from high register to high register
12656         { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
12657         // move from low register to low register
12658         { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
12659         // mov{s}<c>.w <Rd>, <Rm>
12660         { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
12661         // move immediate
12662         { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
12663         { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
12664         { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
12665         // mvn (immediate)
12666         { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
12667         // mvn (register)
12668         { 0xffffffc0, 0x000043c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
12669         { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
12670         // cmn (immediate)
12671         { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12672         // cmn (register)
12673         { 0xffffffc0, 0x000042c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
12674         { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12675         // cmp (immediate)
12676         { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
12677         { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
12678         // cmp (register) (Rn and Rm both from r0-r7)
12679         { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12680         // cmp (register) (Rn and Rm not both from r0-r7)
12681         { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12682         // asr (immediate)
12683         { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
12684         { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
12685         // asr (register)
12686         { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
12687         { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12688         // lsl (immediate)
12689         { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
12690         { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
12691         // lsl (register)
12692         { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
12693         { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
12694         // lsr (immediate)
12695         { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
12696         { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
12697         // lsr (register)
12698         { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
12699         { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12700         // rrx is a special case encoding of ror (immediate)
12701         { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
12702         // ror (immediate)
12703         { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
12704         // ror (register)
12705         { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
12706         { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
12707         // mul
12708         { 0xffffffc0, 0x00004340, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
12709         // mul
12710         { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
12711 
12712         // subs pc, lr and related instructions
12713         { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" },
12714 
12715         //----------------------------------------------------------------------
12716         // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table;
12717         // otherwise the wrong instructions will be selected.
12718         //----------------------------------------------------------------------
12719 
12720         { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
12721         { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
12722 
12723         //----------------------------------------------------------------------
12724         // Load instructions
12725         //----------------------------------------------------------------------
12726         { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12727         { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
12728         { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12729         { 0xfffff800, 0x00006800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
12730         { 0xfffff800, 0x00009800, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
12731         { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
12732         { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
12733                   // Thumb2 PC-relative load into register
12734         { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
12735         { 0xfffffe00, 0x00005800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
12736         { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
12737         { 0xfffff800, 0x00007800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
12738         { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12739         { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" },
12740         { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
12741         { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
12742         { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
12743         { 0xfffff800, 0x00008800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"  },
12744         { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12745         { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"  },
12746         { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12747         { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
12748         { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12749         { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
12750         { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12751         { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
12752         { 0xfffffe00, 0x00005600, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
12753         { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"  },
12754         { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
12755         { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12756         { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12757         { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
12758         { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12759         { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
12760         { 0xfe100f00, 0xec100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12761         { 0xfe100f00, 0xec100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
12762         { 0xffe00f00, 0xed100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12763         { 0xff300f00, 0xed100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
12764         { 0xffb00000, 0xf9200000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12765         { 0xffb00300, 0xf9a00000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12766         { 0xffb00f00, 0xf9a00c00, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12767 
12768         //----------------------------------------------------------------------
12769         // Store instructions
12770         //----------------------------------------------------------------------
12771         { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12772         { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
12773         { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12774         { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
12775         { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
12776         { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
12777         { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
12778         { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
12779         { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
12780         { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
12781         { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
12782         { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
12783         { 0xfffffe00, 0x00005200, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
12784         { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12785         { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
12786         { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
12787         { 0xfe100f00, 0xec000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12788         { 0xfea00f00, 0xec000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12789         { 0xff300f00, 0xed000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12790         { 0xff300f00, 0xed000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12791         { 0xffb00000, 0xf9000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12792         { 0xffb00300, 0xf9800000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12793 
12794         //----------------------------------------------------------------------
12795         // Other instructions
12796         //----------------------------------------------------------------------
12797         { 0xffffffc0, 0x0000b240, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
12798         { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12799         { 0xffffffc0, 0x0000b200, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
12800         { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12801         { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
12802         { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12803         { 0xffffffc0, 0x0000b280, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
12804         { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12805     };
12806 
12807     const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode);
12808     for (size_t i=0; i<k_num_thumb_opcodes; ++i)
12809     {
12810         if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
12811             (g_thumb_opcodes[i].variants & arm_isa) != 0)
12812             return &g_thumb_opcodes[i];
12813     }
12814     return NULL;
12815 }
12816 
12817 bool
SetArchitecture(const ArchSpec & arch)12818 EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
12819 {
12820     m_arch = arch;
12821     m_arm_isa = 0;
12822     const char *arch_cstr = arch.GetArchitectureName ();
12823     if (arch_cstr)
12824     {
12825         if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
12826         else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
12827         else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
12828         else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
12829         else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
12830         else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
12831         else if (0 == ::strcasecmp(arch_cstr, "armv7s"))    m_arm_isa = ARMv7S;
12832         else if (0 == ::strcasecmp(arch_cstr, "arm"))       m_arm_isa = ARMvAll;
12833         else if (0 == ::strcasecmp(arch_cstr, "thumb"))     m_arm_isa = ARMvAll;
12834         else if (0 == ::strncasecmp(arch_cstr,"armv4", 5))  m_arm_isa = ARMv4;
12835         else if (0 == ::strncasecmp(arch_cstr,"armv6", 5))  m_arm_isa = ARMv6;
12836         else if (0 == ::strncasecmp(arch_cstr,"armv7", 5))  m_arm_isa = ARMv7;
12837         else if (0 == ::strncasecmp(arch_cstr,"armv8", 5))  m_arm_isa = ARMv8;
12838     }
12839     return m_arm_isa != 0;
12840 }
12841 
12842 bool
SetInstruction(const Opcode & insn_opcode,const Address & inst_addr,Target * target)12843 EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
12844 {
12845     if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
12846     {
12847         if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
12848             m_opcode_mode = eModeThumb;
12849         else
12850         {
12851             AddressClass addr_class = inst_addr.GetAddressClass();
12852 
12853             if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
12854                 m_opcode_mode = eModeARM;
12855             else if (addr_class == eAddressClassCodeAlternateISA)
12856                 m_opcode_mode = eModeThumb;
12857             else
12858                 return false;
12859         }
12860         if (m_opcode_mode == eModeThumb)
12861             m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
12862         else
12863             m_opcode_cpsr = CPSR_MODE_USR;
12864         return true;
12865     }
12866     return false;
12867 }
12868 
12869 bool
ReadInstruction()12870 EmulateInstructionARM::ReadInstruction ()
12871 {
12872     bool success = false;
12873     m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
12874     if (success)
12875     {
12876         addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
12877         if (success)
12878         {
12879             Context read_inst_context;
12880             read_inst_context.type = eContextReadOpcode;
12881             read_inst_context.SetNoArgs ();
12882 
12883             if (m_opcode_cpsr & MASK_CPSR_T)
12884             {
12885                 m_opcode_mode = eModeThumb;
12886                 uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
12887 
12888                 if (success)
12889                 {
12890                     if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
12891                     {
12892                         m_opcode.SetOpcode16 (thumb_opcode);
12893                     }
12894                     else
12895                     {
12896                         m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success));
12897                     }
12898                 }
12899             }
12900             else
12901             {
12902                 m_opcode_mode = eModeARM;
12903                 m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success));
12904             }
12905         }
12906     }
12907     if (!success)
12908     {
12909         m_opcode_mode = eModeInvalid;
12910         m_addr = LLDB_INVALID_ADDRESS;
12911     }
12912     return success;
12913 }
12914 
12915 uint32_t
ArchVersion()12916 EmulateInstructionARM::ArchVersion ()
12917 {
12918     return m_arm_isa;
12919 }
12920 
12921 bool
ConditionPassed(const uint32_t opcode,bool * is_conditional)12922 EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional)
12923 {
12924    // If we are ignoring conditions, then always return true.
12925    // this allows us to iterate over disassembly code and still
12926    // emulate an instruction even if we don't have all the right
12927    // bits set in the CPSR register...
12928     if (m_ignore_conditions)
12929         return true;
12930 
12931     if (is_conditional)
12932         *is_conditional = true;
12933 
12934     const uint32_t cond = CurrentCond (opcode);
12935 
12936     if (cond == UINT32_MAX)
12937         return false;
12938 
12939     bool result = false;
12940     switch (UnsignedBits(cond, 3, 1))
12941     {
12942     case 0:
12943 		if (m_opcode_cpsr == 0)
12944 			result = true;
12945         else
12946             result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
12947 		break;
12948     case 1:
12949         if (m_opcode_cpsr == 0)
12950             result = true;
12951         else
12952             result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
12953 		break;
12954     case 2:
12955         if (m_opcode_cpsr == 0)
12956             result = true;
12957         else
12958             result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
12959 		break;
12960     case 3:
12961         if (m_opcode_cpsr == 0)
12962             result = true;
12963         else
12964             result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
12965 		break;
12966     case 4:
12967         if (m_opcode_cpsr == 0)
12968             result = true;
12969         else
12970             result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12971 		break;
12972     case 5:
12973         if (m_opcode_cpsr == 0)
12974             result = true;
12975         else
12976 		{
12977             bool n = (m_opcode_cpsr & MASK_CPSR_N);
12978             bool v = (m_opcode_cpsr & MASK_CPSR_V);
12979             result = n == v;
12980         }
12981         break;
12982     case 6:
12983         if (m_opcode_cpsr == 0)
12984             result = true;
12985         else
12986 		{
12987             bool n = (m_opcode_cpsr & MASK_CPSR_N);
12988             bool v = (m_opcode_cpsr & MASK_CPSR_V);
12989             result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12990         }
12991         break;
12992     case 7:
12993         // Always execute (cond == 0b1110, or the special 0b1111 which gives
12994         // opcodes different meanings, but always means execution happpens.
12995         if (is_conditional)
12996             *is_conditional = false;
12997         result = true;
12998         break;
12999     }
13000 
13001     if (cond & 1)
13002         result = !result;
13003     return result;
13004 }
13005 
13006 uint32_t
CurrentCond(const uint32_t opcode)13007 EmulateInstructionARM::CurrentCond (const uint32_t opcode)
13008 {
13009     switch (m_opcode_mode)
13010     {
13011     case eModeInvalid:
13012         break;
13013 
13014     case eModeARM:
13015         return UnsignedBits(opcode, 31, 28);
13016 
13017     case eModeThumb:
13018         // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
13019         // 'cond' field of the encoding.
13020         {
13021             const uint32_t byte_size = m_opcode.GetByteSize();
13022             if (byte_size == 2)
13023             {
13024                 if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f)
13025                     return Bits32(opcode, 11, 7);
13026             }
13027             else if (byte_size == 4)
13028             {
13029                 if (Bits32(opcode, 31, 27) == 0x1e &&
13030                     Bits32(opcode, 15, 14) == 0x02 &&
13031                     Bits32(opcode, 12, 12) == 0x00 &&
13032                     Bits32(opcode, 25, 22) <= 0x0d)
13033                 {
13034                     return Bits32(opcode, 25, 22);
13035                 }
13036             }
13037             else
13038                 // We have an invalid thumb instruction, let's bail out.
13039                 break;
13040 
13041             return m_it_session.GetCond();
13042         }
13043     }
13044     return UINT32_MAX;  // Return invalid value
13045 }
13046 
13047 bool
InITBlock()13048 EmulateInstructionARM::InITBlock()
13049 {
13050     return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13051 }
13052 
13053 bool
LastInITBlock()13054 EmulateInstructionARM::LastInITBlock()
13055 {
13056     return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13057 }
13058 
13059 bool
BadMode(uint32_t mode)13060 EmulateInstructionARM::BadMode (uint32_t mode)
13061 {
13062 
13063     switch (mode)
13064     {
13065         case 16: return false; // '10000'
13066         case 17: return false; // '10001'
13067         case 18: return false; // '10010'
13068         case 19: return false; // '10011'
13069         case 22: return false; // '10110'
13070         case 23: return false; // '10111'
13071         case 27: return false; // '11011'
13072         case 31: return false; // '11111'
13073         default: return true;
13074     }
13075     return true;
13076 }
13077 
13078 bool
CurrentModeIsPrivileged()13079 EmulateInstructionARM::CurrentModeIsPrivileged ()
13080 {
13081     uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
13082 
13083     if (BadMode (mode))
13084         return false;
13085 
13086     if (mode == 16)
13087         return false;
13088 
13089     return true;
13090 }
13091 
13092 void
CPSRWriteByInstr(uint32_t value,uint32_t bytemask,bool affect_execstate)13093 EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
13094 {
13095     bool privileged = CurrentModeIsPrivileged();
13096 
13097     uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20;
13098 
13099     if (BitIsSet (bytemask, 3))
13100     {
13101         tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
13102         if (affect_execstate)
13103             tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
13104     }
13105 
13106     if (BitIsSet (bytemask, 2))
13107     {
13108         tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
13109     }
13110 
13111     if (BitIsSet (bytemask, 1))
13112     {
13113         if (affect_execstate)
13114             tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
13115         tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
13116         if (privileged)
13117             tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
13118     }
13119 
13120     if (BitIsSet (bytemask, 0))
13121     {
13122         if (privileged)
13123             tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
13124         if (affect_execstate)
13125             tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
13126         if (privileged)
13127             tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
13128     }
13129 
13130     m_opcode_cpsr = tmp_cpsr;
13131 }
13132 
13133 
13134 bool
BranchWritePC(const Context & context,uint32_t addr)13135 EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
13136 {
13137     addr_t target;
13138 
13139     // Check the current instruction set.
13140     if (CurrentInstrSet() == eModeARM)
13141         target = addr & 0xfffffffc;
13142     else
13143         target = addr & 0xfffffffe;
13144 
13145     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13146         return false;
13147 
13148     return true;
13149 }
13150 
13151 // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
13152 bool
BXWritePC(Context & context,uint32_t addr)13153 EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
13154 {
13155     addr_t target;
13156     // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
13157     // we want to record it and issue a WriteRegister callback so the clients
13158     // can track the mode changes accordingly.
13159     bool cpsr_changed = false;
13160 
13161     if (BitIsSet(addr, 0))
13162     {
13163         if (CurrentInstrSet() != eModeThumb)
13164         {
13165             SelectInstrSet(eModeThumb);
13166             cpsr_changed = true;
13167         }
13168         target = addr & 0xfffffffe;
13169         context.SetISA (eModeThumb);
13170     }
13171     else if (BitIsClear(addr, 1))
13172     {
13173         if (CurrentInstrSet() != eModeARM)
13174         {
13175             SelectInstrSet(eModeARM);
13176             cpsr_changed = true;
13177         }
13178         target = addr & 0xfffffffc;
13179         context.SetISA (eModeARM);
13180     }
13181     else
13182         return false; // address<1:0> == '10' => UNPREDICTABLE
13183 
13184     if (cpsr_changed)
13185     {
13186         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13187             return false;
13188     }
13189     if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13190         return false;
13191 
13192     return true;
13193 }
13194 
13195 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
13196 bool
LoadWritePC(Context & context,uint32_t addr)13197 EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
13198 {
13199     if (ArchVersion() >= ARMv5T)
13200         return BXWritePC(context, addr);
13201     else
13202         return BranchWritePC((const Context)context, addr);
13203 }
13204 
13205 // Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
13206 bool
ALUWritePC(Context & context,uint32_t addr)13207 EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
13208 {
13209     if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
13210         return BXWritePC(context, addr);
13211     else
13212         return BranchWritePC((const Context)context, addr);
13213 }
13214 
13215 EmulateInstructionARM::Mode
CurrentInstrSet()13216 EmulateInstructionARM::CurrentInstrSet ()
13217 {
13218     return m_opcode_mode;
13219 }
13220 
13221 // Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
13222 // ReadInstruction() is performed.  This function has a side effect of updating
13223 // the m_new_inst_cpsr member variable if necessary.
13224 bool
SelectInstrSet(Mode arm_or_thumb)13225 EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
13226 {
13227     m_new_inst_cpsr = m_opcode_cpsr;
13228     switch (arm_or_thumb)
13229     {
13230     default:
13231         return false;
13232     case eModeARM:
13233         // Clear the T bit.
13234         m_new_inst_cpsr &= ~MASK_CPSR_T;
13235         break;
13236     case eModeThumb:
13237         // Set the T bit.
13238         m_new_inst_cpsr |= MASK_CPSR_T;
13239         break;
13240     }
13241     return true;
13242 }
13243 
13244 // This function returns TRUE if the processor currently provides support for
13245 // unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
13246 // controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
13247 bool
UnalignedSupport()13248 EmulateInstructionARM::UnalignedSupport()
13249 {
13250     return (ArchVersion() >= ARMv7);
13251 }
13252 
13253 // The main addition and subtraction instructions can produce status information
13254 // about both unsigned carry and signed overflow conditions.  This status
13255 // information can be used to synthesize multi-word additions and subtractions.
13256 EmulateInstructionARM::AddWithCarryResult
AddWithCarry(uint32_t x,uint32_t y,uint8_t carry_in)13257 EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
13258 {
13259     uint32_t result;
13260     uint8_t carry_out;
13261     uint8_t overflow;
13262 
13263     uint64_t unsigned_sum = x + y + carry_in;
13264     int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
13265 
13266     result = UnsignedBits(unsigned_sum, 31, 0);
13267 //    carry_out = (result == unsigned_sum ? 0 : 1);
13268     overflow = ((int32_t)result == signed_sum ? 0 : 1);
13269 
13270     if (carry_in)
13271         carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0;
13272     else
13273         carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0;
13274 
13275     AddWithCarryResult res = { result, carry_out, overflow };
13276     return res;
13277 }
13278 
13279 uint32_t
ReadCoreReg(uint32_t num,bool * success)13280 EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
13281 {
13282     uint32_t reg_kind, reg_num;
13283     switch (num)
13284     {
13285     case SP_REG:
13286         reg_kind = eRegisterKindGeneric;
13287         reg_num  = LLDB_REGNUM_GENERIC_SP;
13288         break;
13289     case LR_REG:
13290         reg_kind = eRegisterKindGeneric;
13291         reg_num  = LLDB_REGNUM_GENERIC_RA;
13292         break;
13293     case PC_REG:
13294         reg_kind = eRegisterKindGeneric;
13295         reg_num  = LLDB_REGNUM_GENERIC_PC;
13296         break;
13297     default:
13298         if (num < SP_REG)
13299         {
13300             reg_kind = eRegisterKindDWARF;
13301             reg_num  = dwarf_r0 + num;
13302         }
13303         else
13304         {
13305             //assert(0 && "Invalid register number");
13306             *success = false;
13307             return UINT32_MAX;
13308         }
13309         break;
13310     }
13311 
13312     // Read our register.
13313     uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
13314 
13315     // When executing an ARM instruction , PC reads as the address of the current
13316     // instruction plus 8.
13317     // When executing a Thumb instruction , PC reads as the address of the current
13318     // instruction plus 4.
13319     if (num == 15)
13320     {
13321         if (CurrentInstrSet() == eModeARM)
13322             val += 8;
13323         else
13324             val += 4;
13325     }
13326 
13327     return val;
13328 }
13329 
13330 // Write the result to the ARM core register Rd, and optionally update the
13331 // condition flags based on the result.
13332 //
13333 // This helper method tries to encapsulate the following pseudocode from the
13334 // ARM Architecture Reference Manual:
13335 //
13336 // if d == 15 then         // Can only occur for encoding A1
13337 //     ALUWritePC(result); // setflags is always FALSE here
13338 // else
13339 //     R[d] = result;
13340 //     if setflags then
13341 //         APSR.N = result<31>;
13342 //         APSR.Z = IsZeroBit(result);
13343 //         APSR.C = carry;
13344 //         // APSR.V unchanged
13345 //
13346 // In the above case, the API client does not pass in the overflow arg, which
13347 // defaults to ~0u.
13348 bool
WriteCoreRegOptionalFlags(Context & context,const uint32_t result,const uint32_t Rd,bool setflags,const uint32_t carry,const uint32_t overflow)13349 EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
13350                                                   const uint32_t result,
13351                                                   const uint32_t Rd,
13352                                                   bool setflags,
13353                                                   const uint32_t carry,
13354                                                   const uint32_t overflow)
13355 {
13356     if (Rd == 15)
13357     {
13358         if (!ALUWritePC (context, result))
13359             return false;
13360     }
13361     else
13362     {
13363         uint32_t reg_kind, reg_num;
13364         switch (Rd)
13365         {
13366         case SP_REG:
13367             reg_kind = eRegisterKindGeneric;
13368             reg_num  = LLDB_REGNUM_GENERIC_SP;
13369             break;
13370         case LR_REG:
13371             reg_kind = eRegisterKindGeneric;
13372             reg_num  = LLDB_REGNUM_GENERIC_RA;
13373             break;
13374         default:
13375             reg_kind = eRegisterKindDWARF;
13376             reg_num  = dwarf_r0 + Rd;
13377         }
13378         if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
13379             return false;
13380         if (setflags)
13381             return WriteFlags (context, result, carry, overflow);
13382     }
13383     return true;
13384 }
13385 
13386 // This helper method tries to encapsulate the following pseudocode from the
13387 // ARM Architecture Reference Manual:
13388 //
13389 // APSR.N = result<31>;
13390 // APSR.Z = IsZeroBit(result);
13391 // APSR.C = carry;
13392 // APSR.V = overflow
13393 //
13394 // Default arguments can be specified for carry and overflow parameters, which means
13395 // not to update the respective flags.
13396 bool
WriteFlags(Context & context,const uint32_t result,const uint32_t carry,const uint32_t overflow)13397 EmulateInstructionARM::WriteFlags (Context &context,
13398                                    const uint32_t result,
13399                                    const uint32_t carry,
13400                                    const uint32_t overflow)
13401 {
13402     m_new_inst_cpsr = m_opcode_cpsr;
13403     SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
13404     SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
13405     if (carry != ~0u)
13406         SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
13407     if (overflow != ~0u)
13408         SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
13409     if (m_new_inst_cpsr != m_opcode_cpsr)
13410     {
13411         if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13412             return false;
13413     }
13414     return true;
13415 }
13416 
13417 bool
EvaluateInstruction(uint32_t evaluate_options)13418 EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
13419 {
13420     // Advance the ITSTATE bits to their values for the next instruction.
13421     if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
13422         m_it_session.ITAdvance();
13423 
13424     ARMOpcode *opcode_data = NULL;
13425 
13426     if (m_opcode_mode == eModeThumb)
13427         opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13428     else if (m_opcode_mode == eModeARM)
13429         opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13430 
13431     if (opcode_data == NULL)
13432         return false;
13433 
13434     const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
13435     m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
13436 
13437     bool success = false;
13438     if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
13439     {
13440         m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF,
13441                                                 dwarf_cpsr,
13442                                                 0,
13443                                                 &success);
13444     }
13445 
13446     // Only return false if we are unable to read the CPSR if we care about conditions
13447     if (success == false && m_ignore_conditions == false)
13448         return false;
13449 
13450     uint32_t orig_pc_value = 0;
13451     if (auto_advance_pc)
13452     {
13453         orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13454         if (!success)
13455             return false;
13456     }
13457 
13458     // Call the Emulate... function.
13459     success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
13460     if (!success)
13461         return false;
13462 
13463     if (auto_advance_pc)
13464     {
13465         uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13466         if (!success)
13467             return false;
13468 
13469         if (auto_advance_pc && (after_pc_value == orig_pc_value))
13470         {
13471             if (opcode_data->size == eSize32)
13472                 after_pc_value += 4;
13473             else if (opcode_data->size == eSize16)
13474                 after_pc_value += 2;
13475 
13476             EmulateInstruction::Context context;
13477             context.type = eContextAdvancePC;
13478             context.SetNoArgs();
13479             if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
13480                 return false;
13481 
13482         }
13483     }
13484     return true;
13485 }
13486 
13487 bool
TestEmulation(Stream * out_stream,ArchSpec & arch,OptionValueDictionary * test_data)13488 EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data)
13489 {
13490     if (!test_data)
13491     {
13492         out_stream->Printf ("TestEmulation: Missing test data.\n");
13493         return false;
13494     }
13495 
13496     static ConstString opcode_key ("opcode");
13497     static ConstString before_key ("before_state");
13498     static ConstString after_key ("after_state");
13499 
13500     OptionValueSP value_sp = test_data->GetValueForKey (opcode_key);
13501 
13502     uint32_t test_opcode;
13503     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64))
13504     {
13505         out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n");
13506         return false;
13507     }
13508     test_opcode = value_sp->GetUInt64Value ();
13509 
13510     if (arch.GetTriple().getArch() == llvm::Triple::arm)
13511     {
13512         m_opcode_mode = eModeARM;
13513         m_opcode.SetOpcode32 (test_opcode);
13514     }
13515     else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
13516     {
13517         m_opcode_mode = eModeThumb;
13518         if (test_opcode < 0x10000)
13519             m_opcode.SetOpcode16 (test_opcode);
13520         else
13521             m_opcode.SetOpcode32 (test_opcode);
13522 
13523     }
13524     else
13525     {
13526         out_stream->Printf ("TestEmulation:  Invalid arch.\n");
13527         return false;
13528     }
13529 
13530     EmulationStateARM before_state;
13531     EmulationStateARM after_state;
13532 
13533     value_sp = test_data->GetValueForKey (before_key);
13534     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13535     {
13536         out_stream->Printf ("TestEmulation:  Failed to find 'before' state.\n");
13537         return false;
13538     }
13539 
13540     OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary ();
13541     if (!before_state.LoadStateFromDictionary (state_dictionary))
13542     {
13543         out_stream->Printf ("TestEmulation:  Failed loading 'before' state.\n");
13544         return false;
13545     }
13546 
13547     value_sp = test_data->GetValueForKey (after_key);
13548     if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13549     {
13550         out_stream->Printf ("TestEmulation:  Failed to find 'after' state.\n");
13551         return false;
13552     }
13553 
13554     state_dictionary = value_sp->GetAsDictionary ();
13555     if (!after_state.LoadStateFromDictionary (state_dictionary))
13556     {
13557         out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n");
13558         return false;
13559     }
13560 
13561     SetBaton ((void *) &before_state);
13562     SetCallbacks (&EmulationStateARM::ReadPseudoMemory,
13563                   &EmulationStateARM::WritePseudoMemory,
13564                   &EmulationStateARM::ReadPseudoRegister,
13565                   &EmulationStateARM::WritePseudoRegister);
13566 
13567     bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC);
13568     if (!success)
13569     {
13570         out_stream->Printf ("TestEmulation:  EvaluateInstruction() failed.\n");
13571         return false;
13572     }
13573 
13574     success = before_state.CompareState (after_state);
13575     if (!success)
13576         out_stream->Printf ("TestEmulation:  'before' and 'after' states do not match.\n");
13577 
13578     return success;
13579 }
13580 //
13581 //
13582 //const char *
13583 //EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
13584 //{
13585 //    if (reg_kind == eRegisterKindGeneric)
13586 //    {
13587 //        switch (reg_num)
13588 //        {
13589 //        case LLDB_REGNUM_GENERIC_PC:    return "pc";
13590 //        case LLDB_REGNUM_GENERIC_SP:    return "sp";
13591 //        case LLDB_REGNUM_GENERIC_FP:    return "fp";
13592 //        case LLDB_REGNUM_GENERIC_RA:    return "lr";
13593 //        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
13594 //        default: return NULL;
13595 //        }
13596 //    }
13597 //    else if (reg_kind == eRegisterKindDWARF)
13598 //    {
13599 //        return GetARMDWARFRegisterName (reg_num);
13600 //    }
13601 //    return NULL;
13602 //}
13603 //
13604 bool
CreateFunctionEntryUnwind(UnwindPlan & unwind_plan)13605 EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
13606 {
13607     unwind_plan.Clear();
13608     unwind_plan.SetRegisterKind (eRegisterKindDWARF);
13609 
13610     UnwindPlan::RowSP row(new UnwindPlan::Row);
13611 
13612     // Our previous Call Frame Address is the stack pointer
13613     row->SetCFARegister (dwarf_sp);
13614 
13615     // Our previous PC is in the LR
13616     row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true);
13617     unwind_plan.AppendRow (row);
13618 
13619     // All other registers are the same.
13620 
13621     unwind_plan.SetSourceName ("EmulateInstructionARM");
13622     unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
13623     unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
13624     return true;
13625 }
13626