EmulateInstructionARM.cpp revision 81a96aa6242f7b559770f5dc62316253cb8cb0d4
1//===-- EmulateInstructionARM.cpp -------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include <stdlib.h>
11
12#include "EmulateInstructionARM.h"
13#include "EmulationStateARM.h"
14#include "lldb/Core/ArchSpec.h"
15#include "lldb/Core/Address.h"
16#include "lldb/Core/ConstString.h"
17#include "lldb/Core/PluginManager.h"
18#include "lldb/Core/Stream.h"
19#include "lldb/Interpreter/OptionValueArray.h"
20#include "lldb/Interpreter/OptionValueDictionary.h"
21#include "lldb/Symbol/UnwindPlan.h"
22
23#include "Plugins/Process/Utility/ARMDefines.h"
24#include "Plugins/Process/Utility/ARMUtils.h"
25#include "Utility/ARM_DWARF_Registers.h"
26
27#include "llvm/Support/MathExtras.h" // for SignExtend32 template function
28                                     // and CountTrailingZeros_32 function
29
30using namespace lldb;
31using 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.
47static uint32_t
48CountITSize (uint32_t ITMask) {
49    // First count the trailing zeros of the IT mask.
50    uint32_t TZ = llvm::CountTrailingZeros_32(ITMask);
51    if (TZ > 3)
52    {
53        printf("Encoding error: IT Mask '0000'\n");
54        return 0;
55    }
56    return (4 - TZ);
57}
58
59// Init ITState.  Note that at least one bit is always 1 in mask.
60bool ITSession::InitIT(uint32_t bits7_0)
61{
62    ITCounter = CountITSize(Bits32(bits7_0, 3, 0));
63    if (ITCounter == 0)
64        return false;
65
66    // A8.6.50 IT
67    unsigned short FirstCond = Bits32(bits7_0, 7, 4);
68    if (FirstCond == 0xF)
69    {
70        printf("Encoding error: IT FirstCond '1111'\n");
71        return false;
72    }
73    if (FirstCond == 0xE && ITCounter != 1)
74    {
75        printf("Encoding error: IT FirstCond '1110' && Mask != '1000'\n");
76        return false;
77    }
78
79    ITState = bits7_0;
80    return true;
81}
82
83// Update ITState if necessary.
84void ITSession::ITAdvance()
85{
86    //assert(ITCounter);
87    --ITCounter;
88    if (ITCounter == 0)
89        ITState = 0;
90    else
91    {
92        unsigned short NewITState4_0 = Bits32(ITState, 4, 0) << 1;
93        SetBits32(ITState, 4, 0, NewITState4_0);
94    }
95}
96
97// Return true if we're inside an IT Block.
98bool ITSession::InITBlock()
99{
100    return ITCounter != 0;
101}
102
103// Return true if we're the last instruction inside an IT Block.
104bool ITSession::LastInITBlock()
105{
106    return ITCounter == 1;
107}
108
109// Get condition bits for the current thumb instruction.
110uint32_t ITSession::GetCond()
111{
112    if (InITBlock())
113        return Bits32(ITState, 7, 4);
114    else
115        return COND_AL;
116}
117
118// ARM constants used during decoding
119#define REG_RD          0
120#define LDM_REGLIST     1
121#define SP_REG          13
122#define LR_REG          14
123#define PC_REG          15
124#define PC_REGLIST_BIT  0x8000
125
126#define ARMv4     (1u << 0)
127#define ARMv4T    (1u << 1)
128#define ARMv5T    (1u << 2)
129#define ARMv5TE   (1u << 3)
130#define ARMv5TEJ  (1u << 4)
131#define ARMv6     (1u << 5)
132#define ARMv6K    (1u << 6)
133#define ARMv6T2   (1u << 7)
134#define ARMv7     (1u << 8)
135#define ARMv7S    (1u << 9)
136#define ARMv8     (1u << 10)
137#define ARMvAll   (0xffffffffu)
138
139#define ARMV4T_ABOVE  (ARMv4T|ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
140#define ARMV5_ABOVE   (ARMv5T|ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
141#define ARMV5TE_ABOVE (ARMv5TE|ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
142#define ARMV5J_ABOVE  (ARMv5TEJ|ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
143#define ARMV6_ABOVE   (ARMv6|ARMv6K|ARMv6T2|ARMv7|ARMv7S|ARMv8)
144#define ARMV6T2_ABOVE (ARMv6T2|ARMv7|ARMv7S|ARMv8)
145#define ARMV7_ABOVE   (ARMv7|ARMv7S|ARMv8)
146
147#define No_VFP  0
148#define VFPv1   (1u << 1)
149#define VFPv2   (1u << 2)
150#define VFPv3   (1u << 3)
151#define AdvancedSIMD (1u << 4)
152
153#define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
154#define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
155#define VFPv2v3     (VFPv2 | VFPv3)
156
157//----------------------------------------------------------------------
158//
159// EmulateInstructionARM implementation
160//
161//----------------------------------------------------------------------
162
163void
164EmulateInstructionARM::Initialize ()
165{
166    PluginManager::RegisterPlugin (GetPluginNameStatic (),
167                                   GetPluginDescriptionStatic (),
168                                   CreateInstance);
169}
170
171void
172EmulateInstructionARM::Terminate ()
173{
174    PluginManager::UnregisterPlugin (CreateInstance);
175}
176
177const char *
178EmulateInstructionARM::GetPluginNameStatic ()
179{
180    return "lldb.emulate-instruction.arm";
181}
182
183const char *
184EmulateInstructionARM::GetPluginDescriptionStatic ()
185{
186    return "Emulate instructions for the ARM architecture.";
187}
188
189EmulateInstruction *
190EmulateInstructionARM::CreateInstance (const ArchSpec &arch, InstructionType inst_type)
191{
192    if (EmulateInstructionARM::SupportsEmulatingIntructionsOfTypeStatic(inst_type))
193    {
194        if (arch.GetTriple().getArch() == llvm::Triple::arm)
195        {
196            STD_UNIQUE_PTR(EmulateInstructionARM) emulate_insn_ap (new EmulateInstructionARM (arch));
197
198            if (emulate_insn_ap.get())
199                return emulate_insn_ap.release();
200        }
201        else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
202        {
203            STD_UNIQUE_PTR(EmulateInstructionARM) emulate_insn_ap (new EmulateInstructionARM (arch));
204
205            if (emulate_insn_ap.get())
206                return emulate_insn_ap.release();
207        }
208    }
209
210    return NULL;
211}
212
213bool
214EmulateInstructionARM::SetTargetTriple (const ArchSpec &arch)
215{
216    if (arch.GetTriple().getArch () == llvm::Triple::arm)
217        return true;
218    else if (arch.GetTriple().getArch () == llvm::Triple::thumb)
219        return true;
220
221    return false;
222}
223
224// Write "bits (32) UNKNOWN" to memory address "address".  Helper function for many ARM instructions.
225bool
226EmulateInstructionARM::WriteBits32UnknownToMemory (addr_t address)
227{
228    EmulateInstruction::Context context;
229    context.type = EmulateInstruction::eContextWriteMemoryRandomBits;
230    context.SetNoArgs ();
231
232    uint32_t random_data = rand ();
233    const uint32_t addr_byte_size = GetAddressByteSize();
234
235    if (!MemAWrite (context, address, random_data, addr_byte_size))
236        return false;
237
238    return true;
239}
240
241// Write "bits (32) UNKNOWN" to register n.  Helper function for many ARM instructions.
242bool
243EmulateInstructionARM::WriteBits32Unknown (int n)
244{
245    EmulateInstruction::Context context;
246    context.type = EmulateInstruction::eContextWriteRegisterRandomBits;
247    context.SetNoArgs ();
248
249    bool success;
250    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
251
252    if (!success)
253        return false;
254
255    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
256        return false;
257
258    return true;
259}
260
261bool
262EmulateInstructionARM::GetRegisterInfo (uint32_t reg_kind, uint32_t reg_num, RegisterInfo &reg_info)
263{
264    if (reg_kind == eRegisterKindGeneric)
265    {
266        switch (reg_num)
267        {
268            case LLDB_REGNUM_GENERIC_PC:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc; break;
269            case LLDB_REGNUM_GENERIC_SP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp; break;
270            case LLDB_REGNUM_GENERIC_FP:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_r7; break;
271            case LLDB_REGNUM_GENERIC_RA:    reg_kind = eRegisterKindDWARF; reg_num = dwarf_lr; break;
272            case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_cpsr; break;
273            default: return false;
274        }
275    }
276
277    if (reg_kind == eRegisterKindDWARF)
278        return GetARMDWARFRegisterInfo(reg_num, reg_info);
279    return false;
280}
281
282uint32_t
283EmulateInstructionARM::GetFramePointerRegisterNumber () const
284{
285    if (m_opcode_mode == eModeThumb)
286    {
287        switch (m_arch.GetTriple().getOS())
288        {
289            case llvm::Triple::Darwin:
290            case llvm::Triple::MacOSX:
291            case llvm::Triple::IOS:
292                return 7;
293            default:
294                break;
295        }
296    }
297    return 11;
298}
299
300uint32_t
301EmulateInstructionARM::GetFramePointerDWARFRegisterNumber () const
302{
303    if (m_opcode_mode == eModeThumb)
304    {
305        switch (m_arch.GetTriple().getOS())
306        {
307            case llvm::Triple::Darwin:
308            case llvm::Triple::MacOSX:
309            case llvm::Triple::IOS:
310                return dwarf_r7;
311            default:
312                break;
313        }
314    }
315    return dwarf_r11;
316}
317
318// Push Multiple Registers stores multiple registers to the stack, storing to
319// consecutive memory locations ending just below the address in SP, and updates
320// SP to point to the start of the stored data.
321bool
322EmulateInstructionARM::EmulatePUSH (const uint32_t opcode, const ARMEncoding encoding)
323{
324#if 0
325    // ARM pseudo code...
326    if (ConditionPassed())
327    {
328        EncodingSpecificOperations();
329        NullCheckIfThumbEE(13);
330        address = SP - 4*BitCount(registers);
331
332        for (i = 0 to 14)
333        {
334            if (registers<i> == '1')
335            {
336                if i == 13 && i != LowestSetBit(registers) // Only possible for encoding A1
337                    MemA[address,4] = bits(32) UNKNOWN;
338                else
339                    MemA[address,4] = R[i];
340                address = address + 4;
341            }
342        }
343
344        if (registers<15> == '1') // Only possible for encoding A1 or A2
345            MemA[address,4] = PCStoreValue();
346
347        SP = SP - 4*BitCount(registers);
348    }
349#endif
350
351    bool conditional = false;
352    bool success = false;
353    if (ConditionPassed(opcode, &conditional))
354    {
355        const uint32_t addr_byte_size = GetAddressByteSize();
356        const addr_t sp = ReadCoreReg (SP_REG, &success);
357        if (!success)
358            return false;
359        uint32_t registers = 0;
360        uint32_t Rt; // the source register
361        switch (encoding) {
362        case eEncodingT1:
363            registers = Bits32(opcode, 7, 0);
364            // The M bit represents LR.
365            if (Bit32(opcode, 8))
366                registers |= (1u << 14);
367            // if BitCount(registers) < 1 then UNPREDICTABLE;
368            if (BitCount(registers) < 1)
369                return false;
370            break;
371        case eEncodingT2:
372            // Ignore bits 15 & 13.
373            registers = Bits32(opcode, 15, 0) & ~0xa000;
374            // if BitCount(registers) < 2 then UNPREDICTABLE;
375            if (BitCount(registers) < 2)
376                return false;
377            break;
378        case eEncodingT3:
379            Rt = Bits32(opcode, 15, 12);
380            // if BadReg(t) then UNPREDICTABLE;
381            if (BadReg(Rt))
382                return false;
383            registers = (1u << Rt);
384            break;
385        case eEncodingA1:
386            registers = Bits32(opcode, 15, 0);
387            // Instead of return false, let's handle the following case as well,
388            // which amounts to pushing one reg onto the full descending stacks.
389            // if BitCount(register_list) < 2 then SEE STMDB / STMFD;
390            break;
391        case eEncodingA2:
392            Rt = Bits32(opcode, 15, 12);
393            // if t == 13 then UNPREDICTABLE;
394            if (Rt == dwarf_sp)
395                return false;
396            registers = (1u << Rt);
397            break;
398        default:
399            return false;
400        }
401        addr_t sp_offset = addr_byte_size * BitCount (registers);
402        addr_t addr = sp - sp_offset;
403        uint32_t i;
404
405        EmulateInstruction::Context context;
406        if (conditional)
407            context.type = EmulateInstruction::eContextRegisterStore;
408        else
409            context.type = EmulateInstruction::eContextPushRegisterOnStack;
410        RegisterInfo reg_info;
411        RegisterInfo sp_reg;
412        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
413        for (i=0; i<15; ++i)
414        {
415            if (BitIsSet (registers, i))
416            {
417                GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, reg_info);
418                context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
419                uint32_t reg_value = ReadCoreReg(i, &success);
420                if (!success)
421                    return false;
422                if (!MemAWrite (context, addr, reg_value, addr_byte_size))
423                    return false;
424                addr += addr_byte_size;
425            }
426        }
427
428        if (BitIsSet (registers, 15))
429        {
430            GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, reg_info);
431            context.SetRegisterToRegisterPlusOffset (reg_info, sp_reg, addr - sp);
432            const uint32_t pc = ReadCoreReg(PC_REG, &success);
433            if (!success)
434                return false;
435            if (!MemAWrite (context, addr, pc, addr_byte_size))
436                return false;
437        }
438
439        context.type = EmulateInstruction::eContextAdjustStackPointer;
440        context.SetImmediateSigned (-sp_offset);
441
442        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
443            return false;
444    }
445    return true;
446}
447
448// Pop Multiple Registers loads multiple registers from the stack, loading from
449// consecutive memory locations staring at the address in SP, and updates
450// SP to point just above the loaded data.
451bool
452EmulateInstructionARM::EmulatePOP (const uint32_t opcode, const ARMEncoding encoding)
453{
454#if 0
455    // ARM pseudo code...
456    if (ConditionPassed())
457    {
458        EncodingSpecificOperations(); NullCheckIfThumbEE(13);
459        address = SP;
460        for i = 0 to 14
461            if registers<i> == '1' then
462                R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4]; address = address + 4;
463        if registers<15> == '1' then
464            if UnalignedAllowed then
465                LoadWritePC(MemU[address,4]);
466            else
467                LoadWritePC(MemA[address,4]);
468        if registers<13> == '0' then SP = SP + 4*BitCount(registers);
469        if registers<13> == '1' then SP = bits(32) UNKNOWN;
470    }
471#endif
472
473    bool success = false;
474
475    bool conditional = false;
476    if (ConditionPassed(opcode, &conditional))
477    {
478        const uint32_t addr_byte_size = GetAddressByteSize();
479        const addr_t sp = ReadCoreReg (SP_REG, &success);
480        if (!success)
481            return false;
482        uint32_t registers = 0;
483        uint32_t Rt; // the destination register
484        switch (encoding) {
485        case eEncodingT1:
486            registers = Bits32(opcode, 7, 0);
487            // The P bit represents PC.
488            if (Bit32(opcode, 8))
489                registers |= (1u << 15);
490            // if BitCount(registers) < 1 then UNPREDICTABLE;
491            if (BitCount(registers) < 1)
492                return false;
493            break;
494        case eEncodingT2:
495            // Ignore bit 13.
496            registers = Bits32(opcode, 15, 0) & ~0x2000;
497            // if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
498            if (BitCount(registers) < 2 || (Bit32(opcode, 15) && Bit32(opcode, 14)))
499                return false;
500            // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
501            if (BitIsSet(registers, 15) && InITBlock() && !LastInITBlock())
502                return false;
503            break;
504        case eEncodingT3:
505            Rt = Bits32(opcode, 15, 12);
506            // if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
507            if (Rt == 13)
508                return false;
509            if (Rt == 15 && InITBlock() && !LastInITBlock())
510                return false;
511            registers = (1u << Rt);
512            break;
513        case eEncodingA1:
514            registers = Bits32(opcode, 15, 0);
515            // Instead of return false, let's handle the following case as well,
516            // which amounts to popping one reg from the full descending stacks.
517            // if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD;
518
519            // if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE;
520            if (BitIsSet(opcode, 13) && ArchVersion() >= ARMv7)
521                return false;
522            break;
523        case eEncodingA2:
524            Rt = Bits32(opcode, 15, 12);
525            // if t == 13 then UNPREDICTABLE;
526            if (Rt == dwarf_sp)
527                return false;
528            registers = (1u << Rt);
529            break;
530        default:
531            return false;
532        }
533        addr_t sp_offset = addr_byte_size * BitCount (registers);
534        addr_t addr = sp;
535        uint32_t i, data;
536
537        EmulateInstruction::Context context;
538        if (conditional)
539            context.type = EmulateInstruction::eContextRegisterLoad;
540        else
541            context.type = EmulateInstruction::eContextPopRegisterOffStack;
542
543        RegisterInfo sp_reg;
544        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
545
546        for (i=0; i<15; ++i)
547        {
548            if (BitIsSet (registers, i))
549            {
550                context.SetRegisterPlusOffset (sp_reg, addr - sp);
551                data = MemARead(context, addr, 4, 0, &success);
552                if (!success)
553                    return false;
554                if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_r0 + i, data))
555                    return false;
556                addr += addr_byte_size;
557            }
558        }
559
560        if (BitIsSet (registers, 15))
561        {
562            context.SetRegisterPlusOffset (sp_reg, addr - sp);
563            data = MemARead(context, addr, 4, 0, &success);
564            if (!success)
565                return false;
566            // In ARMv5T and above, this is an interworking branch.
567            if (!LoadWritePC(context, data))
568                return false;
569            //addr += addr_byte_size;
570        }
571
572        context.type = EmulateInstruction::eContextAdjustStackPointer;
573        context.SetImmediateSigned (sp_offset);
574
575        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
576            return false;
577    }
578    return true;
579}
580
581// Set r7 or ip to point to saved value residing within the stack.
582// ADD (SP plus immediate)
583bool
584EmulateInstructionARM::EmulateADDRdSPImm (const uint32_t opcode, const ARMEncoding encoding)
585{
586#if 0
587    // ARM pseudo code...
588    if (ConditionPassed())
589    {
590        EncodingSpecificOperations();
591        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
592        if d == 15 then
593           ALUWritePC(result); // setflags is always FALSE here
594        else
595            R[d] = result;
596            if setflags then
597                APSR.N = result<31>;
598                APSR.Z = IsZeroBit(result);
599                APSR.C = carry;
600                APSR.V = overflow;
601    }
602#endif
603
604    bool success = false;
605
606    if (ConditionPassed(opcode))
607    {
608        const addr_t sp = ReadCoreReg (SP_REG, &success);
609        if (!success)
610            return false;
611        uint32_t Rd; // the destination register
612        uint32_t imm32;
613        switch (encoding) {
614        case eEncodingT1:
615            Rd = 7;
616            imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32)
617            break;
618        case eEncodingA1:
619            Rd = Bits32(opcode, 15, 12);
620            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
621            break;
622        default:
623            return false;
624        }
625        addr_t sp_offset = imm32;
626        addr_t addr = sp + sp_offset; // a pointer to the stack area
627
628        EmulateInstruction::Context context;
629        context.type = eContextSetFramePointer;
630        RegisterInfo sp_reg;
631        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
632        context.SetRegisterPlusOffset (sp_reg, sp_offset);
633
634        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, addr))
635            return false;
636    }
637    return true;
638}
639
640// Set r7 or ip to the current stack pointer.
641// MOV (register)
642bool
643EmulateInstructionARM::EmulateMOVRdSP (const uint32_t opcode, const ARMEncoding encoding)
644{
645#if 0
646    // ARM pseudo code...
647    if (ConditionPassed())
648    {
649        EncodingSpecificOperations();
650        result = R[m];
651        if d == 15 then
652            ALUWritePC(result); // setflags is always FALSE here
653        else
654            R[d] = result;
655            if setflags then
656                APSR.N = result<31>;
657                APSR.Z = IsZeroBit(result);
658                // APSR.C unchanged
659                // APSR.V unchanged
660    }
661#endif
662
663    bool success = false;
664
665    if (ConditionPassed(opcode))
666    {
667        const addr_t sp = ReadCoreReg (SP_REG, &success);
668        if (!success)
669            return false;
670        uint32_t Rd; // the destination register
671        switch (encoding) {
672        case eEncodingT1:
673            Rd = 7;
674            break;
675        case eEncodingA1:
676            Rd = 12;
677            break;
678        default:
679            return false;
680        }
681
682        EmulateInstruction::Context context;
683        if (Rd == GetFramePointerRegisterNumber())
684            context.type = EmulateInstruction::eContextSetFramePointer;
685        else
686            context.type = EmulateInstruction::eContextRegisterPlusOffset;
687        RegisterInfo sp_reg;
688        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
689        context.SetRegisterPlusOffset (sp_reg, 0);
690
691        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rd, sp))
692            return false;
693    }
694    return true;
695}
696
697// Move from high register (r8-r15) to low register (r0-r7).
698// MOV (register)
699bool
700EmulateInstructionARM::EmulateMOVLowHigh (const uint32_t opcode, const ARMEncoding encoding)
701{
702    return EmulateMOVRdRm (opcode, encoding);
703}
704
705// Move from register to register.
706// MOV (register)
707bool
708EmulateInstructionARM::EmulateMOVRdRm (const uint32_t opcode, const ARMEncoding encoding)
709{
710#if 0
711    // ARM pseudo code...
712    if (ConditionPassed())
713    {
714        EncodingSpecificOperations();
715        result = R[m];
716        if d == 15 then
717            ALUWritePC(result); // setflags is always FALSE here
718        else
719            R[d] = result;
720            if setflags then
721                APSR.N = result<31>;
722                APSR.Z = IsZeroBit(result);
723                // APSR.C unchanged
724                // APSR.V unchanged
725    }
726#endif
727
728    bool success = false;
729
730    if (ConditionPassed(opcode))
731    {
732        uint32_t Rm; // the source register
733        uint32_t Rd; // the destination register
734        bool setflags;
735        switch (encoding) {
736        case eEncodingT1:
737            Rd = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
738            Rm = Bits32(opcode, 6, 3);
739            setflags = false;
740            if (Rd == 15 && InITBlock() && !LastInITBlock())
741                return false;
742            break;
743        case eEncodingT2:
744            Rd = Bits32(opcode, 2, 0);
745            Rm = Bits32(opcode, 5, 3);
746            setflags = true;
747            if (InITBlock())
748                return false;
749            break;
750        case eEncodingT3:
751            Rd = Bits32(opcode, 11, 8);
752            Rm = Bits32(opcode, 3, 0);
753            setflags = BitIsSet(opcode, 20);
754            // if setflags && (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
755            if (setflags && (BadReg(Rd) || BadReg(Rm)))
756                return false;
757            // if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE;
758            if (!setflags && (Rd == 15 || Rm == 15 || (Rd == 13 && Rm == 13)))
759                return false;
760            break;
761        case eEncodingA1:
762            Rd = Bits32(opcode, 15, 12);
763            Rm = Bits32(opcode, 3, 0);
764            setflags = BitIsSet(opcode, 20);
765
766            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
767            if (Rd == 15 && setflags)
768                return EmulateSUBSPcLrEtc (opcode, encoding);
769            break;
770        default:
771            return false;
772        }
773        uint32_t result = ReadCoreReg(Rm, &success);
774        if (!success)
775            return false;
776
777        // The context specifies that Rm is to be moved into Rd.
778        EmulateInstruction::Context context;
779        context.type = EmulateInstruction::eContextRegisterLoad;
780        RegisterInfo dwarf_reg;
781        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
782        context.SetRegister (dwarf_reg);
783
784        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags))
785            return false;
786    }
787    return true;
788}
789
790// Move (immediate) writes an immediate value to the destination register.  It
791// can optionally update the condition flags based on the value.
792// MOV (immediate)
793bool
794EmulateInstructionARM::EmulateMOVRdImm (const uint32_t opcode, const ARMEncoding encoding)
795{
796#if 0
797    // ARM pseudo code...
798    if (ConditionPassed())
799    {
800        EncodingSpecificOperations();
801        result = imm32;
802        if d == 15 then         // Can only occur for ARM encoding
803            ALUWritePC(result); // setflags is always FALSE here
804        else
805            R[d] = result;
806            if setflags then
807                APSR.N = result<31>;
808                APSR.Z = IsZeroBit(result);
809                APSR.C = carry;
810                // APSR.V unchanged
811    }
812#endif
813
814    if (ConditionPassed(opcode))
815    {
816        uint32_t Rd; // the destination register
817        uint32_t imm32; // the immediate value to be written to Rd
818        uint32_t carry = 0; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C.
819                            // for setflags == false, this value is a don't care
820                            // initialized to 0 to silence the static analyzer
821        bool setflags;
822        switch (encoding) {
823            case eEncodingT1:
824                Rd = Bits32(opcode, 10, 8);
825                setflags = !InITBlock();
826                imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
827                carry = APSR_C;
828
829                break;
830
831            case eEncodingT2:
832                Rd = Bits32(opcode, 11, 8);
833                setflags = BitIsSet(opcode, 20);
834                imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
835                if (BadReg(Rd))
836                  return false;
837
838                break;
839
840            case eEncodingT3:
841            {
842                // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:i:imm3:imm8, 32);
843                Rd = Bits32 (opcode, 11, 8);
844                setflags = false;
845                uint32_t imm4 = Bits32 (opcode, 19, 16);
846                uint32_t imm3 = Bits32 (opcode, 14, 12);
847                uint32_t i = Bit32 (opcode, 26);
848                uint32_t imm8 = Bits32 (opcode, 7, 0);
849                imm32 = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
850
851                // if BadReg(d) then UNPREDICTABLE;
852                if (BadReg (Rd))
853                    return false;
854            }
855                break;
856
857            case eEncodingA1:
858                // d = UInt(Rd); setflags = (S == �1�); (imm32, carry) = ARMExpandImm_C(imm12, APSR.C);
859                Rd = Bits32 (opcode, 15, 12);
860                setflags = BitIsSet (opcode, 20);
861                imm32 = ARMExpandImm_C (opcode, APSR_C, carry);
862
863                // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
864                if ((Rd == 15) && setflags)
865                    return EmulateSUBSPcLrEtc (opcode, encoding);
866
867                break;
868
869            case eEncodingA2:
870            {
871                // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm4:imm12, 32);
872                Rd = Bits32 (opcode, 15, 12);
873                setflags = false;
874                uint32_t imm4 = Bits32 (opcode, 19, 16);
875                uint32_t imm12 = Bits32 (opcode, 11, 0);
876                imm32 = (imm4 << 12) | imm12;
877
878                // if d == 15 then UNPREDICTABLE;
879                if (Rd == 15)
880                    return false;
881            }
882                break;
883
884            default:
885                return false;
886        }
887        uint32_t result = imm32;
888
889        // The context specifies that an immediate is to be moved into Rd.
890        EmulateInstruction::Context context;
891        context.type = EmulateInstruction::eContextImmediate;
892        context.SetNoArgs ();
893
894        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
895            return false;
896    }
897    return true;
898}
899
900// MUL multiplies two register values.  The least significant 32 bits of the result are written to the destination
901// register.  These 32 bits do not depend on whether the source register values are considered to be signed values or
902// unsigned values.
903//
904// Optionally, it can update the condition flags based on the result.  In the Thumb instruction set, this option is
905// limited to only a few forms of the instruction.
906bool
907EmulateInstructionARM::EmulateMUL (const uint32_t opcode, const ARMEncoding encoding)
908{
909#if 0
910    if ConditionPassed() then
911        EncodingSpecificOperations();
912        operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
913        operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
914        result = operand1 * operand2;
915        R[d] = result<31:0>;
916        if setflags then
917            APSR.N = result<31>;
918            APSR.Z = IsZeroBit(result);
919            if ArchVersion() == 4 then
920                APSR.C = bit UNKNOWN;
921            // else APSR.C unchanged
922            // APSR.V always unchanged
923#endif
924
925    if (ConditionPassed(opcode))
926    {
927        uint32_t d;
928        uint32_t n;
929        uint32_t m;
930        bool setflags;
931
932        // EncodingSpecificOperations();
933        switch (encoding)
934        {
935            case eEncodingT1:
936                // d = UInt(Rdm); n = UInt(Rn); m = UInt(Rdm); setflags = !InITBlock();
937                d = Bits32 (opcode, 2, 0);
938                n = Bits32 (opcode, 5, 3);
939                m = Bits32 (opcode, 2, 0);
940                setflags = !InITBlock();
941
942                // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
943                if ((ArchVersion() < ARMv6) && (d == n))
944                    return false;
945
946                break;
947
948            case eEncodingT2:
949                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = FALSE;
950                d = Bits32 (opcode, 11, 8);
951                n = Bits32 (opcode, 19, 16);
952                m = Bits32 (opcode, 3, 0);
953                setflags = false;
954
955                // if BadReg(d) || BadReg(n) || BadReg(m) then UNPREDICTABLE;
956                if (BadReg (d) || BadReg (n) || BadReg (m))
957                    return false;
958
959                break;
960
961            case eEncodingA1:
962                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == '1');
963                d = Bits32 (opcode, 19, 16);
964                n = Bits32 (opcode, 3, 0);
965                m = Bits32 (opcode, 11, 8);
966                setflags = BitIsSet (opcode, 20);
967
968                // if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
969                if ((d == 15) ||  (n == 15) || (m == 15))
970                    return false;
971
972                // if ArchVersion() < 6 && d == n then UNPREDICTABLE;
973                if ((ArchVersion() < ARMv6) && (d == n))
974                    return false;
975
976                break;
977
978            default:
979                return false;
980        }
981
982        bool success = false;
983
984        // operand1 = SInt(R[n]); // operand1 = UInt(R[n]) produces the same final results
985        uint64_t operand1 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
986        if (!success)
987            return false;
988
989        // operand2 = SInt(R[m]); // operand2 = UInt(R[m]) produces the same final results
990        uint64_t operand2 = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
991        if (!success)
992            return false;
993
994        // result = operand1 * operand2;
995        uint64_t result = operand1 * operand2;
996
997        // R[d] = result<31:0>;
998        RegisterInfo op1_reg;
999        RegisterInfo op2_reg;
1000        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, op1_reg);
1001        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, op2_reg);
1002
1003        EmulateInstruction::Context context;
1004        context.type = eContextArithmetic;
1005        context.SetRegisterRegisterOperands (op1_reg, op2_reg);
1006
1007        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (0x0000ffff & result)))
1008            return false;
1009
1010        // if setflags then
1011        if (setflags)
1012        {
1013            // APSR.N = result<31>;
1014            // APSR.Z = IsZeroBit(result);
1015            m_new_inst_cpsr = m_opcode_cpsr;
1016            SetBit32 (m_new_inst_cpsr, CPSR_N_POS, Bit32 (result, 31));
1017            SetBit32 (m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
1018            if (m_new_inst_cpsr != m_opcode_cpsr)
1019            {
1020                if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
1021                    return false;
1022            }
1023
1024            // if ArchVersion() == 4 then
1025                // APSR.C = bit UNKNOWN;
1026        }
1027    }
1028    return true;
1029}
1030
1031// Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register.
1032// It can optionally update the condition flags based on the value.
1033bool
1034EmulateInstructionARM::EmulateMVNImm (const uint32_t opcode, const ARMEncoding encoding)
1035{
1036#if 0
1037    // ARM pseudo code...
1038    if (ConditionPassed())
1039    {
1040        EncodingSpecificOperations();
1041        result = NOT(imm32);
1042        if d == 15 then         // Can only occur for ARM encoding
1043            ALUWritePC(result); // setflags is always FALSE here
1044        else
1045            R[d] = result;
1046            if setflags then
1047                APSR.N = result<31>;
1048                APSR.Z = IsZeroBit(result);
1049                APSR.C = carry;
1050                // APSR.V unchanged
1051    }
1052#endif
1053
1054    if (ConditionPassed(opcode))
1055    {
1056        uint32_t Rd; // the destination register
1057        uint32_t imm32; // the output after ThumbExpandImm_C or ARMExpandImm_C
1058        uint32_t carry; // the carry bit after ThumbExpandImm_C or ARMExpandImm_C
1059        bool setflags;
1060        switch (encoding) {
1061        case eEncodingT1:
1062            Rd = Bits32(opcode, 11, 8);
1063            setflags = BitIsSet(opcode, 20);
1064            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry);
1065            break;
1066        case eEncodingA1:
1067            Rd = Bits32(opcode, 15, 12);
1068            setflags = BitIsSet(opcode, 20);
1069            imm32 = ARMExpandImm_C(opcode, APSR_C, carry);
1070
1071            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1072            if (Rd == 15 && setflags)
1073                return EmulateSUBSPcLrEtc (opcode, encoding);
1074            break;
1075        default:
1076            return false;
1077        }
1078        uint32_t result = ~imm32;
1079
1080        // The context specifies that an immediate is to be moved into Rd.
1081        EmulateInstruction::Context context;
1082        context.type = EmulateInstruction::eContextImmediate;
1083        context.SetNoArgs ();
1084
1085        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1086            return false;
1087    }
1088    return true;
1089}
1090
1091// Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register.
1092// It can optionally update the condition flags based on the result.
1093bool
1094EmulateInstructionARM::EmulateMVNReg (const uint32_t opcode, const ARMEncoding encoding)
1095{
1096#if 0
1097    // ARM pseudo code...
1098    if (ConditionPassed())
1099    {
1100        EncodingSpecificOperations();
1101        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
1102        result = NOT(shifted);
1103        if d == 15 then         // Can only occur for ARM encoding
1104            ALUWritePC(result); // setflags is always FALSE here
1105        else
1106            R[d] = result;
1107            if setflags then
1108                APSR.N = result<31>;
1109                APSR.Z = IsZeroBit(result);
1110                APSR.C = carry;
1111                // APSR.V unchanged
1112    }
1113#endif
1114
1115    if (ConditionPassed(opcode))
1116    {
1117        uint32_t Rm; // the source register
1118        uint32_t Rd; // the destination register
1119        ARM_ShifterType shift_t;
1120        uint32_t shift_n; // the shift applied to the value read from Rm
1121        bool setflags;
1122        uint32_t carry; // the carry bit after the shift operation
1123        switch (encoding) {
1124        case eEncodingT1:
1125            Rd = Bits32(opcode, 2, 0);
1126            Rm = Bits32(opcode, 5, 3);
1127            setflags = !InITBlock();
1128            shift_t = SRType_LSL;
1129            shift_n = 0;
1130            if (InITBlock())
1131                return false;
1132            break;
1133        case eEncodingT2:
1134            Rd = Bits32(opcode, 11, 8);
1135            Rm = Bits32(opcode, 3, 0);
1136            setflags = BitIsSet(opcode, 20);
1137            shift_n = DecodeImmShiftThumb(opcode, shift_t);
1138            // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
1139            if (BadReg(Rd) || BadReg(Rm))
1140                return false;
1141            break;
1142        case eEncodingA1:
1143            Rd = Bits32(opcode, 15, 12);
1144            Rm = Bits32(opcode, 3, 0);
1145            setflags = BitIsSet(opcode, 20);
1146            shift_n = DecodeImmShiftARM(opcode, shift_t);
1147            break;
1148        default:
1149            return false;
1150        }
1151        bool success = false;
1152        uint32_t value = ReadCoreReg(Rm, &success);
1153        if (!success)
1154            return false;
1155
1156        uint32_t shifted = Shift_C(value, shift_t, shift_n, APSR_C, carry, &success);
1157        if (!success)
1158            return false;
1159        uint32_t result = ~shifted;
1160
1161        // The context specifies that an immediate is to be moved into Rd.
1162        EmulateInstruction::Context context;
1163        context.type = EmulateInstruction::eContextImmediate;
1164        context.SetNoArgs ();
1165
1166        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
1167            return false;
1168    }
1169    return true;
1170}
1171
1172// PC relative immediate load into register, possibly followed by ADD (SP plus register).
1173// LDR (literal)
1174bool
1175EmulateInstructionARM::EmulateLDRRtPCRelative (const uint32_t opcode, const ARMEncoding encoding)
1176{
1177#if 0
1178    // ARM pseudo code...
1179    if (ConditionPassed())
1180    {
1181        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
1182        base = Align(PC,4);
1183        address = if add then (base + imm32) else (base - imm32);
1184        data = MemU[address,4];
1185        if t == 15 then
1186            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
1187        elsif UnalignedSupport() || address<1:0> = '00' then
1188            R[t] = data;
1189        else // Can only apply before ARMv7
1190            if CurrentInstrSet() == InstrSet_ARM then
1191                R[t] = ROR(data, 8*UInt(address<1:0>));
1192            else
1193                R[t] = bits(32) UNKNOWN;
1194    }
1195#endif
1196
1197    if (ConditionPassed(opcode))
1198    {
1199        bool success = false;
1200        const uint32_t pc = ReadCoreReg(PC_REG, &success);
1201        if (!success)
1202            return false;
1203
1204        // PC relative immediate load context
1205        EmulateInstruction::Context context;
1206        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1207        RegisterInfo pc_reg;
1208        GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
1209        context.SetRegisterPlusOffset (pc_reg, 0);
1210
1211        uint32_t Rt;    // the destination register
1212        uint32_t imm32; // immediate offset from the PC
1213        bool add;       // +imm32 or -imm32?
1214        addr_t base;    // the base address
1215        addr_t address; // the PC relative address
1216        uint32_t data;  // the literal data value from the PC relative load
1217        switch (encoding) {
1218        case eEncodingT1:
1219            Rt = Bits32(opcode, 10, 8);
1220            imm32 = Bits32(opcode, 7, 0) << 2; // imm32 = ZeroExtend(imm8:'00', 32);
1221            add = true;
1222            break;
1223        case eEncodingT2:
1224            Rt = Bits32(opcode, 15, 12);
1225            imm32 = Bits32(opcode, 11, 0) << 2; // imm32 = ZeroExtend(imm12, 32);
1226            add = BitIsSet(opcode, 23);
1227            if (Rt == 15 && InITBlock() && !LastInITBlock())
1228                return false;
1229            break;
1230        default:
1231            return false;
1232        }
1233
1234        base = Align(pc, 4);
1235        if (add)
1236            address = base + imm32;
1237        else
1238            address = base - imm32;
1239
1240        context.SetRegisterPlusOffset(pc_reg, address - base);
1241        data = MemURead(context, address, 4, 0, &success);
1242        if (!success)
1243            return false;
1244
1245        if (Rt == 15)
1246        {
1247            if (Bits32(address, 1, 0) == 0)
1248            {
1249                // In ARMv5T and above, this is an interworking branch.
1250                if (!LoadWritePC(context, data))
1251                    return false;
1252            }
1253            else
1254                return false;
1255        }
1256        else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
1257        {
1258            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
1259                return false;
1260        }
1261        else // We don't handle ARM for now.
1262            return false;
1263
1264    }
1265    return true;
1266}
1267
1268// An add operation to adjust the SP.
1269// ADD (SP plus immediate)
1270bool
1271EmulateInstructionARM::EmulateADDSPImm (const uint32_t opcode, const ARMEncoding encoding)
1272{
1273#if 0
1274    // ARM pseudo code...
1275    if (ConditionPassed())
1276    {
1277        EncodingSpecificOperations();
1278        (result, carry, overflow) = AddWithCarry(SP, imm32, '0');
1279        if d == 15 then // Can only occur for ARM encoding
1280            ALUWritePC(result); // setflags is always FALSE here
1281        else
1282            R[d] = result;
1283            if setflags then
1284                APSR.N = result<31>;
1285                APSR.Z = IsZeroBit(result);
1286                APSR.C = carry;
1287                APSR.V = overflow;
1288    }
1289#endif
1290
1291    bool success = false;
1292
1293    if (ConditionPassed(opcode))
1294    {
1295        const addr_t sp = ReadCoreReg (SP_REG, &success);
1296        if (!success)
1297            return false;
1298        uint32_t imm32; // the immediate operand
1299        uint32_t d;
1300        //bool setflags = false; // Add this back if/when support eEncodingT3 eEncodingA1
1301        switch (encoding)
1302        {
1303            case eEncodingT1:
1304                // d = UInt(Rd); setflags = FALSE; imm32 = ZeroExtend(imm8:'00', 32);
1305                d = Bits32 (opcode, 10, 8);
1306                imm32 = (Bits32 (opcode, 7, 0) << 2);
1307
1308                break;
1309
1310            case eEncodingT2:
1311                // d = 13; setflags = FALSE; imm32 = ZeroExtend(imm7:'00', 32);
1312                d = 13;
1313                imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1314
1315                break;
1316
1317            default:
1318                return false;
1319        }
1320        addr_t sp_offset = imm32;
1321        addr_t addr = sp + sp_offset; // the adjusted stack pointer value
1322
1323        EmulateInstruction::Context context;
1324        context.type = EmulateInstruction::eContextAdjustStackPointer;
1325        RegisterInfo sp_reg;
1326        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1327        context.SetRegisterPlusOffset (sp_reg, sp_offset);
1328
1329        if (d == 15)
1330        {
1331            if (!ALUWritePC (context, addr))
1332                return false;
1333        }
1334        else
1335        {
1336            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, addr))
1337                return false;
1338
1339            // Add this back if/when support eEncodingT3 eEncodingA1
1340            //if (setflags)
1341            //{
1342            //    APSR.N = result<31>;
1343            //    APSR.Z = IsZeroBit(result);
1344            //    APSR.C = carry;
1345            //    APSR.V = overflow;
1346            //}
1347        }
1348    }
1349    return true;
1350}
1351
1352// An add operation to adjust the SP.
1353// ADD (SP plus register)
1354bool
1355EmulateInstructionARM::EmulateADDSPRm (const uint32_t opcode, const ARMEncoding encoding)
1356{
1357#if 0
1358    // ARM pseudo code...
1359    if (ConditionPassed())
1360    {
1361        EncodingSpecificOperations();
1362        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
1363        (result, carry, overflow) = AddWithCarry(SP, shifted, '0');
1364        if d == 15 then
1365            ALUWritePC(result); // setflags is always FALSE here
1366        else
1367            R[d] = result;
1368            if setflags then
1369                APSR.N = result<31>;
1370                APSR.Z = IsZeroBit(result);
1371                APSR.C = carry;
1372                APSR.V = overflow;
1373    }
1374#endif
1375
1376    bool success = false;
1377
1378    if (ConditionPassed(opcode))
1379    {
1380        const addr_t sp = ReadCoreReg (SP_REG, &success);
1381        if (!success)
1382            return false;
1383        uint32_t Rm; // the second operand
1384        switch (encoding) {
1385        case eEncodingT2:
1386            Rm = Bits32(opcode, 6, 3);
1387            break;
1388        default:
1389            return false;
1390        }
1391        int32_t reg_value = ReadCoreReg(Rm, &success);
1392        if (!success)
1393            return false;
1394
1395        addr_t addr = (int32_t)sp + reg_value; // the adjusted stack pointer value
1396
1397        EmulateInstruction::Context context;
1398        context.type = eContextArithmetic;
1399        RegisterInfo sp_reg;
1400        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1401
1402        RegisterInfo other_reg;
1403        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, other_reg);
1404        context.SetRegisterRegisterOperands (sp_reg, other_reg);
1405
1406        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, addr))
1407            return false;
1408    }
1409    return true;
1410}
1411
1412// Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine
1413// at a PC-relative address, and changes instruction set from ARM to Thumb, or
1414// from Thumb to ARM.
1415// BLX (immediate)
1416bool
1417EmulateInstructionARM::EmulateBLXImmediate (const uint32_t opcode, const ARMEncoding encoding)
1418{
1419#if 0
1420    // ARM pseudo code...
1421    if (ConditionPassed())
1422    {
1423        EncodingSpecificOperations();
1424        if CurrentInstrSet() == InstrSet_ARM then
1425            LR = PC - 4;
1426        else
1427            LR = PC<31:1> : '1';
1428        if targetInstrSet == InstrSet_ARM then
1429            targetAddress = Align(PC,4) + imm32;
1430        else
1431            targetAddress = PC + imm32;
1432        SelectInstrSet(targetInstrSet);
1433        BranchWritePC(targetAddress);
1434    }
1435#endif
1436
1437    bool success = true;
1438
1439    if (ConditionPassed(opcode))
1440    {
1441        EmulateInstruction::Context context;
1442        context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1443        const uint32_t pc = ReadCoreReg(PC_REG, &success);
1444        if (!success)
1445            return false;
1446        addr_t lr; // next instruction address
1447        addr_t target; // target address
1448        int32_t imm32; // PC-relative offset
1449        switch (encoding) {
1450        case eEncodingT1:
1451            {
1452            lr = pc | 1u; // return address
1453            uint32_t S = Bit32(opcode, 26);
1454            uint32_t imm10 = Bits32(opcode, 25, 16);
1455            uint32_t J1 = Bit32(opcode, 13);
1456            uint32_t J2 = Bit32(opcode, 11);
1457            uint32_t imm11 = Bits32(opcode, 10, 0);
1458            uint32_t I1 = !(J1 ^ S);
1459            uint32_t I2 = !(J2 ^ S);
1460            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
1461            imm32 = llvm::SignExtend32<25>(imm25);
1462            target = pc + imm32;
1463            context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
1464            if (InITBlock() && !LastInITBlock())
1465                return false;
1466            break;
1467            }
1468        case eEncodingT2:
1469            {
1470            lr = pc | 1u; // return address
1471            uint32_t S = Bit32(opcode, 26);
1472            uint32_t imm10H = Bits32(opcode, 25, 16);
1473            uint32_t J1 = Bit32(opcode, 13);
1474            uint32_t J2 = Bit32(opcode, 11);
1475            uint32_t imm10L = Bits32(opcode, 10, 1);
1476            uint32_t I1 = !(J1 ^ S);
1477            uint32_t I2 = !(J2 ^ S);
1478            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10H << 12) | (imm10L << 2);
1479            imm32 = llvm::SignExtend32<25>(imm25);
1480            target = Align(pc, 4) + imm32;
1481            context.SetISAAndImmediateSigned (eModeARM, 4 + imm32);
1482            if (InITBlock() && !LastInITBlock())
1483                return false;
1484            break;
1485            }
1486        case eEncodingA1:
1487            lr = pc - 4; // return address
1488            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
1489            target = Align(pc, 4) + imm32;
1490            context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
1491            break;
1492        case eEncodingA2:
1493            lr = pc - 4; // return address
1494            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2 | Bits32(opcode, 24, 24) << 1);
1495            target = pc + imm32;
1496            context.SetISAAndImmediateSigned (eModeThumb, 8 + imm32);
1497            break;
1498        default:
1499            return false;
1500        }
1501        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1502            return false;
1503        if (!BranchWritePC(context, target))
1504            return false;
1505    }
1506    return true;
1507}
1508
1509// Branch with Link and Exchange (register) calls a subroutine at an address and
1510// instruction set specified by a register.
1511// BLX (register)
1512bool
1513EmulateInstructionARM::EmulateBLXRm (const uint32_t opcode, const ARMEncoding encoding)
1514{
1515#if 0
1516    // ARM pseudo code...
1517    if (ConditionPassed())
1518    {
1519        EncodingSpecificOperations();
1520        target = R[m];
1521        if CurrentInstrSet() == InstrSet_ARM then
1522            next_instr_addr = PC - 4;
1523            LR = next_instr_addr;
1524        else
1525            next_instr_addr = PC - 2;
1526            LR = next_instr_addr<31:1> : '1';
1527        BXWritePC(target);
1528    }
1529#endif
1530
1531    bool success = false;
1532
1533    if (ConditionPassed(opcode))
1534    {
1535        EmulateInstruction::Context context;
1536        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1537        const uint32_t pc = ReadCoreReg(PC_REG, &success);
1538        addr_t lr; // next instruction address
1539        if (!success)
1540            return false;
1541        uint32_t Rm; // the register with the target address
1542        switch (encoding) {
1543        case eEncodingT1:
1544            lr = (pc - 2) | 1u; // return address
1545            Rm = Bits32(opcode, 6, 3);
1546            // if m == 15 then UNPREDICTABLE;
1547            if (Rm == 15)
1548                return false;
1549            if (InITBlock() && !LastInITBlock())
1550                return false;
1551            break;
1552        case eEncodingA1:
1553            lr = pc - 4; // return address
1554            Rm = Bits32(opcode, 3, 0);
1555            // if m == 15 then UNPREDICTABLE;
1556            if (Rm == 15)
1557                return false;
1558            break;
1559        default:
1560            return false;
1561        }
1562        addr_t target = ReadCoreReg (Rm, &success);
1563        if (!success)
1564            return false;
1565        RegisterInfo dwarf_reg;
1566        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1567        context.SetRegister (dwarf_reg);
1568        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
1569            return false;
1570        if (!BXWritePC(context, target))
1571            return false;
1572    }
1573    return true;
1574}
1575
1576// Branch and Exchange causes a branch to an address and instruction set specified by a register.
1577bool
1578EmulateInstructionARM::EmulateBXRm (const uint32_t opcode, const ARMEncoding encoding)
1579{
1580#if 0
1581    // ARM pseudo code...
1582    if (ConditionPassed())
1583    {
1584        EncodingSpecificOperations();
1585        BXWritePC(R[m]);
1586    }
1587#endif
1588
1589    if (ConditionPassed(opcode))
1590    {
1591        EmulateInstruction::Context context;
1592        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1593        uint32_t Rm; // the register with the target address
1594        switch (encoding) {
1595        case eEncodingT1:
1596            Rm = Bits32(opcode, 6, 3);
1597            if (InITBlock() && !LastInITBlock())
1598                return false;
1599            break;
1600        case eEncodingA1:
1601            Rm = Bits32(opcode, 3, 0);
1602            break;
1603        default:
1604            return false;
1605        }
1606        bool success = false;
1607        addr_t target = ReadCoreReg (Rm, &success);
1608        if (!success)
1609            return false;
1610
1611        RegisterInfo dwarf_reg;
1612        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1613        context.SetRegister (dwarf_reg);
1614        if (!BXWritePC(context, target))
1615            return false;
1616    }
1617    return true;
1618}
1619
1620// Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an
1621// address and instruction set specified by a register as though it were a BX instruction.
1622//
1623// TODO: Emulate Jazelle architecture?
1624//       We currently assume that switching to Jazelle state fails, thus treating BXJ as a BX operation.
1625bool
1626EmulateInstructionARM::EmulateBXJRm (const uint32_t opcode, const ARMEncoding encoding)
1627{
1628#if 0
1629    // ARM pseudo code...
1630    if (ConditionPassed())
1631    {
1632        EncodingSpecificOperations();
1633        if JMCR.JE == '0' || CurrentInstrSet() == InstrSet_ThumbEE then
1634            BXWritePC(R[m]);
1635        else
1636            if JazelleAcceptsExecution() then
1637                SwitchToJazelleExecution();
1638            else
1639                SUBARCHITECTURE_DEFINED handler call;
1640    }
1641#endif
1642
1643    if (ConditionPassed(opcode))
1644    {
1645        EmulateInstruction::Context context;
1646        context.type = EmulateInstruction::eContextAbsoluteBranchRegister;
1647        uint32_t Rm; // the register with the target address
1648        switch (encoding) {
1649        case eEncodingT1:
1650            Rm = Bits32(opcode, 19, 16);
1651            if (BadReg(Rm))
1652                return false;
1653            if (InITBlock() && !LastInITBlock())
1654                return false;
1655            break;
1656        case eEncodingA1:
1657            Rm = Bits32(opcode, 3, 0);
1658            if (Rm == 15)
1659                return false;
1660            break;
1661        default:
1662            return false;
1663        }
1664        bool success = false;
1665        addr_t target = ReadCoreReg (Rm, &success);
1666        if (!success)
1667            return false;
1668
1669        RegisterInfo dwarf_reg;
1670        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, dwarf_reg);
1671        context.SetRegister (dwarf_reg);
1672        if (!BXWritePC(context, target))
1673            return false;
1674    }
1675    return true;
1676}
1677
1678// Set r7 to point to some ip offset.
1679// SUB (immediate)
1680bool
1681EmulateInstructionARM::EmulateSUBR7IPImm (const uint32_t opcode, const ARMEncoding encoding)
1682{
1683#if 0
1684    // ARM pseudo code...
1685    if (ConditionPassed())
1686    {
1687        EncodingSpecificOperations();
1688        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1689        if d == 15 then // Can only occur for ARM encoding
1690           ALUWritePC(result); // setflags is always FALSE here
1691        else
1692            R[d] = result;
1693            if setflags then
1694                APSR.N = result<31>;
1695                APSR.Z = IsZeroBit(result);
1696                APSR.C = carry;
1697                APSR.V = overflow;
1698    }
1699#endif
1700
1701    if (ConditionPassed(opcode))
1702    {
1703        bool success = false;
1704        const addr_t ip = ReadCoreReg (12, &success);
1705        if (!success)
1706            return false;
1707        uint32_t imm32;
1708        switch (encoding) {
1709        case eEncodingA1:
1710            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1711            break;
1712        default:
1713            return false;
1714        }
1715        addr_t ip_offset = imm32;
1716        addr_t addr = ip - ip_offset; // the adjusted ip value
1717
1718        EmulateInstruction::Context context;
1719        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1720        RegisterInfo dwarf_reg;
1721        GetRegisterInfo (eRegisterKindDWARF, dwarf_r12, dwarf_reg);
1722        context.SetRegisterPlusOffset (dwarf_reg, -ip_offset);
1723
1724        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r7, addr))
1725            return false;
1726    }
1727    return true;
1728}
1729
1730// Set ip to point to some stack offset.
1731// SUB (SP minus immediate)
1732bool
1733EmulateInstructionARM::EmulateSUBIPSPImm (const uint32_t opcode, const ARMEncoding encoding)
1734{
1735#if 0
1736    // ARM pseudo code...
1737    if (ConditionPassed())
1738    {
1739        EncodingSpecificOperations();
1740        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1741        if d == 15 then // Can only occur for ARM encoding
1742           ALUWritePC(result); // setflags is always FALSE here
1743        else
1744            R[d] = result;
1745            if setflags then
1746                APSR.N = result<31>;
1747                APSR.Z = IsZeroBit(result);
1748                APSR.C = carry;
1749                APSR.V = overflow;
1750    }
1751#endif
1752
1753    if (ConditionPassed(opcode))
1754    {
1755        bool success = false;
1756        const addr_t sp = ReadCoreReg (SP_REG, &success);
1757        if (!success)
1758            return false;
1759        uint32_t imm32;
1760        switch (encoding) {
1761        case eEncodingA1:
1762            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1763            break;
1764        default:
1765            return false;
1766        }
1767        addr_t sp_offset = imm32;
1768        addr_t addr = sp - sp_offset; // the adjusted stack pointer value
1769
1770        EmulateInstruction::Context context;
1771        context.type = EmulateInstruction::eContextRegisterPlusOffset;
1772        RegisterInfo dwarf_reg;
1773        GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, dwarf_reg);
1774        context.SetRegisterPlusOffset (dwarf_reg, -sp_offset);
1775
1776        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r12, addr))
1777            return false;
1778    }
1779    return true;
1780}
1781
1782// This instruction subtracts an immediate value from the SP value, and writes
1783// the result to the destination register.
1784//
1785// If Rd == 13 => A sub operation to adjust the SP -- allocate space for local storage.
1786bool
1787EmulateInstructionARM::EmulateSUBSPImm (const uint32_t opcode, const ARMEncoding encoding)
1788{
1789#if 0
1790    // ARM pseudo code...
1791    if (ConditionPassed())
1792    {
1793        EncodingSpecificOperations();
1794        (result, carry, overflow) = AddWithCarry(SP, NOT(imm32), '1');
1795        if d == 15 then        // Can only occur for ARM encoding
1796           ALUWritePC(result); // setflags is always FALSE here
1797        else
1798            R[d] = result;
1799            if setflags then
1800                APSR.N = result<31>;
1801                APSR.Z = IsZeroBit(result);
1802                APSR.C = carry;
1803                APSR.V = overflow;
1804    }
1805#endif
1806
1807    bool success = false;
1808    if (ConditionPassed(opcode))
1809    {
1810        const addr_t sp = ReadCoreReg (SP_REG, &success);
1811        if (!success)
1812            return false;
1813
1814        uint32_t Rd;
1815        bool setflags;
1816        uint32_t imm32;
1817        switch (encoding) {
1818        case eEncodingT1:
1819            Rd = 13;
1820            setflags = false;
1821            imm32 = ThumbImm7Scaled(opcode); // imm32 = ZeroExtend(imm7:'00', 32)
1822            break;
1823        case eEncodingT2:
1824            Rd = Bits32(opcode, 11, 8);
1825            setflags = BitIsSet(opcode, 20);
1826            imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
1827            if (Rd == 15 && setflags)
1828                return EmulateCMPImm(opcode, eEncodingT2);
1829            if (Rd == 15 && !setflags)
1830                return false;
1831            break;
1832        case eEncodingT3:
1833            Rd = Bits32(opcode, 11, 8);
1834            setflags = false;
1835            imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
1836            if (Rd == 15)
1837                return false;
1838            break;
1839        case eEncodingA1:
1840            Rd = Bits32(opcode, 15, 12);
1841            setflags = BitIsSet(opcode, 20);
1842            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
1843
1844            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
1845            if (Rd == 15 && setflags)
1846                return EmulateSUBSPcLrEtc (opcode, encoding);
1847            break;
1848        default:
1849            return false;
1850        }
1851        AddWithCarryResult res = AddWithCarry(sp, ~imm32, 1);
1852
1853        EmulateInstruction::Context context;
1854        if (Rd == 13)
1855        {
1856            uint64_t imm64 = imm32;  // Need to expand it to 64 bits before attempting to negate it, or the wrong
1857                                     // value gets passed down to context.SetImmediateSigned.
1858            context.type = EmulateInstruction::eContextAdjustStackPointer;
1859            context.SetImmediateSigned (-imm64); // the stack pointer offset
1860        }
1861        else
1862        {
1863            context.type = EmulateInstruction::eContextImmediate;
1864            context.SetNoArgs ();
1865        }
1866
1867        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
1868            return false;
1869    }
1870    return true;
1871}
1872
1873// A store operation to the stack that also updates the SP.
1874bool
1875EmulateInstructionARM::EmulateSTRRtSP (const uint32_t opcode, const ARMEncoding encoding)
1876{
1877#if 0
1878    // ARM pseudo code...
1879    if (ConditionPassed())
1880    {
1881        EncodingSpecificOperations();
1882        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
1883        address = if index then offset_addr else R[n];
1884        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
1885        if wback then R[n] = offset_addr;
1886    }
1887#endif
1888
1889    bool conditional = false;
1890    bool success = false;
1891    if (ConditionPassed(opcode, &conditional))
1892    {
1893        const uint32_t addr_byte_size = GetAddressByteSize();
1894        const addr_t sp = ReadCoreReg (SP_REG, &success);
1895        if (!success)
1896            return false;
1897        uint32_t Rt; // the source register
1898        uint32_t imm12;
1899        uint32_t Rn;  // This function assumes Rn is the SP, but we should verify that.
1900
1901        bool index;
1902        bool add;
1903        bool wback;
1904        switch (encoding) {
1905        case eEncodingA1:
1906            Rt = Bits32(opcode, 15, 12);
1907            imm12 = Bits32(opcode, 11, 0);
1908            Rn = Bits32 (opcode, 19, 16);
1909
1910            if (Rn != 13) // 13 is the SP reg on ARM.  Verify that Rn == SP.
1911                return false;
1912
1913            index = BitIsSet (opcode, 24);
1914            add = BitIsSet (opcode, 23);
1915            wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
1916
1917            if (wback && ((Rn == 15) || (Rn == Rt)))
1918                return false;
1919            break;
1920        default:
1921            return false;
1922        }
1923        addr_t offset_addr;
1924        if (add)
1925            offset_addr = sp + imm12;
1926        else
1927            offset_addr = sp - imm12;
1928
1929        addr_t addr;
1930        if (index)
1931            addr = offset_addr;
1932        else
1933            addr = sp;
1934
1935        EmulateInstruction::Context context;
1936        if (conditional)
1937            context.type = EmulateInstruction::eContextRegisterStore;
1938        else
1939            context.type = EmulateInstruction::eContextPushRegisterOnStack;
1940        RegisterInfo sp_reg;
1941        RegisterInfo dwarf_reg;
1942
1943        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
1944        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rt, dwarf_reg);
1945        context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
1946        if (Rt != 15)
1947        {
1948            uint32_t reg_value = ReadCoreReg(Rt, &success);
1949            if (!success)
1950                return false;
1951            if (!MemUWrite (context, addr, reg_value, addr_byte_size))
1952                return false;
1953        }
1954        else
1955        {
1956            const uint32_t pc = ReadCoreReg(PC_REG, &success);
1957            if (!success)
1958                return false;
1959            if (!MemUWrite (context, addr, pc, addr_byte_size))
1960                return false;
1961        }
1962
1963
1964        if (wback)
1965        {
1966            context.type = EmulateInstruction::eContextAdjustStackPointer;
1967            context.SetImmediateSigned (addr - sp);
1968            if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, offset_addr))
1969                return false;
1970        }
1971    }
1972    return true;
1973}
1974
1975// Vector Push stores multiple extension registers to the stack.
1976// It also updates SP to point to the start of the stored data.
1977bool
1978EmulateInstructionARM::EmulateVPUSH (const uint32_t opcode, const ARMEncoding encoding)
1979{
1980#if 0
1981    // ARM pseudo code...
1982    if (ConditionPassed())
1983    {
1984        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
1985        address = SP - imm32;
1986        SP = SP - imm32;
1987        if single_regs then
1988            for r = 0 to regs-1
1989                MemA[address,4] = S[d+r]; address = address+4;
1990        else
1991            for r = 0 to regs-1
1992                // Store as two word-aligned words in the correct order for current endianness.
1993                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
1994                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
1995                address = address+8;
1996    }
1997#endif
1998
1999    bool success = false;
2000    bool conditional = false;
2001    if (ConditionPassed(opcode, &conditional))
2002    {
2003        const uint32_t addr_byte_size = GetAddressByteSize();
2004        const addr_t sp = ReadCoreReg (SP_REG, &success);
2005        if (!success)
2006            return false;
2007        bool single_regs;
2008        uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2009        uint32_t imm32; // stack offset
2010        uint32_t regs;  // number of registers
2011        switch (encoding) {
2012        case eEncodingT1:
2013        case eEncodingA1:
2014            single_regs = false;
2015            d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2016            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2017            // If UInt(imm8) is odd, see "FSTMX".
2018            regs = Bits32(opcode, 7, 0) / 2;
2019            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2020            if (regs == 0 || regs > 16 || (d + regs) > 32)
2021                return false;
2022            break;
2023        case eEncodingT2:
2024        case eEncodingA2:
2025            single_regs = true;
2026            d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2027            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2028            regs = Bits32(opcode, 7, 0);
2029            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2030            if (regs == 0 || regs > 16 || (d + regs) > 32)
2031                return false;
2032            break;
2033        default:
2034            return false;
2035        }
2036        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2037        uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2038        addr_t sp_offset = imm32;
2039        addr_t addr = sp - sp_offset;
2040        uint32_t i;
2041
2042        EmulateInstruction::Context context;
2043        if (conditional)
2044            context.type = EmulateInstruction::eContextRegisterStore;
2045        else
2046            context.type = EmulateInstruction::eContextPushRegisterOnStack;
2047        RegisterInfo dwarf_reg;
2048        RegisterInfo sp_reg;
2049        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2050        for (i=0; i<regs; ++i)
2051        {
2052            GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2053            context.SetRegisterToRegisterPlusOffset ( dwarf_reg, sp_reg, addr - sp);
2054            // uint64_t to accommodate 64-bit registers.
2055            uint64_t reg_value = ReadRegisterUnsigned (&dwarf_reg, 0, &success);
2056            if (!success)
2057                return false;
2058            if (!MemAWrite (context, addr, reg_value, reg_byte_size))
2059                return false;
2060            addr += reg_byte_size;
2061        }
2062
2063        context.type = EmulateInstruction::eContextAdjustStackPointer;
2064        context.SetImmediateSigned (-sp_offset);
2065
2066        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp - sp_offset))
2067            return false;
2068    }
2069    return true;
2070}
2071
2072// Vector Pop loads multiple extension registers from the stack.
2073// It also updates SP to point just above the loaded data.
2074bool
2075EmulateInstructionARM::EmulateVPOP (const uint32_t opcode, const ARMEncoding encoding)
2076{
2077#if 0
2078    // ARM pseudo code...
2079    if (ConditionPassed())
2080    {
2081        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(13);
2082        address = SP;
2083        SP = SP + imm32;
2084        if single_regs then
2085            for r = 0 to regs-1
2086                S[d+r] = MemA[address,4]; address = address+4;
2087        else
2088            for r = 0 to regs-1
2089                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
2090                // Combine the word-aligned words in the correct order for current endianness.
2091                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
2092    }
2093#endif
2094
2095    bool success = false;
2096    bool conditional = false;
2097    if (ConditionPassed(opcode, &conditional))
2098    {
2099        const uint32_t addr_byte_size = GetAddressByteSize();
2100        const addr_t sp = ReadCoreReg (SP_REG, &success);
2101        if (!success)
2102            return false;
2103        bool single_regs;
2104        uint32_t d;     // UInt(D:Vd) or UInt(Vd:D) starting register
2105        uint32_t imm32; // stack offset
2106        uint32_t regs;  // number of registers
2107        switch (encoding) {
2108        case eEncodingT1:
2109        case eEncodingA1:
2110            single_regs = false;
2111            d = Bit32(opcode, 22) << 4 | Bits32(opcode, 15, 12);
2112            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2113            // If UInt(imm8) is odd, see "FLDMX".
2114            regs = Bits32(opcode, 7, 0) / 2;
2115            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2116            if (regs == 0 || regs > 16 || (d + regs) > 32)
2117                return false;
2118            break;
2119        case eEncodingT2:
2120        case eEncodingA2:
2121            single_regs = true;
2122            d = Bits32(opcode, 15, 12) << 1 | Bit32(opcode, 22);
2123            imm32 = Bits32(opcode, 7, 0) * addr_byte_size;
2124            regs = Bits32(opcode, 7, 0);
2125            // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
2126            if (regs == 0 || regs > 16 || (d + regs) > 32)
2127                return false;
2128            break;
2129        default:
2130            return false;
2131        }
2132        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
2133        uint32_t reg_byte_size = single_regs ? addr_byte_size : addr_byte_size * 2;
2134        addr_t sp_offset = imm32;
2135        addr_t addr = sp;
2136        uint32_t i;
2137        uint64_t data; // uint64_t to accomodate 64-bit registers.
2138
2139        EmulateInstruction::Context context;
2140        if (conditional)
2141            context.type = EmulateInstruction::eContextRegisterLoad;
2142        else
2143            context.type = EmulateInstruction::eContextPopRegisterOffStack;
2144        RegisterInfo dwarf_reg;
2145        RegisterInfo sp_reg;
2146        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
2147        for (i=0; i<regs; ++i)
2148        {
2149            GetRegisterInfo (eRegisterKindDWARF, start_reg + d + i, dwarf_reg);
2150            context.SetRegisterPlusOffset (sp_reg, addr - sp);
2151            data = MemARead(context, addr, reg_byte_size, 0, &success);
2152            if (!success)
2153                return false;
2154            if (!WriteRegisterUnsigned(context, &dwarf_reg, data))
2155                return false;
2156            addr += reg_byte_size;
2157        }
2158
2159        context.type = EmulateInstruction::eContextAdjustStackPointer;
2160        context.SetImmediateSigned (sp_offset);
2161
2162        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, sp + sp_offset))
2163            return false;
2164    }
2165    return true;
2166}
2167
2168// SVC (previously SWI)
2169bool
2170EmulateInstructionARM::EmulateSVC (const uint32_t opcode, const ARMEncoding encoding)
2171{
2172#if 0
2173    // ARM pseudo code...
2174    if (ConditionPassed())
2175    {
2176        EncodingSpecificOperations();
2177        CallSupervisor();
2178    }
2179#endif
2180
2181    bool success = false;
2182
2183    if (ConditionPassed(opcode))
2184    {
2185        const uint32_t pc = ReadCoreReg(PC_REG, &success);
2186        addr_t lr; // next instruction address
2187        if (!success)
2188            return false;
2189        uint32_t imm32; // the immediate constant
2190        uint32_t mode;  // ARM or Thumb mode
2191        switch (encoding) {
2192        case eEncodingT1:
2193            lr = (pc + 2) | 1u; // return address
2194            imm32 = Bits32(opcode, 7, 0);
2195            mode = eModeThumb;
2196            break;
2197        case eEncodingA1:
2198            lr = pc + 4; // return address
2199            imm32 = Bits32(opcode, 23, 0);
2200            mode = eModeARM;
2201            break;
2202        default:
2203            return false;
2204        }
2205
2206        EmulateInstruction::Context context;
2207        context.type = EmulateInstruction::eContextSupervisorCall;
2208        context.SetISAAndImmediate (mode, imm32);
2209        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, lr))
2210            return false;
2211    }
2212    return true;
2213}
2214
2215// If Then makes up to four following instructions (the IT block) conditional.
2216bool
2217EmulateInstructionARM::EmulateIT (const uint32_t opcode, const ARMEncoding encoding)
2218{
2219#if 0
2220    // ARM pseudo code...
2221    EncodingSpecificOperations();
2222    ITSTATE.IT<7:0> = firstcond:mask;
2223#endif
2224
2225    m_it_session.InitIT(Bits32(opcode, 7, 0));
2226    return true;
2227}
2228
2229bool
2230EmulateInstructionARM::EmulateNop (const uint32_t opcode, const ARMEncoding encoding)
2231{
2232    // NOP, nothing to do...
2233    return true;
2234}
2235
2236// Branch causes a branch to a target address.
2237bool
2238EmulateInstructionARM::EmulateB (const uint32_t opcode, const ARMEncoding encoding)
2239{
2240#if 0
2241    // ARM pseudo code...
2242    if (ConditionPassed())
2243    {
2244        EncodingSpecificOperations();
2245        BranchWritePC(PC + imm32);
2246    }
2247#endif
2248
2249    bool success = false;
2250
2251    if (ConditionPassed(opcode))
2252    {
2253        EmulateInstruction::Context context;
2254        context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2255        const uint32_t pc = ReadCoreReg(PC_REG, &success);
2256        if (!success)
2257            return false;
2258        addr_t target; // target address
2259        int32_t imm32; // PC-relative offset
2260        switch (encoding) {
2261        case eEncodingT1:
2262            // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2263            imm32 = llvm::SignExtend32<9>(Bits32(opcode, 7, 0) << 1);
2264            target = pc + imm32;
2265            context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2266            break;
2267        case eEncodingT2:
2268            imm32 = llvm::SignExtend32<12>(Bits32(opcode, 10, 0));
2269            target = pc + imm32;
2270            context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2271            break;
2272        case eEncodingT3:
2273            // The 'cond' field is handled in EmulateInstructionARM::CurrentCond().
2274            {
2275            uint32_t S = Bit32(opcode, 26);
2276            uint32_t imm6 = Bits32(opcode, 21, 16);
2277            uint32_t J1 = Bit32(opcode, 13);
2278            uint32_t J2 = Bit32(opcode, 11);
2279            uint32_t imm11 = Bits32(opcode, 10, 0);
2280            uint32_t imm21 = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1);
2281            imm32 = llvm::SignExtend32<21>(imm21);
2282            target = pc + imm32;
2283            context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2284            break;
2285            }
2286        case eEncodingT4:
2287            {
2288            uint32_t S = Bit32(opcode, 26);
2289            uint32_t imm10 = Bits32(opcode, 25, 16);
2290            uint32_t J1 = Bit32(opcode, 13);
2291            uint32_t J2 = Bit32(opcode, 11);
2292            uint32_t imm11 = Bits32(opcode, 10, 0);
2293            uint32_t I1 = !(J1 ^ S);
2294            uint32_t I2 = !(J2 ^ S);
2295            uint32_t imm25 = (S << 24) | (I1 << 23) | (I2 << 22) | (imm10 << 12) | (imm11 << 1);
2296            imm32 = llvm::SignExtend32<25>(imm25);
2297            target = pc + imm32;
2298            context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2299            break;
2300            }
2301        case eEncodingA1:
2302            imm32 = llvm::SignExtend32<26>(Bits32(opcode, 23, 0) << 2);
2303            target = pc + imm32;
2304            context.SetISAAndImmediateSigned (eModeARM, 8 + imm32);
2305            break;
2306        default:
2307            return false;
2308        }
2309        if (!BranchWritePC(context, target))
2310            return false;
2311    }
2312    return true;
2313}
2314
2315// Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with
2316// zero and conditionally branch forward a constant value.  They do not affect the condition flags.
2317// CBNZ, CBZ
2318bool
2319EmulateInstructionARM::EmulateCB (const uint32_t opcode, const ARMEncoding encoding)
2320{
2321#if 0
2322    // ARM pseudo code...
2323    EncodingSpecificOperations();
2324    if nonzero ^ IsZero(R[n]) then
2325        BranchWritePC(PC + imm32);
2326#endif
2327
2328    bool success = false;
2329
2330    // Read the register value from the operand register Rn.
2331    uint32_t reg_val = ReadCoreReg(Bits32(opcode, 2, 0), &success);
2332    if (!success)
2333        return false;
2334
2335    EmulateInstruction::Context context;
2336    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2337    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2338    if (!success)
2339        return false;
2340
2341    addr_t target;  // target address
2342    uint32_t imm32; // PC-relative offset to branch forward
2343    bool nonzero;
2344    switch (encoding) {
2345    case eEncodingT1:
2346        imm32 = Bit32(opcode, 9) << 6 | Bits32(opcode, 7, 3) << 1;
2347        nonzero = BitIsSet(opcode, 11);
2348        target = pc + imm32;
2349        context.SetISAAndImmediateSigned (eModeThumb, 4 + imm32);
2350        break;
2351    default:
2352        return false;
2353    }
2354    if (nonzero ^ (reg_val == 0))
2355        if (!BranchWritePC(context, target))
2356            return false;
2357
2358    return true;
2359}
2360
2361// Table Branch Byte causes a PC-relative forward branch using a table of single byte offsets.
2362// A base register provides a pointer to the table, and a second register supplies an index into the table.
2363// The branch length is twice the value of the byte returned from the table.
2364//
2365// Table Branch Halfword causes a PC-relative forward branch using a table of single halfword offsets.
2366// A base register provides a pointer to the table, and a second register supplies an index into the table.
2367// The branch length is twice the value of the halfword returned from the table.
2368// TBB, TBH
2369bool
2370EmulateInstructionARM::EmulateTB (const uint32_t opcode, const ARMEncoding encoding)
2371{
2372#if 0
2373    // ARM pseudo code...
2374    EncodingSpecificOperations(); NullCheckIfThumbEE(n);
2375    if is_tbh then
2376        halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
2377    else
2378        halfwords = UInt(MemU[R[n]+R[m], 1]);
2379    BranchWritePC(PC + 2*halfwords);
2380#endif
2381
2382    bool success = false;
2383
2384    uint32_t Rn;     // the base register which contains the address of the table of branch lengths
2385    uint32_t Rm;     // the index register which contains an integer pointing to a byte/halfword in the table
2386    bool is_tbh;     // true if table branch halfword
2387    switch (encoding) {
2388    case eEncodingT1:
2389        Rn = Bits32(opcode, 19, 16);
2390        Rm = Bits32(opcode, 3, 0);
2391        is_tbh = BitIsSet(opcode, 4);
2392        if (Rn == 13 || BadReg(Rm))
2393            return false;
2394        if (InITBlock() && !LastInITBlock())
2395            return false;
2396        break;
2397    default:
2398        return false;
2399    }
2400
2401    // Read the address of the table from the operand register Rn.
2402    // The PC can be used, in which case the table immediately follows this instruction.
2403    uint32_t base = ReadCoreReg(Rm, &success);
2404    if (!success)
2405        return false;
2406
2407    // the table index
2408    uint32_t index = ReadCoreReg(Rm, &success);
2409    if (!success)
2410        return false;
2411
2412    // the offsetted table address
2413    addr_t addr = base + (is_tbh ? index*2 : index);
2414
2415    // PC-relative offset to branch forward
2416    EmulateInstruction::Context context;
2417    context.type = EmulateInstruction::eContextTableBranchReadMemory;
2418    uint32_t offset = MemURead(context, addr, is_tbh ? 2 : 1, 0, &success) * 2;
2419    if (!success)
2420        return false;
2421
2422    const uint32_t pc = ReadCoreReg(PC_REG, &success);
2423    if (!success)
2424        return false;
2425
2426    // target address
2427    addr_t target = pc + offset;
2428    context.type = EmulateInstruction::eContextRelativeBranchImmediate;
2429    context.SetISAAndImmediateSigned (eModeThumb, 4 + offset);
2430
2431    if (!BranchWritePC(context, target))
2432        return false;
2433
2434    return true;
2435}
2436
2437// This instruction adds an immediate value to a register value, and writes the result to the destination register.
2438// It can optionally update the condition flags based on the result.
2439bool
2440EmulateInstructionARM::EmulateADDImmThumb (const uint32_t opcode, const ARMEncoding encoding)
2441{
2442#if 0
2443    if ConditionPassed() then
2444        EncodingSpecificOperations();
2445        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2446        R[d] = result;
2447        if setflags then
2448            APSR.N = result<31>;
2449            APSR.Z = IsZeroBit(result);
2450            APSR.C = carry;
2451            APSR.V = overflow;
2452#endif
2453
2454    bool success = false;
2455
2456    if (ConditionPassed(opcode))
2457    {
2458        uint32_t d;
2459        uint32_t n;
2460        bool setflags;
2461        uint32_t imm32;
2462        uint32_t carry_out;
2463
2464        //EncodingSpecificOperations();
2465        switch (encoding)
2466        {
2467            case eEncodingT1:
2468                // d = UInt(Rd); n = UInt(Rn); setflags = !InITBlock(); imm32 = ZeroExtend(imm3, 32);
2469                d = Bits32 (opcode, 2, 0);
2470                n = Bits32 (opcode, 5, 3);
2471                setflags = !InITBlock();
2472                imm32 = Bits32 (opcode, 8,6);
2473
2474                break;
2475
2476            case eEncodingT2:
2477                // d = UInt(Rdn); n = UInt(Rdn); setflags = !InITBlock(); imm32 = ZeroExtend(imm8, 32);
2478                d = Bits32 (opcode, 10, 8);
2479                n = Bits32 (opcode, 10, 8);
2480                setflags = !InITBlock();
2481                imm32 = Bits32 (opcode, 7, 0);
2482
2483                break;
2484
2485            case eEncodingT3:
2486                // if Rd == '1111' && S == '1' then SEE CMN (immediate);
2487                // if Rn == '1101' then SEE ADD (SP plus immediate);
2488                // d = UInt(Rd); n = UInt(Rn); setflags = (S == '1'); imm32 = ThumbExpandImm(i:imm3:imm8);
2489                d = Bits32 (opcode, 11, 8);
2490                n = Bits32 (opcode, 19, 16);
2491                setflags = BitIsSet (opcode, 20);
2492                imm32 = ThumbExpandImm_C (opcode, APSR_C, carry_out);
2493
2494                // if BadReg(d) || n == 15 then UNPREDICTABLE;
2495                if (BadReg (d) || (n == 15))
2496                    return false;
2497
2498                break;
2499
2500            case eEncodingT4:
2501            {
2502                // if Rn == '1111' then SEE ADR;
2503                // if Rn == '1101' then SEE ADD (SP plus immediate);
2504                // d = UInt(Rd); n = UInt(Rn); setflags = FALSE; imm32 = ZeroExtend(i:imm3:imm8, 32);
2505                d = Bits32 (opcode, 11, 8);
2506                n = Bits32 (opcode, 19, 16);
2507                setflags = false;
2508                uint32_t i = Bit32 (opcode, 26);
2509                uint32_t imm3 = Bits32 (opcode, 14, 12);
2510                uint32_t imm8 = Bits32 (opcode, 7, 0);
2511                imm32 = (i << 11) | (imm3 << 8) | imm8;
2512
2513                // if BadReg(d) then UNPREDICTABLE;
2514                if (BadReg (d))
2515                    return false;
2516
2517                break;
2518            }
2519            default:
2520                return false;
2521        }
2522
2523        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
2524        if (!success)
2525            return false;
2526
2527        //(result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2528        AddWithCarryResult res = AddWithCarry (Rn, imm32, 0);
2529
2530        RegisterInfo reg_n;
2531        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
2532
2533        EmulateInstruction::Context context;
2534        context.type = eContextArithmetic;
2535        context.SetRegisterPlusOffset (reg_n, imm32);
2536
2537        //R[d] = result;
2538        //if setflags then
2539            //APSR.N = result<31>;
2540            //APSR.Z = IsZeroBit(result);
2541            //APSR.C = carry;
2542            //APSR.V = overflow;
2543        if (!WriteCoreRegOptionalFlags (context, res.result, d, setflags, res.carry_out, res.overflow))
2544            return false;
2545
2546    }
2547    return true;
2548}
2549
2550// This instruction adds an immediate value to a register value, and writes the result to the destination
2551// register.  It can optionally update the condition flags based on the result.
2552bool
2553EmulateInstructionARM::EmulateADDImmARM (const uint32_t opcode, const ARMEncoding encoding)
2554{
2555#if 0
2556    // ARM pseudo code...
2557    if ConditionPassed() then
2558        EncodingSpecificOperations();
2559        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2560        if d == 15 then
2561            ALUWritePC(result); // setflags is always FALSE here
2562        else
2563            R[d] = result;
2564            if setflags then
2565                APSR.N = result<31>;
2566                APSR.Z = IsZeroBit(result);
2567                APSR.C = carry;
2568                APSR.V = overflow;
2569#endif
2570
2571    bool success = false;
2572
2573    if (ConditionPassed(opcode))
2574    {
2575        uint32_t Rd, Rn;
2576        uint32_t imm32; // the immediate value to be added to the value obtained from Rn
2577        bool setflags;
2578        switch (encoding)
2579        {
2580        case eEncodingA1:
2581            Rd = Bits32(opcode, 15, 12);
2582            Rn = Bits32(opcode, 19, 16);
2583            setflags = BitIsSet(opcode, 20);
2584            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2585            break;
2586        default:
2587            return false;
2588        }
2589
2590        // Read the first operand.
2591        uint32_t val1 = ReadCoreReg(Rn, &success);
2592        if (!success)
2593            return false;
2594
2595        AddWithCarryResult res = AddWithCarry(val1, imm32, 0);
2596
2597        EmulateInstruction::Context context;
2598        context.type = eContextArithmetic;
2599        RegisterInfo dwarf_reg;
2600        GetRegisterInfo (eRegisterKindDWARF, Rn, dwarf_reg);
2601        context.SetRegisterPlusOffset (dwarf_reg, imm32);
2602
2603        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2604            return false;
2605    }
2606    return true;
2607}
2608
2609// This instruction adds a register value and an optionally-shifted register value, and writes the result
2610// to the destination register. It can optionally update the condition flags based on the result.
2611bool
2612EmulateInstructionARM::EmulateADDReg (const uint32_t opcode, const ARMEncoding encoding)
2613{
2614#if 0
2615    // ARM pseudo code...
2616    if ConditionPassed() then
2617        EncodingSpecificOperations();
2618        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2619        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2620        if d == 15 then
2621            ALUWritePC(result); // setflags is always FALSE here
2622        else
2623            R[d] = result;
2624            if setflags then
2625                APSR.N = result<31>;
2626                APSR.Z = IsZeroBit(result);
2627                APSR.C = carry;
2628                APSR.V = overflow;
2629#endif
2630
2631    bool success = false;
2632
2633    if (ConditionPassed(opcode))
2634    {
2635        uint32_t Rd, Rn, Rm;
2636        ARM_ShifterType shift_t;
2637        uint32_t shift_n; // the shift applied to the value read from Rm
2638        bool setflags;
2639        switch (encoding)
2640        {
2641        case eEncodingT1:
2642            Rd = Bits32(opcode, 2, 0);
2643            Rn = Bits32(opcode, 5, 3);
2644            Rm = Bits32(opcode, 8, 6);
2645            setflags = !InITBlock();
2646            shift_t = SRType_LSL;
2647            shift_n = 0;
2648            break;
2649        case eEncodingT2:
2650            Rd = Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2651            Rm = Bits32(opcode, 6, 3);
2652            setflags = false;
2653            shift_t = SRType_LSL;
2654            shift_n = 0;
2655            if (Rn == 15 && Rm == 15)
2656                return false;
2657            if (Rd == 15 && InITBlock() && !LastInITBlock())
2658                return false;
2659            break;
2660        case eEncodingA1:
2661            Rd = Bits32(opcode, 15, 12);
2662            Rn = Bits32(opcode, 19, 16);
2663            Rm = Bits32(opcode, 3, 0);
2664            setflags = BitIsSet(opcode, 20);
2665            shift_n = DecodeImmShiftARM(opcode, shift_t);
2666            break;
2667        default:
2668            return false;
2669        }
2670
2671        // Read the first operand.
2672        uint32_t val1 = ReadCoreReg(Rn, &success);
2673        if (!success)
2674            return false;
2675
2676        // Read the second operand.
2677        uint32_t val2 = ReadCoreReg(Rm, &success);
2678        if (!success)
2679            return false;
2680
2681        uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2682        if (!success)
2683            return false;
2684        AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2685
2686        EmulateInstruction::Context context;
2687        context.type = eContextArithmetic;
2688        RegisterInfo op1_reg;
2689        RegisterInfo op2_reg;
2690        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, op1_reg);
2691        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rm, op2_reg);
2692        context.SetRegisterRegisterOperands (op1_reg, op2_reg);
2693
2694        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
2695            return false;
2696    }
2697    return true;
2698}
2699
2700// Compare Negative (immediate) adds a register value and an immediate value.
2701// It updates the condition flags based on the result, and discards the result.
2702bool
2703EmulateInstructionARM::EmulateCMNImm (const uint32_t opcode, const ARMEncoding encoding)
2704{
2705#if 0
2706    // ARM pseudo code...
2707    if ConditionPassed() then
2708        EncodingSpecificOperations();
2709        (result, carry, overflow) = AddWithCarry(R[n], imm32, '0');
2710        APSR.N = result<31>;
2711        APSR.Z = IsZeroBit(result);
2712        APSR.C = carry;
2713        APSR.V = overflow;
2714#endif
2715
2716    bool success = false;
2717
2718    uint32_t Rn; // the first operand
2719    uint32_t imm32; // the immediate value to be compared with
2720    switch (encoding) {
2721    case eEncodingT1:
2722        Rn = Bits32(opcode, 19, 16);
2723        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2724        if (Rn == 15)
2725            return false;
2726        break;
2727    case eEncodingA1:
2728        Rn = Bits32(opcode, 19, 16);
2729        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2730        break;
2731    default:
2732        return false;
2733    }
2734    // Read the register value from the operand register Rn.
2735    uint32_t reg_val = ReadCoreReg(Rn, &success);
2736    if (!success)
2737        return false;
2738
2739    AddWithCarryResult res = AddWithCarry(reg_val, imm32, 0);
2740
2741    EmulateInstruction::Context context;
2742    context.type = EmulateInstruction::eContextImmediate;
2743    context.SetNoArgs ();
2744    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2745        return false;
2746
2747    return true;
2748}
2749
2750// Compare Negative (register) adds a register value and an optionally-shifted register value.
2751// It updates the condition flags based on the result, and discards the result.
2752bool
2753EmulateInstructionARM::EmulateCMNReg (const uint32_t opcode, const ARMEncoding encoding)
2754{
2755#if 0
2756    // ARM pseudo code...
2757    if ConditionPassed() then
2758        EncodingSpecificOperations();
2759        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2760        (result, carry, overflow) = AddWithCarry(R[n], shifted, '0');
2761        APSR.N = result<31>;
2762        APSR.Z = IsZeroBit(result);
2763        APSR.C = carry;
2764        APSR.V = overflow;
2765#endif
2766
2767    bool success = false;
2768
2769    uint32_t Rn; // the first operand
2770    uint32_t Rm; // the second operand
2771    ARM_ShifterType shift_t;
2772    uint32_t shift_n; // the shift applied to the value read from Rm
2773    switch (encoding) {
2774    case eEncodingT1:
2775        Rn = Bits32(opcode, 2, 0);
2776        Rm = Bits32(opcode, 5, 3);
2777        shift_t = SRType_LSL;
2778        shift_n = 0;
2779        break;
2780    case eEncodingT2:
2781        Rn = Bits32(opcode, 19, 16);
2782        Rm = Bits32(opcode, 3, 0);
2783        shift_n = DecodeImmShiftThumb(opcode, shift_t);
2784        // if n == 15 || BadReg(m) then UNPREDICTABLE;
2785        if (Rn == 15 || BadReg(Rm))
2786            return false;
2787        break;
2788    case eEncodingA1:
2789        Rn = Bits32(opcode, 19, 16);
2790        Rm = Bits32(opcode, 3, 0);
2791        shift_n = DecodeImmShiftARM(opcode, shift_t);
2792        break;
2793    default:
2794        return false;
2795    }
2796    // Read the register value from register Rn.
2797    uint32_t val1 = ReadCoreReg(Rn, &success);
2798    if (!success)
2799        return false;
2800
2801    // Read the register value from register Rm.
2802    uint32_t val2 = ReadCoreReg(Rm, &success);
2803    if (!success)
2804        return false;
2805
2806    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2807    if (!success)
2808        return false;
2809    AddWithCarryResult res = AddWithCarry(val1, shifted, 0);
2810
2811    EmulateInstruction::Context context;
2812    context.type = EmulateInstruction::eContextImmediate;
2813    context.SetNoArgs();
2814    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2815        return false;
2816
2817    return true;
2818}
2819
2820// Compare (immediate) subtracts an immediate value from a register value.
2821// It updates the condition flags based on the result, and discards the result.
2822bool
2823EmulateInstructionARM::EmulateCMPImm (const uint32_t opcode, const ARMEncoding encoding)
2824{
2825#if 0
2826    // ARM pseudo code...
2827    if ConditionPassed() then
2828        EncodingSpecificOperations();
2829        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
2830        APSR.N = result<31>;
2831        APSR.Z = IsZeroBit(result);
2832        APSR.C = carry;
2833        APSR.V = overflow;
2834#endif
2835
2836    bool success = false;
2837
2838    uint32_t Rn; // the first operand
2839    uint32_t imm32; // the immediate value to be compared with
2840    switch (encoding) {
2841    case eEncodingT1:
2842        Rn = Bits32(opcode, 10, 8);
2843        imm32 = Bits32(opcode, 7, 0);
2844        break;
2845    case eEncodingT2:
2846        Rn = Bits32(opcode, 19, 16);
2847        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
2848        if (Rn == 15)
2849            return false;
2850        break;
2851    case eEncodingA1:
2852        Rn = Bits32(opcode, 19, 16);
2853        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
2854        break;
2855    default:
2856        return false;
2857    }
2858    // Read the register value from the operand register Rn.
2859    uint32_t reg_val = ReadCoreReg(Rn, &success);
2860    if (!success)
2861        return false;
2862
2863    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
2864
2865    EmulateInstruction::Context context;
2866    context.type = EmulateInstruction::eContextImmediate;
2867    context.SetNoArgs ();
2868    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2869        return false;
2870
2871    return true;
2872}
2873
2874// Compare (register) subtracts an optionally-shifted register value from a register value.
2875// It updates the condition flags based on the result, and discards the result.
2876bool
2877EmulateInstructionARM::EmulateCMPReg (const uint32_t opcode, const ARMEncoding encoding)
2878{
2879#if 0
2880    // ARM pseudo code...
2881    if ConditionPassed() then
2882        EncodingSpecificOperations();
2883        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
2884        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), '1');
2885        APSR.N = result<31>;
2886        APSR.Z = IsZeroBit(result);
2887        APSR.C = carry;
2888        APSR.V = overflow;
2889#endif
2890
2891    bool success = false;
2892
2893    uint32_t Rn; // the first operand
2894    uint32_t Rm; // the second operand
2895    ARM_ShifterType shift_t;
2896    uint32_t shift_n; // the shift applied to the value read from Rm
2897    switch (encoding) {
2898    case eEncodingT1:
2899        Rn = Bits32(opcode, 2, 0);
2900        Rm = Bits32(opcode, 5, 3);
2901        shift_t = SRType_LSL;
2902        shift_n = 0;
2903        break;
2904    case eEncodingT2:
2905        Rn = Bit32(opcode, 7) << 3 | Bits32(opcode, 2, 0);
2906        Rm = Bits32(opcode, 6, 3);
2907        shift_t = SRType_LSL;
2908        shift_n = 0;
2909        if (Rn < 8 && Rm < 8)
2910            return false;
2911        if (Rn == 15 || Rm == 15)
2912            return false;
2913        break;
2914    case eEncodingA1:
2915        Rn = Bits32(opcode, 19, 16);
2916        Rm = Bits32(opcode, 3, 0);
2917        shift_n = DecodeImmShiftARM(opcode, shift_t);
2918        break;
2919    default:
2920        return false;
2921    }
2922    // Read the register value from register Rn.
2923    uint32_t val1 = ReadCoreReg(Rn, &success);
2924    if (!success)
2925        return false;
2926
2927    // Read the register value from register Rm.
2928    uint32_t val2 = ReadCoreReg(Rm, &success);
2929    if (!success)
2930        return false;
2931
2932    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
2933    if (!success)
2934        return false;
2935    AddWithCarryResult res = AddWithCarry(val1, ~shifted, 1);
2936
2937    EmulateInstruction::Context context;
2938    context.type = EmulateInstruction::eContextImmediate;
2939    context.SetNoArgs();
2940    if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
2941        return false;
2942
2943    return true;
2944}
2945
2946// Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits,
2947// shifting in copies of its sign bit, and writes the result to the destination register.  It can
2948// optionally update the condition flags based on the result.
2949bool
2950EmulateInstructionARM::EmulateASRImm (const uint32_t opcode, const ARMEncoding encoding)
2951{
2952#if 0
2953    // ARM pseudo code...
2954    if ConditionPassed() then
2955        EncodingSpecificOperations();
2956        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2957        if d == 15 then         // Can only occur for ARM encoding
2958            ALUWritePC(result); // setflags is always FALSE here
2959        else
2960            R[d] = result;
2961            if setflags then
2962                APSR.N = result<31>;
2963                APSR.Z = IsZeroBit(result);
2964                APSR.C = carry;
2965                // APSR.V unchanged
2966#endif
2967
2968    return EmulateShiftImm (opcode, encoding, SRType_ASR);
2969}
2970
2971// Arithmetic Shift Right (register) shifts a register value right by a variable number of bits,
2972// shifting in copies of its sign bit, and writes the result to the destination register.
2973// The variable number of bits is read from the bottom byte of a register. It can optionally update
2974// the condition flags based on the result.
2975bool
2976EmulateInstructionARM::EmulateASRReg (const uint32_t opcode, const ARMEncoding encoding)
2977{
2978#if 0
2979    // ARM pseudo code...
2980    if ConditionPassed() then
2981        EncodingSpecificOperations();
2982        shift_n = UInt(R[m]<7:0>);
2983        (result, carry) = Shift_C(R[m], SRType_ASR, shift_n, APSR.C);
2984        R[d] = result;
2985        if setflags then
2986            APSR.N = result<31>;
2987            APSR.Z = IsZeroBit(result);
2988            APSR.C = carry;
2989            // APSR.V unchanged
2990#endif
2991
2992    return EmulateShiftReg (opcode, encoding, SRType_ASR);
2993}
2994
2995// Logical Shift Left (immediate) shifts a register value left by an immediate number of bits,
2996// shifting in zeros, and writes the result to the destination register.  It can optionally
2997// update the condition flags based on the result.
2998bool
2999EmulateInstructionARM::EmulateLSLImm (const uint32_t opcode, const ARMEncoding encoding)
3000{
3001#if 0
3002    // ARM pseudo code...
3003    if ConditionPassed() then
3004        EncodingSpecificOperations();
3005        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3006        if d == 15 then         // Can only occur for ARM encoding
3007            ALUWritePC(result); // setflags is always FALSE here
3008        else
3009            R[d] = result;
3010            if setflags then
3011                APSR.N = result<31>;
3012                APSR.Z = IsZeroBit(result);
3013                APSR.C = carry;
3014                // APSR.V unchanged
3015#endif
3016
3017    return EmulateShiftImm (opcode, encoding, SRType_LSL);
3018}
3019
3020// Logical Shift Left (register) shifts a register value left by a variable number of bits,
3021// shifting in zeros, and writes the result to the destination register.  The variable number
3022// of bits is read from the bottom byte of a register. It can optionally update the condition
3023// flags based on the result.
3024bool
3025EmulateInstructionARM::EmulateLSLReg (const uint32_t opcode, const ARMEncoding encoding)
3026{
3027#if 0
3028    // ARM pseudo code...
3029    if ConditionPassed() then
3030        EncodingSpecificOperations();
3031        shift_n = UInt(R[m]<7:0>);
3032        (result, carry) = Shift_C(R[m], SRType_LSL, shift_n, APSR.C);
3033        R[d] = result;
3034        if setflags then
3035            APSR.N = result<31>;
3036            APSR.Z = IsZeroBit(result);
3037            APSR.C = carry;
3038            // APSR.V unchanged
3039#endif
3040
3041    return EmulateShiftReg (opcode, encoding, SRType_LSL);
3042}
3043
3044// Logical Shift Right (immediate) shifts a register value right by an immediate number of bits,
3045// shifting in zeros, and writes the result to the destination register.  It can optionally
3046// update the condition flags based on the result.
3047bool
3048EmulateInstructionARM::EmulateLSRImm (const uint32_t opcode, const ARMEncoding encoding)
3049{
3050#if 0
3051    // ARM pseudo code...
3052    if ConditionPassed() then
3053        EncodingSpecificOperations();
3054        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3055        if d == 15 then         // Can only occur for ARM encoding
3056            ALUWritePC(result); // setflags is always FALSE here
3057        else
3058            R[d] = result;
3059            if setflags then
3060                APSR.N = result<31>;
3061                APSR.Z = IsZeroBit(result);
3062                APSR.C = carry;
3063                // APSR.V unchanged
3064#endif
3065
3066    return EmulateShiftImm (opcode, encoding, SRType_LSR);
3067}
3068
3069// Logical Shift Right (register) shifts a register value right by a variable number of bits,
3070// shifting in zeros, and writes the result to the destination register.  The variable number
3071// of bits is read from the bottom byte of a register. It can optionally update the condition
3072// flags based on the result.
3073bool
3074EmulateInstructionARM::EmulateLSRReg (const uint32_t opcode, const ARMEncoding encoding)
3075{
3076#if 0
3077    // ARM pseudo code...
3078    if ConditionPassed() then
3079        EncodingSpecificOperations();
3080        shift_n = UInt(R[m]<7:0>);
3081        (result, carry) = Shift_C(R[m], SRType_LSR, shift_n, APSR.C);
3082        R[d] = result;
3083        if setflags then
3084            APSR.N = result<31>;
3085            APSR.Z = IsZeroBit(result);
3086            APSR.C = carry;
3087            // APSR.V unchanged
3088#endif
3089
3090    return EmulateShiftReg (opcode, encoding, SRType_LSR);
3091}
3092
3093// Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value.
3094// The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3095// It can optionally update the condition flags based on the result.
3096bool
3097EmulateInstructionARM::EmulateRORImm (const uint32_t opcode, const ARMEncoding encoding)
3098{
3099#if 0
3100    // ARM pseudo code...
3101    if ConditionPassed() then
3102        EncodingSpecificOperations();
3103        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3104        if d == 15 then         // Can only occur for ARM encoding
3105            ALUWritePC(result); // setflags is always FALSE here
3106        else
3107            R[d] = result;
3108            if setflags then
3109                APSR.N = result<31>;
3110                APSR.Z = IsZeroBit(result);
3111                APSR.C = carry;
3112                // APSR.V unchanged
3113#endif
3114
3115    return EmulateShiftImm (opcode, encoding, SRType_ROR);
3116}
3117
3118// Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits.
3119// The bits that are rotated off the right end are inserted into the vacated bit positions on the left.
3120// The variable number of bits is read from the bottom byte of a register. It can optionally update the condition
3121// flags based on the result.
3122bool
3123EmulateInstructionARM::EmulateRORReg (const uint32_t opcode, const ARMEncoding encoding)
3124{
3125#if 0
3126    // ARM pseudo code...
3127    if ConditionPassed() then
3128        EncodingSpecificOperations();
3129        shift_n = UInt(R[m]<7:0>);
3130        (result, carry) = Shift_C(R[m], SRType_ROR, shift_n, APSR.C);
3131        R[d] = result;
3132        if setflags then
3133            APSR.N = result<31>;
3134            APSR.Z = IsZeroBit(result);
3135            APSR.C = carry;
3136            // APSR.V unchanged
3137#endif
3138
3139    return EmulateShiftReg (opcode, encoding, SRType_ROR);
3140}
3141
3142// Rotate Right with Extend provides the value of the contents of a register shifted right by one place,
3143// with the carry flag shifted into bit [31].
3144//
3145// RRX can optionally update the condition flags based on the result.
3146// In that case, bit [0] is shifted into the carry flag.
3147bool
3148EmulateInstructionARM::EmulateRRX (const uint32_t opcode, const ARMEncoding encoding)
3149{
3150#if 0
3151    // ARM pseudo code...
3152    if ConditionPassed() then
3153        EncodingSpecificOperations();
3154        (result, carry) = Shift_C(R[m], SRType_RRX, 1, APSR.C);
3155        if d == 15 then         // Can only occur for ARM encoding
3156            ALUWritePC(result); // setflags is always FALSE here
3157        else
3158            R[d] = result;
3159            if setflags then
3160                APSR.N = result<31>;
3161                APSR.Z = IsZeroBit(result);
3162                APSR.C = carry;
3163                // APSR.V unchanged
3164#endif
3165
3166    return EmulateShiftImm (opcode, encoding, SRType_RRX);
3167}
3168
3169bool
3170EmulateInstructionARM::EmulateShiftImm (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3171{
3172//    assert(shift_type == SRType_ASR
3173//           || shift_type == SRType_LSL
3174//           || shift_type == SRType_LSR
3175//           || shift_type == SRType_ROR
3176//           || shift_type == SRType_RRX);
3177
3178    bool success = false;
3179
3180    if (ConditionPassed(opcode))
3181    {
3182        uint32_t Rd;    // the destination register
3183        uint32_t Rm;    // the first operand register
3184        uint32_t imm5;  // encoding for the shift amount
3185        uint32_t carry; // the carry bit after the shift operation
3186        bool setflags;
3187
3188        // Special case handling!
3189        // A8.6.139 ROR (immediate) -- Encoding T1
3190        ARMEncoding use_encoding = encoding;
3191        if (shift_type == SRType_ROR && use_encoding == eEncodingT1)
3192        {
3193            // Morph the T1 encoding from the ARM Architecture Manual into T2 encoding to
3194            // have the same decoding of bit fields as the other Thumb2 shift operations.
3195            use_encoding = eEncodingT2;
3196        }
3197
3198        switch (use_encoding) {
3199        case eEncodingT1:
3200            // Due to the above special case handling!
3201            if (shift_type == SRType_ROR)
3202                return false;
3203
3204            Rd = Bits32(opcode, 2, 0);
3205            Rm = Bits32(opcode, 5, 3);
3206            setflags = !InITBlock();
3207            imm5 = Bits32(opcode, 10, 6);
3208            break;
3209        case eEncodingT2:
3210            // A8.6.141 RRX
3211            // There's no imm form of RRX instructions.
3212            if (shift_type == SRType_RRX)
3213                return false;
3214
3215            Rd = Bits32(opcode, 11, 8);
3216            Rm = Bits32(opcode, 3, 0);
3217            setflags = BitIsSet(opcode, 20);
3218            imm5 = Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6);
3219            if (BadReg(Rd) || BadReg(Rm))
3220                return false;
3221            break;
3222        case eEncodingA1:
3223            Rd = Bits32(opcode, 15, 12);
3224            Rm = Bits32(opcode, 3, 0);
3225            setflags = BitIsSet(opcode, 20);
3226            imm5 = Bits32(opcode, 11, 7);
3227            break;
3228        default:
3229            return false;
3230        }
3231
3232        // A8.6.139 ROR (immediate)
3233        if (shift_type == SRType_ROR && imm5 == 0)
3234            shift_type = SRType_RRX;
3235
3236        // Get the first operand.
3237        uint32_t value = ReadCoreReg (Rm, &success);
3238        if (!success)
3239            return false;
3240
3241        // Decode the shift amount if not RRX.
3242        uint32_t amt = (shift_type == SRType_RRX ? 1 : DecodeImmShift(shift_type, imm5));
3243
3244        uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3245        if (!success)
3246            return false;
3247
3248        // The context specifies that an immediate is to be moved into Rd.
3249        EmulateInstruction::Context context;
3250        context.type = EmulateInstruction::eContextImmediate;
3251        context.SetNoArgs ();
3252
3253        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3254            return false;
3255    }
3256    return true;
3257}
3258
3259bool
3260EmulateInstructionARM::EmulateShiftReg (const uint32_t opcode, const ARMEncoding encoding, ARM_ShifterType shift_type)
3261{
3262    // assert(shift_type == SRType_ASR
3263    //        || shift_type == SRType_LSL
3264    //        || shift_type == SRType_LSR
3265    //        || shift_type == SRType_ROR);
3266
3267    bool success = false;
3268
3269    if (ConditionPassed(opcode))
3270    {
3271        uint32_t Rd;    // the destination register
3272        uint32_t Rn;    // the first operand register
3273        uint32_t Rm;    // the register whose bottom byte contains the amount to shift by
3274        uint32_t carry; // the carry bit after the shift operation
3275        bool setflags;
3276        switch (encoding) {
3277        case eEncodingT1:
3278            Rd = Bits32(opcode, 2, 0);
3279            Rn = Rd;
3280            Rm = Bits32(opcode, 5, 3);
3281            setflags = !InITBlock();
3282            break;
3283        case eEncodingT2:
3284            Rd = Bits32(opcode, 11, 8);
3285            Rn = Bits32(opcode, 19, 16);
3286            Rm = Bits32(opcode, 3, 0);
3287            setflags = BitIsSet(opcode, 20);
3288            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
3289                return false;
3290            break;
3291        case eEncodingA1:
3292            Rd = Bits32(opcode, 15, 12);
3293            Rn = Bits32(opcode, 3, 0);
3294            Rm = Bits32(opcode, 11, 8);
3295            setflags = BitIsSet(opcode, 20);
3296            if (Rd == 15 || Rn == 15 || Rm == 15)
3297                return false;
3298            break;
3299        default:
3300            return false;
3301        }
3302
3303        // Get the first operand.
3304        uint32_t value = ReadCoreReg (Rn, &success);
3305        if (!success)
3306            return false;
3307        // Get the Rm register content.
3308        uint32_t val = ReadCoreReg (Rm, &success);
3309        if (!success)
3310            return false;
3311
3312        // Get the shift amount.
3313        uint32_t amt = Bits32(val, 7, 0);
3314
3315        uint32_t result = Shift_C(value, shift_type, amt, APSR_C, carry, &success);
3316        if (!success)
3317            return false;
3318
3319        // The context specifies that an immediate is to be moved into Rd.
3320        EmulateInstruction::Context context;
3321        context.type = EmulateInstruction::eContextImmediate;
3322        context.SetNoArgs ();
3323
3324        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
3325            return false;
3326    }
3327    return true;
3328}
3329
3330// LDM loads multiple registers from consecutive memory locations, using an
3331// address from a base register.  Optionally the address just above the highest of those locations
3332// can be written back to the base register.
3333bool
3334EmulateInstructionARM::EmulateLDM (const uint32_t opcode, const ARMEncoding encoding)
3335{
3336#if 0
3337    // ARM pseudo code...
3338    if ConditionPassed()
3339        EncodingSpecificOperations(); NullCheckIfThumbEE (n);
3340        address = R[n];
3341
3342        for i = 0 to 14
3343            if registers<i> == '1' then
3344                R[i] = MemA[address, 4]; address = address + 4;
3345        if registers<15> == '1' then
3346            LoadWritePC (MemA[address, 4]);
3347
3348        if wback && registers<n> == '0' then R[n] = R[n] + 4 * BitCount (registers);
3349        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3350
3351#endif
3352
3353    bool success = false;
3354    bool conditional = false;
3355    if (ConditionPassed(opcode, &conditional))
3356    {
3357        uint32_t n;
3358        uint32_t registers = 0;
3359        bool wback;
3360        const uint32_t addr_byte_size = GetAddressByteSize();
3361        switch (encoding)
3362        {
3363            case eEncodingT1:
3364                // n = UInt(Rn); registers = '00000000':register_list; wback = (registers<n> == '0');
3365                n = Bits32 (opcode, 10, 8);
3366                registers = Bits32 (opcode, 7, 0);
3367                registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
3368                wback = BitIsClear (registers, n);
3369                // if BitCount(registers) < 1 then UNPREDICTABLE;
3370                if (BitCount(registers) < 1)
3371                    return false;
3372                break;
3373            case eEncodingT2:
3374                // if W == '1' && Rn == '1101' then SEE POP;
3375                // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3376                n = Bits32 (opcode, 19, 16);
3377                registers = Bits32 (opcode, 15, 0);
3378                registers = registers & 0xdfff; // Make sure bit 13 is zero.
3379                wback = BitIsSet (opcode, 21);
3380
3381                // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3382                if ((n == 15)
3383                    || (BitCount (registers) < 2)
3384                    || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3385                    return false;
3386
3387                // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3388                if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3389                    return false;
3390
3391                // if wback && registers<n> == '1' then UNPREDICTABLE;
3392                if (wback
3393                    && BitIsSet (registers, n))
3394                    return false;
3395                break;
3396
3397            case eEncodingA1:
3398                n = Bits32 (opcode, 19, 16);
3399                registers = Bits32 (opcode, 15, 0);
3400                wback = BitIsSet (opcode, 21);
3401                if ((n == 15)
3402                    || (BitCount (registers) < 1))
3403                    return false;
3404                break;
3405            default:
3406                return false;
3407        }
3408
3409        int32_t offset = 0;
3410        const addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3411        if (!success)
3412            return false;
3413
3414        EmulateInstruction::Context context;
3415        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3416        RegisterInfo dwarf_reg;
3417        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3418        context.SetRegisterPlusOffset (dwarf_reg, offset);
3419
3420        for (int i = 0; i < 14; ++i)
3421        {
3422            if (BitIsSet (registers, i))
3423            {
3424                context.type = EmulateInstruction::eContextRegisterPlusOffset;
3425                context.SetRegisterPlusOffset (dwarf_reg, offset);
3426                if (wback && (n == 13)) // Pop Instruction
3427                {
3428                    if (conditional)
3429                        context.type = EmulateInstruction::eContextRegisterLoad;
3430                    else
3431                        context.type = EmulateInstruction::eContextPopRegisterOffStack;
3432                }
3433
3434                // R[i] = MemA [address, 4]; address = address + 4;
3435                uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3436                if (!success)
3437                    return false;
3438
3439                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3440                    return false;
3441
3442                offset += addr_byte_size;
3443            }
3444        }
3445
3446        if (BitIsSet (registers, 15))
3447        {
3448            //LoadWritePC (MemA [address, 4]);
3449            context.type = EmulateInstruction::eContextRegisterPlusOffset;
3450            context.SetRegisterPlusOffset (dwarf_reg, offset);
3451            uint32_t data = MemARead (context, base_address + offset, addr_byte_size, 0, &success);
3452            if (!success)
3453                return false;
3454            // In ARMv5T and above, this is an interworking branch.
3455            if (!LoadWritePC(context, data))
3456                return false;
3457        }
3458
3459        if (wback && BitIsClear (registers, n))
3460        {
3461            // R[n] = R[n] + 4 * BitCount (registers)
3462            int32_t offset = addr_byte_size * BitCount (registers);
3463            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3464            context.SetRegisterPlusOffset (dwarf_reg, offset);
3465
3466            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, base_address + offset))
3467                return false;
3468        }
3469        if (wback && BitIsSet (registers, n))
3470            // R[n] bits(32) UNKNOWN;
3471            return WriteBits32Unknown (n);
3472    }
3473    return true;
3474}
3475
3476// LDMDA loads multiple registers from consecutive memory locations using an address from a base register.
3477// The consecutive memory locations end at this address and the address just below the lowest of those locations
3478// can optionally be written back to the base register.
3479bool
3480EmulateInstructionARM::EmulateLDMDA (const uint32_t opcode, const ARMEncoding encoding)
3481{
3482#if 0
3483    // ARM pseudo code...
3484    if ConditionPassed() then
3485        EncodingSpecificOperations();
3486        address = R[n] - 4*BitCount(registers) + 4;
3487
3488        for i = 0 to 14
3489            if registers<i> == '1' then
3490                  R[i] = MemA[address,4]; address = address + 4;
3491
3492        if registers<15> == '1' then
3493            LoadWritePC(MemA[address,4]);
3494
3495        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3496        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3497#endif
3498
3499    bool success = false;
3500
3501    if (ConditionPassed(opcode))
3502    {
3503        uint32_t n;
3504        uint32_t registers = 0;
3505        bool wback;
3506        const uint32_t addr_byte_size = GetAddressByteSize();
3507
3508        // EncodingSpecificOperations();
3509        switch (encoding)
3510        {
3511            case eEncodingA1:
3512                // n = UInt(Rn); registers = register_list; wback = (W == '1');
3513                n = Bits32 (opcode, 19, 16);
3514                registers = Bits32 (opcode, 15, 0);
3515                wback = BitIsSet (opcode, 21);
3516
3517                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3518                if ((n == 15) || (BitCount (registers) < 1))
3519                    return false;
3520
3521                break;
3522
3523            default:
3524                return false;
3525        }
3526        // address = R[n] - 4*BitCount(registers) + 4;
3527
3528        int32_t offset = 0;
3529        addr_t Rn = ReadCoreReg (n, &success);
3530
3531        if (!success)
3532            return false;
3533
3534        addr_t address = Rn - (addr_byte_size * BitCount (registers)) + addr_byte_size;
3535
3536        EmulateInstruction::Context context;
3537        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3538        RegisterInfo dwarf_reg;
3539        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3540        context.SetRegisterPlusOffset (dwarf_reg, offset);
3541
3542        // for i = 0 to 14
3543        for (int i = 0; i < 14; ++i)
3544        {
3545            // if registers<i> == '1' then
3546            if (BitIsSet (registers, i))
3547            {
3548                  // R[i] = MemA[address,4]; address = address + 4;
3549                  context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3550                  uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3551                  if (!success)
3552                      return false;
3553                  if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3554                      return false;
3555                  offset += addr_byte_size;
3556            }
3557        }
3558
3559        // if registers<15> == '1' then
3560        //     LoadWritePC(MemA[address,4]);
3561        if (BitIsSet (registers, 15))
3562        {
3563            context.SetRegisterPlusOffset (dwarf_reg, offset);
3564            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3565            if (!success)
3566                return false;
3567            // In ARMv5T and above, this is an interworking branch.
3568            if (!LoadWritePC(context, data))
3569                return false;
3570        }
3571
3572        // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3573        if (wback && BitIsClear (registers, n))
3574        {
3575            if (!success)
3576                return false;
3577
3578            offset = (addr_byte_size * BitCount (registers)) * -1;
3579            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3580            context.SetImmediateSigned (offset);
3581            addr_t addr = Rn + offset;
3582            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3583                return false;
3584        }
3585
3586        // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3587        if (wback && BitIsSet (registers, n))
3588            return WriteBits32Unknown (n);
3589    }
3590    return true;
3591}
3592
3593// LDMDB loads multiple registers from consecutive memory locations using an address from a base register.  The
3594// consecutive memory lcoations end just below this address, and the address of the lowest of those locations can
3595// be optionally written back to the base register.
3596bool
3597EmulateInstructionARM::EmulateLDMDB (const uint32_t opcode, const ARMEncoding encoding)
3598{
3599#if 0
3600    // ARM pseudo code...
3601    if ConditionPassed() then
3602        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
3603        address = R[n] - 4*BitCount(registers);
3604
3605        for i = 0 to 14
3606            if registers<i> == '1' then
3607                  R[i] = MemA[address,4]; address = address + 4;
3608        if registers<15> == '1' then
3609                  LoadWritePC(MemA[address,4]);
3610
3611        if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3612        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3613#endif
3614
3615    bool success = false;
3616
3617    if (ConditionPassed(opcode))
3618    {
3619        uint32_t n;
3620        uint32_t registers = 0;
3621        bool wback;
3622        const uint32_t addr_byte_size = GetAddressByteSize();
3623        switch (encoding)
3624        {
3625            case eEncodingT1:
3626                // n = UInt(Rn); registers = P:M:'0':register_list; wback = (W == '1');
3627                n = Bits32 (opcode, 19, 16);
3628                registers = Bits32 (opcode, 15, 0);
3629                registers = registers & 0xdfff;  // Make sure bit 13 is a zero.
3630                wback = BitIsSet (opcode, 21);
3631
3632                // if n == 15 || BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE;
3633                if ((n == 15)
3634                    || (BitCount (registers) < 2)
3635                    || (BitIsSet (opcode, 14) && BitIsSet (opcode, 15)))
3636                    return false;
3637
3638                // if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3639                if (BitIsSet (registers, 15) && InITBlock() && !LastInITBlock())
3640                    return false;
3641
3642                // if wback && registers<n> == '1' then UNPREDICTABLE;
3643                if (wback && BitIsSet (registers, n))
3644                    return false;
3645
3646                break;
3647
3648            case eEncodingA1:
3649                // n = UInt(Rn); registers = register_list; wback = (W == '1');
3650                n = Bits32 (opcode, 19, 16);
3651                registers = Bits32 (opcode, 15, 0);
3652                wback = BitIsSet (opcode, 21);
3653
3654                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3655                if ((n == 15) || (BitCount (registers) < 1))
3656                    return false;
3657
3658                break;
3659
3660            default:
3661                return false;
3662        }
3663
3664        // address = R[n] - 4*BitCount(registers);
3665
3666        int32_t offset = 0;
3667        addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3668
3669        if (!success)
3670            return false;
3671
3672        addr_t address = Rn - (addr_byte_size * BitCount (registers));
3673        EmulateInstruction::Context context;
3674        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3675        RegisterInfo dwarf_reg;
3676        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3677        context.SetRegisterPlusOffset (dwarf_reg, Rn - address);
3678
3679        for (int i = 0; i < 14; ++i)
3680        {
3681            if (BitIsSet (registers, i))
3682            {
3683                // R[i] = MemA[address,4]; address = address + 4;
3684                context.SetRegisterPlusOffset (dwarf_reg, Rn - (address + offset));
3685                uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3686                if (!success)
3687                    return false;
3688
3689                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3690                    return false;
3691
3692                offset += addr_byte_size;
3693            }
3694        }
3695
3696        // if registers<15> == '1' then
3697        //     LoadWritePC(MemA[address,4]);
3698        if (BitIsSet (registers, 15))
3699        {
3700            context.SetRegisterPlusOffset (dwarf_reg, offset);
3701            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3702            if (!success)
3703                return false;
3704            // In ARMv5T and above, this is an interworking branch.
3705            if (!LoadWritePC(context, data))
3706                return false;
3707        }
3708
3709        // if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
3710        if (wback && BitIsClear (registers, n))
3711        {
3712            if (!success)
3713                return false;
3714
3715            offset = (addr_byte_size * BitCount (registers)) * -1;
3716            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3717            context.SetImmediateSigned (offset);
3718            addr_t addr = Rn + offset;
3719            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3720                return false;
3721        }
3722
3723        // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3724        if (wback && BitIsSet (registers, n))
3725            return WriteBits32Unknown (n);
3726    }
3727    return true;
3728}
3729
3730// LDMIB loads multiple registers from consecutive memory locations using an address from a base register.  The
3731// consecutive memory locations start just above this address, and thea ddress of the last of those locations can
3732// optinoally be written back to the base register.
3733bool
3734EmulateInstructionARM::EmulateLDMIB (const uint32_t opcode, const ARMEncoding encoding)
3735{
3736#if 0
3737    if ConditionPassed() then
3738        EncodingSpecificOperations();
3739        address = R[n] + 4;
3740
3741        for i = 0 to 14
3742            if registers<i> == '1' then
3743                  R[i] = MemA[address,4]; address = address + 4;
3744        if registers<15> == '1' then
3745            LoadWritePC(MemA[address,4]);
3746
3747        if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3748        if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;
3749#endif
3750
3751    bool success = false;
3752
3753    if (ConditionPassed(opcode))
3754    {
3755        uint32_t n;
3756        uint32_t registers = 0;
3757        bool wback;
3758        const uint32_t addr_byte_size = GetAddressByteSize();
3759        switch (encoding)
3760        {
3761            case eEncodingA1:
3762                // n = UInt(Rn); registers = register_list; wback = (W == '1');
3763                n = Bits32 (opcode, 19, 16);
3764                registers = Bits32 (opcode, 15, 0);
3765                wback = BitIsSet (opcode, 21);
3766
3767                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
3768                if ((n == 15) || (BitCount (registers) < 1))
3769                    return false;
3770
3771                break;
3772            default:
3773                return false;
3774        }
3775        // address = R[n] + 4;
3776
3777        int32_t offset = 0;
3778        addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
3779
3780        if (!success)
3781            return false;
3782
3783        addr_t address = Rn + addr_byte_size;
3784
3785        EmulateInstruction::Context context;
3786        context.type = EmulateInstruction::eContextRegisterPlusOffset;
3787        RegisterInfo dwarf_reg;
3788        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, dwarf_reg);
3789        context.SetRegisterPlusOffset (dwarf_reg, offset);
3790
3791        for (int i = 0; i < 14; ++i)
3792        {
3793            if (BitIsSet (registers, i))
3794            {
3795                // R[i] = MemA[address,4]; address = address + 4;
3796
3797                context.SetRegisterPlusOffset (dwarf_reg, offset + addr_byte_size);
3798                uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3799                if (!success)
3800                    return false;
3801
3802                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + i, data))
3803                    return false;
3804
3805                offset += addr_byte_size;
3806            }
3807        }
3808
3809        // if registers<15> == '1' then
3810        //     LoadWritePC(MemA[address,4]);
3811        if (BitIsSet (registers, 15))
3812        {
3813            context.SetRegisterPlusOffset (dwarf_reg, offset);
3814            uint32_t data = MemARead (context, address + offset, addr_byte_size, 0, &success);
3815            if (!success)
3816                return false;
3817            // In ARMv5T and above, this is an interworking branch.
3818            if (!LoadWritePC(context, data))
3819                return false;
3820        }
3821
3822        // if wback && registers<n> == '0' then R[n] = R[n] + 4*BitCount(registers);
3823        if (wback && BitIsClear (registers, n))
3824        {
3825            if (!success)
3826                return false;
3827
3828            offset = addr_byte_size * BitCount (registers);
3829            context.type = EmulateInstruction::eContextAdjustBaseRegister;
3830            context.SetImmediateSigned (offset);
3831            addr_t addr = Rn + offset;
3832            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, addr))
3833                return false;
3834        }
3835
3836        // if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN; // Only possible for encoding A1
3837        if (wback && BitIsSet (registers, n))
3838            return WriteBits32Unknown (n);
3839    }
3840    return true;
3841}
3842
3843// Load Register (immediate) calculates an address from a base register value and
3844// an immediate offset, loads a word from memory, and writes to a register.
3845// LDR (immediate, Thumb)
3846bool
3847EmulateInstructionARM::EmulateLDRRtRnImm (const uint32_t opcode, const ARMEncoding encoding)
3848{
3849#if 0
3850    // ARM pseudo code...
3851    if (ConditionPassed())
3852    {
3853        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
3854        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
3855        address = if index then offset_addr else R[n];
3856        data = MemU[address,4];
3857        if wback then R[n] = offset_addr;
3858        if t == 15 then
3859            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
3860        elsif UnalignedSupport() || address<1:0> = '00' then
3861            R[t] = data;
3862        else R[t] = bits(32) UNKNOWN; // Can only apply before ARMv7
3863    }
3864#endif
3865
3866    bool success = false;
3867
3868    if (ConditionPassed(opcode))
3869    {
3870        uint32_t Rt; // the destination register
3871        uint32_t Rn; // the base register
3872        uint32_t imm32; // the immediate offset used to form the address
3873        addr_t offset_addr; // the offset address
3874        addr_t address; // the calculated address
3875        uint32_t data; // the literal data value from memory load
3876        bool add, index, wback;
3877        switch (encoding) {
3878            case eEncodingT1:
3879                Rt = Bits32(opcode, 2, 0);
3880                Rn = Bits32(opcode, 5, 3);
3881                imm32 = Bits32(opcode, 10, 6) << 2; // imm32 = ZeroExtend(imm5:'00', 32);
3882                // index = TRUE; add = TRUE; wback = FALSE
3883                add = true;
3884                index = true;
3885                wback = false;
3886
3887                break;
3888
3889            case eEncodingT2:
3890                // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
3891                Rt = Bits32 (opcode, 10, 8);
3892                Rn = 13;
3893                imm32 = Bits32 (opcode, 7, 0) << 2;
3894
3895                // index = TRUE; add = TRUE; wback = FALSE;
3896                index = true;
3897                add = true;
3898                wback = false;
3899
3900                break;
3901
3902            case eEncodingT3:
3903                // if Rn == '1111' then SEE LDR (literal);
3904                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
3905                Rt = Bits32 (opcode, 15, 12);
3906                Rn = Bits32 (opcode, 19, 16);
3907                imm32 = Bits32 (opcode, 11, 0);
3908
3909                // index = TRUE; add = TRUE; wback = FALSE;
3910                index = true;
3911                add = true;
3912                wback = false;
3913
3914                // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
3915                if ((Rt == 15) && InITBlock() && !LastInITBlock())
3916                    return false;
3917
3918                break;
3919
3920            case eEncodingT4:
3921                // if Rn == '1111' then SEE LDR (literal);
3922                // if P == '1' && U == '1' && W == '0' then SEE LDRT;
3923                // if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP;
3924                // if P == '0' && W == '0' then UNDEFINED;
3925                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
3926                    return false;
3927
3928                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
3929                Rt = Bits32 (opcode, 15, 12);
3930                Rn = Bits32 (opcode, 19, 16);
3931                imm32 = Bits32 (opcode, 7, 0);
3932
3933                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
3934                index = BitIsSet (opcode, 10);
3935                add = BitIsSet (opcode, 9);
3936                wback = BitIsSet (opcode, 8);
3937
3938                // if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE;
3939                if ((wback && (Rn == Rt)) || ((Rt == 15) && InITBlock() && !LastInITBlock()))
3940                    return false;
3941
3942                break;
3943
3944            default:
3945                return false;
3946        }
3947        uint32_t base = ReadCoreReg (Rn, &success);
3948        if (!success)
3949            return false;
3950        if (add)
3951            offset_addr = base + imm32;
3952        else
3953            offset_addr = base - imm32;
3954
3955        address = (index ? offset_addr : base);
3956
3957        RegisterInfo base_reg;
3958        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + Rn, base_reg);
3959        if (wback)
3960        {
3961            EmulateInstruction::Context ctx;
3962            ctx.type = EmulateInstruction::eContextAdjustBaseRegister;
3963            ctx.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3964
3965            if (!WriteRegisterUnsigned (ctx, eRegisterKindDWARF, dwarf_r0 + Rn, offset_addr))
3966                return false;
3967        }
3968
3969        // Prepare to write to the Rt register.
3970        EmulateInstruction::Context context;
3971        context.type = EmulateInstruction::eContextRegisterLoad;
3972        context.SetRegisterPlusOffset (base_reg, (int32_t) (offset_addr - base));
3973
3974        // Read memory from the address.
3975        data = MemURead(context, address, 4, 0, &success);
3976        if (!success)
3977            return false;
3978
3979        if (Rt == 15)
3980        {
3981            if (Bits32(address, 1, 0) == 0)
3982            {
3983                if (!LoadWritePC(context, data))
3984                    return false;
3985            }
3986            else
3987                return false;
3988        }
3989        else if (UnalignedSupport() || Bits32(address, 1, 0) == 0)
3990        {
3991            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + Rt, data))
3992                return false;
3993        }
3994        else
3995            WriteBits32Unknown (Rt);
3996    }
3997    return true;
3998}
3999
4000// STM (Store Multiple Increment After) stores multiple registers to consecutive memory locations using an address
4001// from a base register.  The consecutive memory locations start at this address, and teh address just above the last
4002// of those locations can optionally be written back to the base register.
4003bool
4004EmulateInstructionARM::EmulateSTM (const uint32_t opcode, const ARMEncoding encoding)
4005{
4006#if 0
4007    if ConditionPassed() then
4008        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4009        address = R[n];
4010
4011        for i = 0 to 14
4012            if registers<i> == '1' then
4013                if i == n && wback && i != LowestSetBit(registers) then
4014                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4015                else
4016                    MemA[address,4] = R[i];
4017                address = address + 4;
4018
4019        if registers<15> == '1' then // Only possible for encoding A1
4020            MemA[address,4] = PCStoreValue();
4021        if wback then R[n] = R[n] + 4*BitCount(registers);
4022#endif
4023
4024    bool success = false;
4025
4026    if (ConditionPassed(opcode))
4027    {
4028        uint32_t n;
4029        uint32_t registers = 0;
4030        bool wback;
4031        const uint32_t addr_byte_size = GetAddressByteSize();
4032
4033        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4034        switch (encoding)
4035        {
4036            case eEncodingT1:
4037                // n = UInt(Rn); registers = '00000000':register_list; wback = TRUE;
4038                n = Bits32 (opcode, 10, 8);
4039                registers = Bits32 (opcode, 7, 0);
4040                registers = registers & 0x00ff;  // Make sure the top 8 bits are zeros.
4041                wback = true;
4042
4043                // if BitCount(registers) < 1 then UNPREDICTABLE;
4044                if (BitCount (registers) < 1)
4045                    return false;
4046
4047                break;
4048
4049            case eEncodingT2:
4050                // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4051                n = Bits32 (opcode, 19, 16);
4052                registers = Bits32 (opcode, 15, 0);
4053                registers = registers & 0x5fff; // Make sure bits 15 & 13 are zeros.
4054                wback = BitIsSet (opcode, 21);
4055
4056                // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4057                if ((n == 15) || (BitCount (registers) < 2))
4058                    return false;
4059
4060                // if wback && registers<n> == '1' then UNPREDICTABLE;
4061                if (wback && BitIsSet (registers, n))
4062                    return false;
4063
4064                break;
4065
4066            case eEncodingA1:
4067                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4068                n = Bits32 (opcode, 19, 16);
4069                registers = Bits32 (opcode, 15, 0);
4070                wback = BitIsSet (opcode, 21);
4071
4072                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4073                if ((n == 15) || (BitCount (registers) < 1))
4074                    return false;
4075
4076                break;
4077
4078            default:
4079                return false;
4080        }
4081
4082        // address = R[n];
4083        int32_t offset = 0;
4084        const addr_t address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4085        if (!success)
4086            return false;
4087
4088        EmulateInstruction::Context context;
4089        context.type = EmulateInstruction::eContextRegisterStore;
4090        RegisterInfo base_reg;
4091        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4092
4093        // for i = 0 to 14
4094        int lowest_set_bit = 14;
4095        for (int i = 0; i < 14; ++i)
4096        {
4097            // if registers<i> == '1' then
4098            if (BitIsSet (registers, i))
4099            {
4100                  if (i < lowest_set_bit)
4101                      lowest_set_bit = i;
4102                  // if i == n && wback && i != LowestSetBit(registers) then
4103                  if ((i == n) && wback && (i != lowest_set_bit))
4104                      // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encodings T1 and A1
4105                      WriteBits32UnknownToMemory (address + offset);
4106                  else
4107                  {
4108                     // MemA[address,4] = R[i];
4109                      uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4110                      if (!success)
4111                          return false;
4112
4113                      RegisterInfo data_reg;
4114                      GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4115                      context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4116                      if (!MemAWrite (context, address + offset, data, addr_byte_size))
4117                          return false;
4118                  }
4119
4120                  // address = address + 4;
4121                  offset += addr_byte_size;
4122            }
4123        }
4124
4125        // if registers<15> == '1' then // Only possible for encoding A1
4126        //     MemA[address,4] = PCStoreValue();
4127        if (BitIsSet (registers, 15))
4128        {
4129            RegisterInfo pc_reg;
4130            GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4131            context.SetRegisterPlusOffset (pc_reg, 8);
4132            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4133            if (!success)
4134                return false;
4135
4136            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4137                return false;
4138        }
4139
4140        // if wback then R[n] = R[n] + 4*BitCount(registers);
4141        if (wback)
4142        {
4143            offset = addr_byte_size * BitCount (registers);
4144            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4145            context.SetImmediateSigned (offset);
4146            addr_t data = address + offset;
4147            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4148                return false;
4149        }
4150    }
4151    return true;
4152}
4153
4154// STMDA (Store Multiple Decrement After) stores multiple registers to consecutive memory locations using an address
4155// from a base register.  The consecutive memory locations end at this address, and the address just below the lowest
4156// of those locations can optionally be written back to the base register.
4157bool
4158EmulateInstructionARM::EmulateSTMDA (const uint32_t opcode, const ARMEncoding encoding)
4159{
4160#if 0
4161    if ConditionPassed() then
4162        EncodingSpecificOperations();
4163        address = R[n] - 4*BitCount(registers) + 4;
4164
4165        for i = 0 to 14
4166            if registers<i> == '1' then
4167                if i == n && wback && i != LowestSetBit(registers) then
4168                    MemA[address,4] = bits(32) UNKNOWN;
4169                else
4170                    MemA[address,4] = R[i];
4171                address = address + 4;
4172
4173        if registers<15> == '1' then
4174            MemA[address,4] = PCStoreValue();
4175
4176        if wback then R[n] = R[n] - 4*BitCount(registers);
4177#endif
4178
4179    bool success = false;
4180
4181    if (ConditionPassed(opcode))
4182    {
4183        uint32_t n;
4184        uint32_t registers = 0;
4185        bool wback;
4186        const uint32_t addr_byte_size = GetAddressByteSize();
4187
4188        // EncodingSpecificOperations();
4189        switch (encoding)
4190        {
4191            case eEncodingA1:
4192                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4193                n = Bits32 (opcode, 19, 16);
4194                registers = Bits32 (opcode, 15, 0);
4195                wback = BitIsSet (opcode, 21);
4196
4197                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4198                if ((n == 15) || (BitCount (registers) < 1))
4199                    return false;
4200                break;
4201            default:
4202                return false;
4203        }
4204
4205        // address = R[n] - 4*BitCount(registers) + 4;
4206        int32_t offset = 0;
4207        addr_t Rn = ReadCoreReg (n, &success);
4208        if (!success)
4209            return false;
4210
4211        addr_t address = Rn - (addr_byte_size * BitCount (registers)) + 4;
4212
4213        EmulateInstruction::Context context;
4214        context.type = EmulateInstruction::eContextRegisterStore;
4215        RegisterInfo base_reg;
4216        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4217
4218        // for i = 0 to 14
4219        int lowest_bit_set = 14;
4220        for (int i = 0; i < 14; ++i)
4221        {
4222            // if registers<i> == '1' then
4223            if (BitIsSet (registers, i))
4224            {
4225                if (i < lowest_bit_set)
4226                    lowest_bit_set = i;
4227                //if i == n && wback && i != LowestSetBit(registers) then
4228                if ((i == n) && wback && (i != lowest_bit_set))
4229                    // MemA[address,4] = bits(32) UNKNOWN;
4230                    WriteBits32UnknownToMemory (address + offset);
4231                else
4232                {
4233                    // MemA[address,4] = R[i];
4234                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4235                    if (!success)
4236                        return false;
4237
4238                    RegisterInfo data_reg;
4239                    GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4240                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4241                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
4242                        return false;
4243                }
4244
4245                // address = address + 4;
4246                offset += addr_byte_size;
4247            }
4248        }
4249
4250        // if registers<15> == '1' then
4251        //    MemA[address,4] = PCStoreValue();
4252        if (BitIsSet (registers, 15))
4253        {
4254            RegisterInfo pc_reg;
4255            GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4256            context.SetRegisterPlusOffset (pc_reg, 8);
4257            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4258            if (!success)
4259                return false;
4260
4261            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4262                return false;
4263        }
4264
4265        // if wback then R[n] = R[n] - 4*BitCount(registers);
4266        if (wback)
4267        {
4268            offset = (addr_byte_size * BitCount (registers)) * -1;
4269            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4270            context.SetImmediateSigned (offset);
4271            addr_t data = Rn + offset;
4272            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4273                return false;
4274        }
4275    }
4276    return true;
4277}
4278
4279// STMDB (Store Multiple Decrement Before) stores multiple registers to consecutive memory locations using an address
4280// from a base register.  The consecutive memory locations end just below this address, and the address of the first of
4281// those locations can optionally be written back to the base register.
4282bool
4283EmulateInstructionARM::EmulateSTMDB (const uint32_t opcode, const ARMEncoding encoding)
4284{
4285#if 0
4286    if ConditionPassed() then
4287        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4288        address = R[n] - 4*BitCount(registers);
4289
4290        for i = 0 to 14
4291            if registers<i> == '1' then
4292                if i == n && wback && i != LowestSetBit(registers) then
4293                    MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4294                else
4295                    MemA[address,4] = R[i];
4296                address = address + 4;
4297
4298        if registers<15> == '1' then // Only possible for encoding A1
4299            MemA[address,4] = PCStoreValue();
4300
4301        if wback then R[n] = R[n] - 4*BitCount(registers);
4302#endif
4303
4304
4305    bool success = false;
4306
4307    if (ConditionPassed(opcode))
4308    {
4309        uint32_t n;
4310        uint32_t registers = 0;
4311        bool wback;
4312        const uint32_t addr_byte_size = GetAddressByteSize();
4313
4314        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4315        switch (encoding)
4316        {
4317            case eEncodingT1:
4318                // if W == '1' && Rn == '1101' then SEE PUSH;
4319                if ((BitIsSet (opcode, 21)) && (Bits32 (opcode, 19, 16) == 13))
4320                {
4321                    // See PUSH
4322                }
4323                // n = UInt(Rn); registers = '0':M:'0':register_list; wback = (W == '1');
4324                n = Bits32 (opcode, 19, 16);
4325                registers = Bits32 (opcode, 15, 0);
4326                registers = registers & 0x5fff;  // Make sure bits 15 & 13 are zeros.
4327                wback = BitIsSet (opcode, 21);
4328                // if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
4329                if ((n == 15) || BitCount (registers) < 2)
4330                    return false;
4331                // if wback && registers<n> == '1' then UNPREDICTABLE;
4332                if (wback && BitIsSet (registers, n))
4333                    return false;
4334                break;
4335
4336            case eEncodingA1:
4337                // if W == '1' && Rn == '1101� && BitCount(register_list) >= 2 then SEE PUSH;
4338                if (BitIsSet (opcode, 21) && (Bits32 (opcode, 19, 16) == 13) && BitCount (Bits32 (opcode, 15, 0)) >= 2)
4339                {
4340                    // See Push
4341                }
4342                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4343                n = Bits32 (opcode, 19, 16);
4344                registers = Bits32 (opcode, 15, 0);
4345                wback = BitIsSet (opcode, 21);
4346                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4347                if ((n == 15) || BitCount (registers) < 1)
4348                    return false;
4349                break;
4350
4351            default:
4352                return false;
4353        }
4354
4355        // address = R[n] - 4*BitCount(registers);
4356
4357        int32_t offset = 0;
4358        addr_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4359        if (!success)
4360        return false;
4361
4362        addr_t address = Rn - (addr_byte_size * BitCount (registers));
4363
4364        EmulateInstruction::Context context;
4365        context.type = EmulateInstruction::eContextRegisterStore;
4366        RegisterInfo base_reg;
4367        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4368
4369        // for i = 0 to 14
4370        uint32_t lowest_set_bit = 14;
4371        for (int i = 0; i < 14; ++i)
4372        {
4373            // if registers<i> == '1' then
4374            if (BitIsSet (registers, i))
4375            {
4376                if (i < lowest_set_bit)
4377                    lowest_set_bit = i;
4378                // if i == n && wback && i != LowestSetBit(registers) then
4379                if ((i == n) && wback && (i != lowest_set_bit))
4380                    // MemA[address,4] = bits(32) UNKNOWN; // Only possible for encoding A1
4381                    WriteBits32UnknownToMemory (address + offset);
4382                else
4383                {
4384                    // MemA[address,4] = R[i];
4385                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4386                    if (!success)
4387                        return false;
4388
4389                    RegisterInfo data_reg;
4390                    GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4391                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, Rn - (address + offset));
4392                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
4393                        return false;
4394                }
4395
4396                // address = address + 4;
4397                offset += addr_byte_size;
4398            }
4399        }
4400
4401        // if registers<15> == '1' then // Only possible for encoding A1
4402        //     MemA[address,4] = PCStoreValue();
4403        if (BitIsSet (registers, 15))
4404        {
4405            RegisterInfo pc_reg;
4406            GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4407            context.SetRegisterPlusOffset (pc_reg, 8);
4408            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4409            if (!success)
4410                return false;
4411
4412            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4413                return false;
4414        }
4415
4416        // if wback then R[n] = R[n] - 4*BitCount(registers);
4417        if (wback)
4418        {
4419            offset = (addr_byte_size * BitCount (registers)) * -1;
4420            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4421            context.SetImmediateSigned (offset);
4422            addr_t data = Rn + offset;
4423            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4424                return false;
4425        }
4426    }
4427    return true;
4428}
4429
4430// STMIB (Store Multiple Increment Before) stores multiple registers to consecutive memory locations using an address
4431// from a base register.  The consecutive memory locations start just above this address, and the address of the last
4432// of those locations can optionally be written back to the base register.
4433bool
4434EmulateInstructionARM::EmulateSTMIB (const uint32_t opcode, const ARMEncoding encoding)
4435{
4436#if 0
4437    if ConditionPassed() then
4438        EncodingSpecificOperations();
4439        address = R[n] + 4;
4440
4441        for i = 0 to 14
4442            if registers<i> == '1' then
4443                if i == n && wback && i != LowestSetBit(registers) then
4444                    MemA[address,4] = bits(32) UNKNOWN;
4445                else
4446                    MemA[address,4] = R[i];
4447                address = address + 4;
4448
4449        if registers<15> == '1' then
4450            MemA[address,4] = PCStoreValue();
4451
4452        if wback then R[n] = R[n] + 4*BitCount(registers);
4453#endif
4454
4455    bool success = false;
4456
4457    if (ConditionPassed(opcode))
4458    {
4459        uint32_t n;
4460        uint32_t registers = 0;
4461        bool wback;
4462        const uint32_t addr_byte_size = GetAddressByteSize();
4463
4464        // EncodingSpecificOperations();
4465        switch (encoding)
4466        {
4467            case eEncodingA1:
4468                // n = UInt(Rn); registers = register_list; wback = (W == '1');
4469                n = Bits32 (opcode, 19, 16);
4470                registers = Bits32 (opcode, 15, 0);
4471                wback = BitIsSet (opcode, 21);
4472
4473                // if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
4474                if ((n == 15) && (BitCount (registers) < 1))
4475                    return false;
4476                break;
4477            default:
4478                return false;
4479        }
4480        // address = R[n] + 4;
4481
4482        int32_t offset = 0;
4483        addr_t Rn = ReadCoreReg (n, &success);
4484        if (!success)
4485            return false;
4486
4487        addr_t address = Rn + addr_byte_size;
4488
4489        EmulateInstruction::Context context;
4490        context.type = EmulateInstruction::eContextRegisterStore;
4491        RegisterInfo base_reg;
4492        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4493
4494        uint32_t lowest_set_bit = 14;
4495        // for i = 0 to 14
4496        for (int i = 0; i < 14; ++i)
4497        {
4498            // if registers<i> == '1' then
4499            if (BitIsSet (registers, i))
4500            {
4501                if (i < lowest_set_bit)
4502                    lowest_set_bit = i;
4503                // if i == n && wback && i != LowestSetBit(registers) then
4504                if ((i == n) && wback && (i != lowest_set_bit))
4505                    // MemA[address,4] = bits(32) UNKNOWN;
4506                    WriteBits32UnknownToMemory (address + offset);
4507                // else
4508                else
4509                {
4510                    // MemA[address,4] = R[i];
4511                    uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + i, 0, &success);
4512                    if (!success)
4513                        return false;
4514
4515                    RegisterInfo data_reg;
4516                    GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + i, data_reg);
4517                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset + addr_byte_size);
4518                    if (!MemAWrite (context, address + offset, data, addr_byte_size))
4519                        return false;
4520                }
4521
4522                // address = address + 4;
4523                offset += addr_byte_size;
4524            }
4525        }
4526
4527        // if registers<15> == '1' then
4528            // MemA[address,4] = PCStoreValue();
4529        if (BitIsSet (registers, 15))
4530        {
4531            RegisterInfo pc_reg;
4532            GetRegisterInfo (eRegisterKindDWARF, dwarf_pc, pc_reg);
4533            context.SetRegisterPlusOffset (pc_reg, 8);
4534            const uint32_t pc = ReadCoreReg (PC_REG, &success);
4535            if (!success)
4536            return false;
4537
4538            if (!MemAWrite (context, address + offset, pc, addr_byte_size))
4539                return false;
4540        }
4541
4542        // if wback then R[n] = R[n] + 4*BitCount(registers);
4543        if (wback)
4544        {
4545            offset = addr_byte_size * BitCount (registers);
4546            context.type = EmulateInstruction::eContextAdjustBaseRegister;
4547            context.SetImmediateSigned (offset);
4548            addr_t data = Rn + offset;
4549            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, data))
4550                return false;
4551        }
4552    }
4553    return true;
4554}
4555
4556// STR (store immediate) calcualtes an address from a base register value and an immediate offset, and stores a word
4557// from a register to memory.  It can use offset, post-indexed, or pre-indexed addressing.
4558bool
4559EmulateInstructionARM::EmulateSTRThumb (const uint32_t opcode, const ARMEncoding encoding)
4560{
4561#if 0
4562    if ConditionPassed() then
4563        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4564        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4565        address = if index then offset_addr else R[n];
4566        if UnalignedSupport() || address<1:0> == '00' then
4567            MemU[address,4] = R[t];
4568        else // Can only occur before ARMv7
4569            MemU[address,4] = bits(32) UNKNOWN;
4570        if wback then R[n] = offset_addr;
4571#endif
4572
4573    bool success = false;
4574
4575    if (ConditionPassed(opcode))
4576    {
4577        const uint32_t addr_byte_size = GetAddressByteSize();
4578
4579        uint32_t t;
4580        uint32_t n;
4581        uint32_t imm32;
4582        bool index;
4583        bool add;
4584        bool wback;
4585        // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4586        switch (encoding)
4587        {
4588            case eEncodingT1:
4589                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'00', 32);
4590                t = Bits32 (opcode, 2, 0);
4591                n = Bits32 (opcode, 5, 3);
4592                imm32 = Bits32 (opcode, 10, 6) << 2;
4593
4594                // index = TRUE; add = TRUE; wback = FALSE;
4595                index = true;
4596                add = false;
4597                wback = false;
4598                break;
4599
4600            case eEncodingT2:
4601                // t = UInt(Rt); n = 13; imm32 = ZeroExtend(imm8:'00', 32);
4602                t = Bits32 (opcode, 10, 8);
4603                n = 13;
4604                imm32 = Bits32 (opcode, 7, 0) << 2;
4605
4606                // index = TRUE; add = TRUE; wback = FALSE;
4607                index = true;
4608                add = true;
4609                wback = false;
4610                break;
4611
4612            case eEncodingT3:
4613                // if Rn == '1111' then UNDEFINED;
4614                if (Bits32 (opcode, 19, 16) == 15)
4615                    return false;
4616
4617                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4618                t = Bits32 (opcode, 15, 12);
4619                n = Bits32 (opcode, 19, 16);
4620                imm32 = Bits32 (opcode, 11, 0);
4621
4622                // index = TRUE; add = TRUE; wback = FALSE;
4623                index = true;
4624                add = true;
4625                wback = false;
4626
4627                // if t == 15 then UNPREDICTABLE;
4628                if (t == 15)
4629                    return false;
4630                break;
4631
4632            case eEncodingT4:
4633                // if P == '1' && U == '1' && W == '0' then SEE STRT;
4634                // if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH;
4635                // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4636                if ((Bits32 (opcode, 19, 16) == 15)
4637                      || (BitIsClear (opcode, 10) && BitIsClear (opcode, 8)))
4638                    return false;
4639
4640                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4641                t = Bits32 (opcode, 15, 12);
4642                n = Bits32 (opcode, 19, 16);
4643                imm32 = Bits32 (opcode, 7, 0);
4644
4645                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4646                index = BitIsSet (opcode, 10);
4647                add = BitIsSet (opcode, 9);
4648                wback = BitIsSet (opcode, 8);
4649
4650                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
4651                if ((t == 15) || (wback && (n == t)))
4652                    return false;
4653                break;
4654
4655            default:
4656                return false;
4657        }
4658
4659        addr_t offset_addr;
4660        addr_t address;
4661
4662        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4663        uint32_t base_address = ReadCoreReg (n, &success);
4664        if (!success)
4665            return false;
4666
4667        if (add)
4668            offset_addr = base_address + imm32;
4669        else
4670            offset_addr = base_address - imm32;
4671
4672        // address = if index then offset_addr else R[n];
4673        if (index)
4674            address = offset_addr;
4675        else
4676            address = base_address;
4677
4678        EmulateInstruction::Context context;
4679        context.type = eContextRegisterStore;
4680        RegisterInfo base_reg;
4681        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
4682
4683        // if UnalignedSupport() || address<1:0> == '00' then
4684        if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
4685        {
4686            // MemU[address,4] = R[t];
4687            uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4688            if (!success)
4689                return false;
4690
4691            RegisterInfo data_reg;
4692            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4693            int32_t offset = address - base_address;
4694            context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, offset);
4695            if (!MemUWrite (context, address, data, addr_byte_size))
4696                return false;
4697        }
4698        else
4699        {
4700            // MemU[address,4] = bits(32) UNKNOWN;
4701            WriteBits32UnknownToMemory (address);
4702        }
4703
4704        // if wback then R[n] = offset_addr;
4705        if (wback)
4706        {
4707            context.type = eContextRegisterLoad;
4708            context.SetAddress (offset_addr);
4709            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4710                return false;
4711        }
4712    }
4713    return true;
4714}
4715
4716// STR (Store Register) calculates an address from a base register value and an offset register value, stores a
4717// word from a register to memory.   The offset register value can optionally be shifted.
4718bool
4719EmulateInstructionARM::EmulateSTRRegister (const uint32_t opcode, const ARMEncoding encoding)
4720{
4721#if 0
4722    if ConditionPassed() then
4723        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4724        offset = Shift(R[m], shift_t, shift_n, APSR.C);
4725        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4726        address = if index then offset_addr else R[n];
4727        if t == 15 then // Only possible for encoding A1
4728            data = PCStoreValue();
4729        else
4730            data = R[t];
4731        if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4732            MemU[address,4] = data;
4733        else // Can only occur before ARMv7
4734            MemU[address,4] = bits(32) UNKNOWN;
4735        if wback then R[n] = offset_addr;
4736#endif
4737
4738    bool success = false;
4739
4740    if (ConditionPassed(opcode))
4741    {
4742        const uint32_t addr_byte_size = GetAddressByteSize();
4743
4744        uint32_t t;
4745        uint32_t n;
4746        uint32_t m;
4747        ARM_ShifterType shift_t;
4748        uint32_t shift_n;
4749        bool index;
4750        bool add;
4751        bool wback;
4752
4753        // EncodingSpecificOperations (); NullCheckIfThumbEE(n);
4754        switch (encoding)
4755        {
4756            case eEncodingT1:
4757                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
4758                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4759                t = Bits32 (opcode, 2, 0);
4760                n = Bits32 (opcode, 5, 3);
4761                m = Bits32 (opcode, 8, 6);
4762
4763                // index = TRUE; add = TRUE; wback = FALSE;
4764                index = true;
4765                add = true;
4766                wback = false;
4767
4768                // (shift_t, shift_n) = (SRType_LSL, 0);
4769                shift_t = SRType_LSL;
4770                shift_n = 0;
4771                break;
4772
4773            case eEncodingT2:
4774                // if Rn == '1111' then UNDEFINED;
4775                if (Bits32 (opcode, 19, 16) == 15)
4776                    return false;
4777
4778                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4779                t = Bits32 (opcode, 15, 12);
4780                n = Bits32 (opcode, 19, 16);
4781                m = Bits32 (opcode, 3, 0);
4782
4783                // index = TRUE; add = TRUE; wback = FALSE;
4784                index = true;
4785                add = true;
4786                wback = false;
4787
4788                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
4789                shift_t = SRType_LSL;
4790                shift_n = Bits32 (opcode, 5, 4);
4791
4792                // if t == 15 || BadReg(m) then UNPREDICTABLE;
4793                if ((t == 15) || (BadReg (m)))
4794                    return false;
4795                break;
4796
4797            case eEncodingA1:
4798            {
4799                // if P == '0' && W == '1' then SEE STRT;
4800                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
4801                t = Bits32 (opcode, 15, 12);
4802                n = Bits32 (opcode, 19, 16);
4803                m = Bits32 (opcode, 3, 0);
4804
4805                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
4806                index = BitIsSet (opcode, 24);
4807                add = BitIsSet (opcode, 23);
4808                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
4809
4810                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
4811                uint32_t typ = Bits32 (opcode, 6, 5);
4812                uint32_t imm5 = Bits32 (opcode, 11, 7);
4813                shift_n = DecodeImmShift(typ, imm5, shift_t);
4814
4815                // if m == 15 then UNPREDICTABLE;
4816                if (m == 15)
4817                    return false;
4818
4819                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
4820                if (wback && ((n == 15) || (n == t)))
4821                    return false;
4822
4823                break;
4824            }
4825            default:
4826                return false;
4827        }
4828
4829        addr_t offset_addr;
4830        addr_t address;
4831        int32_t offset = 0;
4832
4833        addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4834        if (!success)
4835            return false;
4836
4837        uint32_t Rm_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
4838        if (!success)
4839            return false;
4840
4841        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
4842        offset = Shift (Rm_data, shift_t, shift_n, APSR_C, &success);
4843        if (!success)
4844            return false;
4845
4846        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
4847        if (add)
4848            offset_addr = base_address + offset;
4849        else
4850            offset_addr = base_address - offset;
4851
4852        // address = if index then offset_addr else R[n];
4853        if (index)
4854            address = offset_addr;
4855        else
4856            address = base_address;
4857
4858        uint32_t data;
4859        // if t == 15 then // Only possible for encoding A1
4860        if (t == 15)
4861            // data = PCStoreValue();
4862            data = ReadCoreReg (PC_REG, &success);
4863        else
4864            // data = R[t];
4865            data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
4866
4867        if (!success)
4868            return false;
4869
4870        EmulateInstruction::Context context;
4871        context.type = eContextRegisterStore;
4872
4873        // if UnalignedSupport() || address<1:0> == '00' || CurrentInstrSet() == InstrSet_ARM then
4874        if (UnalignedSupport ()
4875            || (BitIsClear (address, 1) && BitIsClear (address, 0))
4876            || CurrentInstrSet() == eModeARM)
4877        {
4878            // MemU[address,4] = data;
4879
4880            RegisterInfo base_reg;
4881            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 +  n, base_reg);
4882
4883            RegisterInfo data_reg;
4884            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
4885
4886            context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
4887            if (!MemUWrite (context, address, data, addr_byte_size))
4888                return false;
4889
4890        }
4891        else
4892            // MemU[address,4] = bits(32) UNKNOWN;
4893            WriteBits32UnknownToMemory (address);
4894
4895        // if wback then R[n] = offset_addr;
4896        if (wback)
4897        {
4898            context.type = eContextRegisterLoad;
4899            context.SetAddress (offset_addr);
4900            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
4901                return false;
4902        }
4903
4904    }
4905    return true;
4906}
4907
4908bool
4909EmulateInstructionARM::EmulateSTRBThumb (const uint32_t opcode, const ARMEncoding encoding)
4910{
4911#if 0
4912    if ConditionPassed() then
4913        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4914        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4915        address = if index then offset_addr else R[n];
4916        MemU[address,1] = R[t]<7:0>;
4917        if wback then R[n] = offset_addr;
4918#endif
4919
4920
4921    bool success = false;
4922
4923    if (ConditionPassed(opcode))
4924    {
4925        uint32_t t;
4926        uint32_t n;
4927        uint32_t imm32;
4928        bool index;
4929        bool add;
4930        bool wback;
4931        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
4932        switch (encoding)
4933        {
4934            case eEncodingT1:
4935                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
4936                t = Bits32 (opcode, 2, 0);
4937                n = Bits32 (opcode, 5, 3);
4938                imm32 = Bits32 (opcode, 10, 6);
4939
4940                // index = TRUE; add = TRUE; wback = FALSE;
4941                index = true;
4942                add = true;
4943                wback = false;
4944                break;
4945
4946            case eEncodingT2:
4947                // if Rn == '1111' then UNDEFINED;
4948                if (Bits32 (opcode, 19, 16) == 15)
4949                    return false;
4950
4951                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
4952                t = Bits32 (opcode, 15, 12);
4953                n = Bits32 (opcode, 19, 16);
4954                imm32 = Bits32 (opcode, 11, 0);
4955
4956                // index = TRUE; add = TRUE; wback = FALSE;
4957                index = true;
4958                add = true;
4959                wback = false;
4960
4961                // if BadReg(t) then UNPREDICTABLE;
4962                if (BadReg (t))
4963                    return false;
4964                break;
4965
4966            case eEncodingT3:
4967                // if P == '1' && U == '1' && W == '0' then SEE STRBT;
4968                // if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED;
4969                if (Bits32 (opcode, 19, 16) == 15)
4970                    return false;
4971
4972                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
4973                t = Bits32 (opcode, 15, 12);
4974                n = Bits32 (opcode, 19, 16);
4975                imm32 = Bits32 (opcode, 7, 0);
4976
4977                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
4978                index = BitIsSet (opcode, 10);
4979                add = BitIsSet (opcode, 9);
4980                wback = BitIsSet (opcode, 8);
4981
4982                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE
4983                if ((BadReg (t)) || (wback && (n == t)))
4984                    return false;
4985                break;
4986
4987            default:
4988                return false;
4989        }
4990
4991        addr_t offset_addr;
4992        addr_t address;
4993        addr_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
4994        if (!success)
4995            return false;
4996
4997        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
4998        if (add)
4999            offset_addr = base_address + imm32;
5000        else
5001            offset_addr = base_address - imm32;
5002
5003        // address = if index then offset_addr else R[n];
5004        if (index)
5005            address = offset_addr;
5006        else
5007            address = base_address;
5008
5009        // MemU[address,1] = R[t]<7:0>
5010        RegisterInfo base_reg;
5011        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5012
5013        RegisterInfo data_reg;
5014        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5015
5016        EmulateInstruction::Context context;
5017        context.type = eContextRegisterStore;
5018        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - base_address);
5019
5020        uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
5021        if (!success)
5022            return false;
5023
5024        data = Bits32 (data, 7, 0);
5025
5026        if (!MemUWrite (context, address, data, 1))
5027            return false;
5028
5029        // if wback then R[n] = offset_addr;
5030        if (wback)
5031        {
5032            context.type = eContextRegisterLoad;
5033            context.SetAddress (offset_addr);
5034            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5035                return false;
5036        }
5037
5038    }
5039
5040    return true;
5041}
5042
5043// STRH (register) calculates an address from a base register value and an offset register value, and stores a
5044// halfword from a register to memory.  The offset register alue can be shifted left by 0, 1, 2, or 3 bits.
5045bool
5046EmulateInstructionARM::EmulateSTRHRegister (const uint32_t opcode, const ARMEncoding encoding)
5047{
5048#if 0
5049    if ConditionPassed() then
5050        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5051        offset = Shift(R[m], shift_t, shift_n, APSR.C);
5052        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5053        address = if index then offset_addr else R[n];
5054        if UnalignedSupport() || address<0> == '0' then
5055            MemU[address,2] = R[t]<15:0>;
5056        else // Can only occur before ARMv7
5057            MemU[address,2] = bits(16) UNKNOWN;
5058        if wback then R[n] = offset_addr;
5059#endif
5060
5061    bool success = false;
5062
5063    if (ConditionPassed(opcode))
5064    {
5065        uint32_t t;
5066        uint32_t n;
5067        uint32_t m;
5068        bool index;
5069        bool add;
5070        bool wback;
5071        ARM_ShifterType shift_t;
5072        uint32_t shift_n;
5073
5074        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5075        switch (encoding)
5076        {
5077            case eEncodingT1:
5078                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5079                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5080                t = Bits32 (opcode, 2, 0);
5081                n = Bits32 (opcode, 5, 3);
5082                m = Bits32 (opcode, 8, 6);
5083
5084                // index = TRUE; add = TRUE; wback = FALSE;
5085                index = true;
5086                add = true;
5087                wback = false;
5088
5089                // (shift_t, shift_n) = (SRType_LSL, 0);
5090                shift_t = SRType_LSL;
5091                shift_n = 0;
5092
5093                break;
5094
5095            case eEncodingT2:
5096                // if Rn == '1111' then UNDEFINED;
5097                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5098                t = Bits32 (opcode, 15, 12);
5099                n = Bits32 (opcode, 19, 16);
5100                m = Bits32 (opcode, 3, 0);
5101                if (n == 15)
5102                    return false;
5103
5104                // index = TRUE; add = TRUE; wback = FALSE;
5105                index = true;
5106                add = true;
5107                wback = false;
5108
5109                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5110                shift_t = SRType_LSL;
5111                shift_n = Bits32 (opcode, 5, 4);
5112
5113                // if BadReg(t) || BadReg(m) then UNPREDICTABLE;
5114                if (BadReg (t) || BadReg (m))
5115                    return false;
5116
5117                break;
5118
5119            case eEncodingA1:
5120                // if P == '0' && W == '1' then SEE STRHT;
5121                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5122                t = Bits32 (opcode, 15, 12);
5123                n = Bits32 (opcode, 19, 16);
5124                m = Bits32 (opcode, 3, 0);
5125
5126                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5127                index = BitIsSet (opcode, 24);
5128                add = BitIsSet (opcode, 23);
5129                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5130
5131                // (shift_t, shift_n) = (SRType_LSL, 0);
5132                shift_t = SRType_LSL;
5133                shift_n = 0;
5134
5135                // if t == 15 || m == 15 then UNPREDICTABLE;
5136                if ((t == 15) || (m == 15))
5137                    return false;
5138
5139                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
5140                if (wback && ((n == 15) || (n == t)))
5141                    return false;
5142
5143                break;
5144
5145            default:
5146                return false;
5147        }
5148
5149        uint32_t Rm = ReadCoreReg (m, &success);
5150        if (!success)
5151            return false;
5152
5153        uint32_t Rn = ReadCoreReg (n, &success);
5154        if (!success)
5155            return false;
5156
5157        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
5158        uint32_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
5159        if (!success)
5160            return false;
5161
5162        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5163        addr_t offset_addr;
5164        if (add)
5165            offset_addr = Rn + offset;
5166        else
5167            offset_addr = Rn - offset;
5168
5169        // address = if index then offset_addr else R[n];
5170        addr_t address;
5171        if (index)
5172            address = offset_addr;
5173        else
5174            address = Rn;
5175
5176        EmulateInstruction::Context context;
5177        context.type = eContextRegisterStore;
5178        RegisterInfo base_reg;
5179        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5180        RegisterInfo offset_reg;
5181        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5182
5183        // if UnalignedSupport() || address<0> == '0' then
5184        if (UnalignedSupport() || BitIsClear (address, 0))
5185        {
5186            // MemU[address,2] = R[t]<15:0>;
5187            uint32_t Rt = ReadCoreReg (t, &success);
5188            if (!success)
5189                return false;
5190
5191            EmulateInstruction::Context context;
5192            context.type = eContextRegisterStore;
5193            RegisterInfo base_reg;
5194            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5195            RegisterInfo offset_reg;
5196            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
5197            RegisterInfo data_reg;
5198            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
5199            context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
5200
5201            if (!MemUWrite (context, address, Bits32 (Rt, 15, 0), 2))
5202                return false;
5203        }
5204        else // Can only occur before ARMv7
5205        {
5206            // MemU[address,2] = bits(16) UNKNOWN;
5207        }
5208
5209        // if wback then R[n] = offset_addr;
5210        if (wback)
5211        {
5212            context.type = eContextAdjustBaseRegister;
5213            context.SetAddress (offset_addr);
5214            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5215                return false;
5216        }
5217    }
5218
5219    return true;
5220}
5221
5222// Add with Carry (immediate) adds an immediate value and the carry flag value to a register value,
5223// and writes the result to the destination register.  It can optionally update the condition flags
5224// based on the result.
5225bool
5226EmulateInstructionARM::EmulateADCImm (const uint32_t opcode, const ARMEncoding encoding)
5227{
5228#if 0
5229    // ARM pseudo code...
5230    if ConditionPassed() then
5231        EncodingSpecificOperations();
5232        (result, carry, overflow) = AddWithCarry(R[n], imm32, APSR.C);
5233        if d == 15 then         // Can only occur for ARM encoding
5234            ALUWritePC(result); // setflags is always FALSE here
5235        else
5236            R[d] = result;
5237            if setflags then
5238                APSR.N = result<31>;
5239                APSR.Z = IsZeroBit(result);
5240                APSR.C = carry;
5241                APSR.V = overflow;
5242#endif
5243
5244    bool success = false;
5245
5246    if (ConditionPassed(opcode))
5247    {
5248        uint32_t Rd, Rn;
5249        uint32_t imm32; // the immediate value to be added to the value obtained from Rn
5250        bool setflags;
5251        switch (encoding)
5252        {
5253        case eEncodingT1:
5254            Rd = Bits32(opcode, 11, 8);
5255            Rn = Bits32(opcode, 19, 16);
5256            setflags = BitIsSet(opcode, 20);
5257            imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
5258            if (BadReg(Rd) || BadReg(Rn))
5259                return false;
5260            break;
5261        case eEncodingA1:
5262            Rd = Bits32(opcode, 15, 12);
5263            Rn = Bits32(opcode, 19, 16);
5264            setflags = BitIsSet(opcode, 20);
5265            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5266
5267            if (Rd == 15 && setflags)
5268                return EmulateSUBSPcLrEtc (opcode, encoding);
5269            break;
5270        default:
5271            return false;
5272        }
5273
5274        // Read the first operand.
5275        int32_t val1 = ReadCoreReg(Rn, &success);
5276        if (!success)
5277            return false;
5278
5279        AddWithCarryResult res = AddWithCarry(val1, imm32, APSR_C);
5280
5281        EmulateInstruction::Context context;
5282        context.type = EmulateInstruction::eContextImmediate;
5283        context.SetNoArgs ();
5284
5285        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5286            return false;
5287    }
5288    return true;
5289}
5290
5291// Add with Carry (register) adds a register value, the carry flag value, and an optionally-shifted
5292// register value, and writes the result to the destination register.  It can optionally update the
5293// condition flags based on the result.
5294bool
5295EmulateInstructionARM::EmulateADCReg (const uint32_t opcode, const ARMEncoding encoding)
5296{
5297#if 0
5298    // ARM pseudo code...
5299    if ConditionPassed() then
5300        EncodingSpecificOperations();
5301        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
5302        (result, carry, overflow) = AddWithCarry(R[n], shifted, APSR.C);
5303        if d == 15 then         // Can only occur for ARM encoding
5304            ALUWritePC(result); // setflags is always FALSE here
5305        else
5306            R[d] = result;
5307            if setflags then
5308                APSR.N = result<31>;
5309                APSR.Z = IsZeroBit(result);
5310                APSR.C = carry;
5311                APSR.V = overflow;
5312#endif
5313
5314    bool success = false;
5315
5316    if (ConditionPassed(opcode))
5317    {
5318        uint32_t Rd, Rn, Rm;
5319        ARM_ShifterType shift_t;
5320        uint32_t shift_n; // the shift applied to the value read from Rm
5321        bool setflags;
5322        switch (encoding)
5323        {
5324        case eEncodingT1:
5325            Rd = Rn = Bits32(opcode, 2, 0);
5326            Rm = Bits32(opcode, 5, 3);
5327            setflags = !InITBlock();
5328            shift_t = SRType_LSL;
5329            shift_n = 0;
5330            break;
5331        case eEncodingT2:
5332            Rd = Bits32(opcode, 11, 8);
5333            Rn = Bits32(opcode, 19, 16);
5334            Rm = Bits32(opcode, 3, 0);
5335            setflags = BitIsSet(opcode, 20);
5336            shift_n = DecodeImmShiftThumb(opcode, shift_t);
5337            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5338                return false;
5339            break;
5340        case eEncodingA1:
5341            Rd = Bits32(opcode, 15, 12);
5342            Rn = Bits32(opcode, 19, 16);
5343            Rm = Bits32(opcode, 3, 0);
5344            setflags = BitIsSet(opcode, 20);
5345            shift_n = DecodeImmShiftARM(opcode, shift_t);
5346
5347            if (Rd == 15 && setflags)
5348                return EmulateSUBSPcLrEtc (opcode, encoding);
5349            break;
5350        default:
5351            return false;
5352        }
5353
5354        // Read the first operand.
5355        int32_t val1 = ReadCoreReg(Rn, &success);
5356        if (!success)
5357            return false;
5358
5359        // Read the second operand.
5360        int32_t val2 = ReadCoreReg(Rm, &success);
5361        if (!success)
5362            return false;
5363
5364        uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
5365        if (!success)
5366            return false;
5367        AddWithCarryResult res = AddWithCarry(val1, shifted, APSR_C);
5368
5369        EmulateInstruction::Context context;
5370        context.type = EmulateInstruction::eContextImmediate;
5371        context.SetNoArgs ();
5372
5373        if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
5374            return false;
5375    }
5376    return true;
5377}
5378
5379// This instruction adds an immediate value to the PC value to form a PC-relative address,
5380// and writes the result to the destination register.
5381bool
5382EmulateInstructionARM::EmulateADR (const uint32_t opcode, const ARMEncoding encoding)
5383{
5384#if 0
5385    // ARM pseudo code...
5386    if ConditionPassed() then
5387        EncodingSpecificOperations();
5388        result = if add then (Align(PC,4) + imm32) else (Align(PC,4) - imm32);
5389        if d == 15 then         // Can only occur for ARM encodings
5390            ALUWritePC(result);
5391        else
5392            R[d] = result;
5393#endif
5394
5395    bool success = false;
5396
5397    if (ConditionPassed(opcode))
5398    {
5399        uint32_t Rd;
5400        uint32_t imm32; // the immediate value to be added/subtracted to/from the PC
5401        bool add;
5402        switch (encoding)
5403        {
5404        case eEncodingT1:
5405            Rd = Bits32(opcode, 10, 8);
5406            imm32 = ThumbImm8Scaled(opcode); // imm32 = ZeroExtend(imm8:'00', 32)
5407            add = true;
5408            break;
5409        case eEncodingT2:
5410        case eEncodingT3:
5411            Rd = Bits32(opcode, 11, 8);
5412            imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
5413            add = (Bits32(opcode, 24, 21) == 0); // 0b0000 => ADD; 0b0101 => SUB
5414            if (BadReg(Rd))
5415                return false;
5416            break;
5417        case eEncodingA1:
5418        case eEncodingA2:
5419            Rd = Bits32(opcode, 15, 12);
5420            imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
5421            add = (Bits32(opcode, 24, 21) == 0x4); // 0b0100 => ADD; 0b0010 => SUB
5422            break;
5423        default:
5424            return false;
5425        }
5426
5427        // Read the PC value.
5428        uint32_t pc = ReadCoreReg(PC_REG, &success);
5429        if (!success)
5430            return false;
5431
5432        uint32_t result = (add ? Align(pc, 4) + imm32 : Align(pc, 4) - imm32);
5433
5434        EmulateInstruction::Context context;
5435        context.type = EmulateInstruction::eContextImmediate;
5436        context.SetNoArgs ();
5437
5438        if (!WriteCoreReg(context, result, Rd))
5439            return false;
5440    }
5441    return true;
5442}
5443
5444// This instruction performs a bitwise AND of a register value and an immediate value, and writes the result
5445// to the destination register.  It can optionally update the condition flags based on the result.
5446bool
5447EmulateInstructionARM::EmulateANDImm (const uint32_t opcode, const ARMEncoding encoding)
5448{
5449#if 0
5450    // ARM pseudo code...
5451    if ConditionPassed() then
5452        EncodingSpecificOperations();
5453        result = R[n] AND imm32;
5454        if d == 15 then         // Can only occur for ARM encoding
5455            ALUWritePC(result); // setflags is always FALSE here
5456        else
5457            R[d] = result;
5458            if setflags then
5459                APSR.N = result<31>;
5460                APSR.Z = IsZeroBit(result);
5461                APSR.C = carry;
5462                // APSR.V unchanged
5463#endif
5464
5465    bool success = false;
5466
5467    if (ConditionPassed(opcode))
5468    {
5469        uint32_t Rd, Rn;
5470        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
5471        bool setflags;
5472        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5473        switch (encoding)
5474        {
5475        case eEncodingT1:
5476            Rd = Bits32(opcode, 11, 8);
5477            Rn = Bits32(opcode, 19, 16);
5478            setflags = BitIsSet(opcode, 20);
5479            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5480            // if Rd == '1111' && S == '1' then SEE TST (immediate);
5481            if (Rd == 15 && setflags)
5482                return EmulateTSTImm(opcode, eEncodingT1);
5483            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
5484                return false;
5485            break;
5486        case eEncodingA1:
5487            Rd = Bits32(opcode, 15, 12);
5488            Rn = Bits32(opcode, 19, 16);
5489            setflags = BitIsSet(opcode, 20);
5490            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5491
5492            if (Rd == 15 && setflags)
5493                return EmulateSUBSPcLrEtc (opcode, encoding);
5494            break;
5495        default:
5496            return false;
5497        }
5498
5499        // Read the first operand.
5500        uint32_t val1 = ReadCoreReg(Rn, &success);
5501        if (!success)
5502            return false;
5503
5504        uint32_t result = val1 & imm32;
5505
5506        EmulateInstruction::Context context;
5507        context.type = EmulateInstruction::eContextImmediate;
5508        context.SetNoArgs ();
5509
5510        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5511            return false;
5512    }
5513    return true;
5514}
5515
5516// This instruction performs a bitwise AND of a register value and an optionally-shifted register value,
5517// and writes the result to the destination register.  It can optionally update the condition flags
5518// based on the result.
5519bool
5520EmulateInstructionARM::EmulateANDReg (const uint32_t opcode, const ARMEncoding encoding)
5521{
5522#if 0
5523    // ARM pseudo code...
5524    if ConditionPassed() then
5525        EncodingSpecificOperations();
5526        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5527        result = R[n] AND shifted;
5528        if d == 15 then         // Can only occur for ARM encoding
5529            ALUWritePC(result); // setflags is always FALSE here
5530        else
5531            R[d] = result;
5532            if setflags then
5533                APSR.N = result<31>;
5534                APSR.Z = IsZeroBit(result);
5535                APSR.C = carry;
5536                // APSR.V unchanged
5537#endif
5538
5539    bool success = false;
5540
5541    if (ConditionPassed(opcode))
5542    {
5543        uint32_t Rd, Rn, Rm;
5544        ARM_ShifterType shift_t;
5545        uint32_t shift_n; // the shift applied to the value read from Rm
5546        bool setflags;
5547        uint32_t carry;
5548        switch (encoding)
5549        {
5550        case eEncodingT1:
5551            Rd = Rn = Bits32(opcode, 2, 0);
5552            Rm = Bits32(opcode, 5, 3);
5553            setflags = !InITBlock();
5554            shift_t = SRType_LSL;
5555            shift_n = 0;
5556            break;
5557        case eEncodingT2:
5558            Rd = Bits32(opcode, 11, 8);
5559            Rn = Bits32(opcode, 19, 16);
5560            Rm = Bits32(opcode, 3, 0);
5561            setflags = BitIsSet(opcode, 20);
5562            shift_n = DecodeImmShiftThumb(opcode, shift_t);
5563            // if Rd == '1111' && S == '1' then SEE TST (register);
5564            if (Rd == 15 && setflags)
5565                return EmulateTSTReg(opcode, eEncodingT2);
5566            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
5567                return false;
5568            break;
5569        case eEncodingA1:
5570            Rd = Bits32(opcode, 15, 12);
5571            Rn = Bits32(opcode, 19, 16);
5572            Rm = Bits32(opcode, 3, 0);
5573            setflags = BitIsSet(opcode, 20);
5574            shift_n = DecodeImmShiftARM(opcode, shift_t);
5575
5576            if (Rd == 15 && setflags)
5577                return EmulateSUBSPcLrEtc (opcode, encoding);
5578            break;
5579        default:
5580            return false;
5581        }
5582
5583        // Read the first operand.
5584        uint32_t val1 = ReadCoreReg(Rn, &success);
5585        if (!success)
5586            return false;
5587
5588        // Read the second operand.
5589        uint32_t val2 = ReadCoreReg(Rm, &success);
5590        if (!success)
5591            return false;
5592
5593        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5594        if (!success)
5595            return false;
5596        uint32_t result = val1 & shifted;
5597
5598        EmulateInstruction::Context context;
5599        context.type = EmulateInstruction::eContextImmediate;
5600        context.SetNoArgs ();
5601
5602        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5603            return false;
5604    }
5605    return true;
5606}
5607
5608// Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an
5609// immediate value, and writes the result to the destination register.  It can optionally update the
5610// condition flags based on the result.
5611bool
5612EmulateInstructionARM::EmulateBICImm (const uint32_t opcode, const ARMEncoding encoding)
5613{
5614#if 0
5615    // ARM pseudo code...
5616    if ConditionPassed() then
5617        EncodingSpecificOperations();
5618        result = R[n] AND NOT(imm32);
5619        if d == 15 then         // Can only occur for ARM encoding
5620            ALUWritePC(result); // setflags is always FALSE here
5621        else
5622            R[d] = result;
5623            if setflags then
5624                APSR.N = result<31>;
5625                APSR.Z = IsZeroBit(result);
5626                APSR.C = carry;
5627                // APSR.V unchanged
5628#endif
5629
5630    bool success = false;
5631
5632    if (ConditionPassed(opcode))
5633    {
5634        uint32_t Rd, Rn;
5635        uint32_t imm32; // the immediate value to be bitwise inverted and ANDed to the value obtained from Rn
5636        bool setflags;
5637        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
5638        switch (encoding)
5639        {
5640        case eEncodingT1:
5641            Rd = Bits32(opcode, 11, 8);
5642            Rn = Bits32(opcode, 19, 16);
5643            setflags = BitIsSet(opcode, 20);
5644            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
5645            if (BadReg(Rd) || BadReg(Rn))
5646                return false;
5647            break;
5648        case eEncodingA1:
5649            Rd = Bits32(opcode, 15, 12);
5650            Rn = Bits32(opcode, 19, 16);
5651            setflags = BitIsSet(opcode, 20);
5652            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
5653
5654            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5655            if (Rd == 15 && setflags)
5656                return EmulateSUBSPcLrEtc (opcode, encoding);
5657            break;
5658        default:
5659            return false;
5660        }
5661
5662        // Read the first operand.
5663        uint32_t val1 = ReadCoreReg(Rn, &success);
5664        if (!success)
5665            return false;
5666
5667        uint32_t result = val1 & ~imm32;
5668
5669        EmulateInstruction::Context context;
5670        context.type = EmulateInstruction::eContextImmediate;
5671        context.SetNoArgs ();
5672
5673        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5674            return false;
5675    }
5676    return true;
5677}
5678
5679// Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an
5680// optionally-shifted register value, and writes the result to the destination register.
5681// It can optionally update the condition flags based on the result.
5682bool
5683EmulateInstructionARM::EmulateBICReg (const uint32_t opcode, const ARMEncoding encoding)
5684{
5685#if 0
5686    // ARM pseudo code...
5687    if ConditionPassed() then
5688        EncodingSpecificOperations();
5689        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
5690        result = R[n] AND NOT(shifted);
5691        if d == 15 then         // Can only occur for ARM encoding
5692            ALUWritePC(result); // setflags is always FALSE here
5693        else
5694            R[d] = result;
5695            if setflags then
5696                APSR.N = result<31>;
5697                APSR.Z = IsZeroBit(result);
5698                APSR.C = carry;
5699                // APSR.V unchanged
5700#endif
5701
5702    bool success = false;
5703
5704    if (ConditionPassed(opcode))
5705    {
5706        uint32_t Rd, Rn, Rm;
5707        ARM_ShifterType shift_t;
5708        uint32_t shift_n; // the shift applied to the value read from Rm
5709        bool setflags;
5710        uint32_t carry;
5711        switch (encoding)
5712        {
5713        case eEncodingT1:
5714            Rd = Rn = Bits32(opcode, 2, 0);
5715            Rm = Bits32(opcode, 5, 3);
5716            setflags = !InITBlock();
5717            shift_t = SRType_LSL;
5718            shift_n = 0;
5719            break;
5720        case eEncodingT2:
5721            Rd = Bits32(opcode, 11, 8);
5722            Rn = Bits32(opcode, 19, 16);
5723            Rm = Bits32(opcode, 3, 0);
5724            setflags = BitIsSet(opcode, 20);
5725            shift_n = DecodeImmShiftThumb(opcode, shift_t);
5726            if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
5727                return false;
5728            break;
5729        case eEncodingA1:
5730            Rd = Bits32(opcode, 15, 12);
5731            Rn = Bits32(opcode, 19, 16);
5732            Rm = Bits32(opcode, 3, 0);
5733            setflags = BitIsSet(opcode, 20);
5734            shift_n = DecodeImmShiftARM(opcode, shift_t);
5735
5736            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
5737            if (Rd == 15 && setflags)
5738                return EmulateSUBSPcLrEtc (opcode, encoding);
5739            break;
5740        default:
5741            return false;
5742        }
5743
5744        // Read the first operand.
5745        uint32_t val1 = ReadCoreReg(Rn, &success);
5746        if (!success)
5747            return false;
5748
5749        // Read the second operand.
5750        uint32_t val2 = ReadCoreReg(Rm, &success);
5751        if (!success)
5752            return false;
5753
5754        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
5755        if (!success)
5756            return false;
5757        uint32_t result = val1 & ~shifted;
5758
5759        EmulateInstruction::Context context;
5760        context.type = EmulateInstruction::eContextImmediate;
5761        context.SetNoArgs ();
5762
5763        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
5764            return false;
5765    }
5766    return true;
5767}
5768
5769// LDR (immediate, ARM) calculates an address from a base register value and an immediate offset, loads a word
5770// from memory, and writes it to a register.  It can use offset, post-indexed, or pre-indexed addressing.
5771bool
5772EmulateInstructionARM::EmulateLDRImmediateARM (const uint32_t opcode, const ARMEncoding encoding)
5773{
5774#if 0
5775    if ConditionPassed() then
5776        EncodingSpecificOperations();
5777        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5778        address = if index then offset_addr else R[n];
5779        data = MemU[address,4];
5780        if wback then R[n] = offset_addr;
5781        if t == 15 then
5782            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5783        elsif UnalignedSupport() || address<1:0> = '00' then
5784            R[t] = data;
5785        else // Can only apply before ARMv7
5786            R[t] = ROR(data, 8*UInt(address<1:0>));
5787#endif
5788
5789    bool success = false;
5790
5791    if (ConditionPassed(opcode))
5792    {
5793        const uint32_t addr_byte_size = GetAddressByteSize();
5794
5795        uint32_t t;
5796        uint32_t n;
5797        uint32_t imm32;
5798        bool index;
5799        bool add;
5800        bool wback;
5801
5802        switch (encoding)
5803        {
5804            case eEncodingA1:
5805                // if Rn == '1111' then SEE LDR (literal);
5806                // if P == '0' && W == '1' then SEE LDRT;
5807                // if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP;
5808                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
5809                t = Bits32 (opcode, 15, 12);
5810                n = Bits32 (opcode, 19, 16);
5811                imm32 = Bits32 (opcode, 11, 0);
5812
5813                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
5814                index = BitIsSet (opcode, 24);
5815                add = BitIsSet (opcode, 23);
5816                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
5817
5818                // if wback && n == t then UNPREDICTABLE;
5819                if (wback && (n == t))
5820                    return false;
5821
5822                break;
5823
5824            default:
5825                return false;
5826        }
5827
5828        addr_t address;
5829        addr_t offset_addr;
5830        addr_t base_address = ReadCoreReg (n, &success);
5831        if (!success)
5832            return false;
5833
5834        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
5835        if (add)
5836            offset_addr = base_address + imm32;
5837        else
5838            offset_addr = base_address - imm32;
5839
5840        // address = if index then offset_addr else R[n];
5841        if (index)
5842            address = offset_addr;
5843        else
5844            address = base_address;
5845
5846        // data = MemU[address,4];
5847
5848        RegisterInfo base_reg;
5849        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
5850
5851        EmulateInstruction::Context context;
5852        context.type = eContextRegisterLoad;
5853        context.SetRegisterPlusOffset (base_reg, address - base_address);
5854
5855        uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
5856        if (!success)
5857            return false;
5858
5859        // if wback then R[n] = offset_addr;
5860        if (wback)
5861        {
5862            context.type = eContextAdjustBaseRegister;
5863            context.SetAddress (offset_addr);
5864            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
5865                return false;
5866        }
5867
5868        // if t == 15 then
5869        if (t == 15)
5870        {
5871            // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5872            if (BitIsClear (address, 1) && BitIsClear (address, 0))
5873            {
5874                // LoadWritePC (data);
5875                context.type = eContextRegisterLoad;
5876                context.SetRegisterPlusOffset (base_reg, address - base_address);
5877                LoadWritePC (context, data);
5878            }
5879            else
5880                  return false;
5881        }
5882        // elsif UnalignedSupport() || address<1:0> = '00' then
5883        else if (UnalignedSupport() || (BitIsClear (address, 1) && BitIsClear (address, 0)))
5884        {
5885            // R[t] = data;
5886            context.type = eContextRegisterLoad;
5887            context.SetRegisterPlusOffset (base_reg, address - base_address);
5888            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5889                return false;
5890        }
5891        // else // Can only apply before ARMv7
5892        else
5893        {
5894            // R[t] = ROR(data, 8*UInt(address<1:0>));
5895            data = ROR (data, Bits32 (address, 1, 0), &success);
5896            if (!success)
5897                return false;
5898            context.type = eContextRegisterLoad;
5899            context.SetImmediate (data);
5900            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
5901                return false;
5902        }
5903
5904    }
5905    return true;
5906}
5907
5908// LDR (register) calculates an address from a base register value and an offset register value, loads a word
5909// from memory, and writes it to a resgister.  The offset register value can optionally be shifted.
5910bool
5911EmulateInstructionARM::EmulateLDRRegister (const uint32_t opcode, const ARMEncoding encoding)
5912{
5913#if 0
5914    if ConditionPassed() then
5915        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
5916        offset = Shift(R[m], shift_t, shift_n, APSR.C);
5917        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
5918        address = if index then offset_addr else R[n];
5919        data = MemU[address,4];
5920        if wback then R[n] = offset_addr;
5921        if t == 15 then
5922            if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
5923        elsif UnalignedSupport() || address<1:0> = '00' then
5924            R[t] = data;
5925        else // Can only apply before ARMv7
5926            if CurrentInstrSet() == InstrSet_ARM then
5927                R[t] = ROR(data, 8*UInt(address<1:0>));
5928            else
5929                R[t] = bits(32) UNKNOWN;
5930#endif
5931
5932    bool success = false;
5933
5934    if (ConditionPassed(opcode))
5935    {
5936        const uint32_t addr_byte_size = GetAddressByteSize();
5937
5938        uint32_t t;
5939        uint32_t n;
5940        uint32_t m;
5941        bool index;
5942        bool add;
5943        bool wback;
5944        ARM_ShifterType shift_t;
5945        uint32_t shift_n;
5946
5947        switch (encoding)
5948        {
5949            case eEncodingT1:
5950                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
5951                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5952                t = Bits32 (opcode, 2, 0);
5953                n = Bits32 (opcode, 5, 3);
5954                m = Bits32 (opcode, 8, 6);
5955
5956                // index = TRUE; add = TRUE; wback = FALSE;
5957                index = true;
5958                add = true;
5959                wback = false;
5960
5961                // (shift_t, shift_n) = (SRType_LSL, 0);
5962                shift_t = SRType_LSL;
5963                shift_n = 0;
5964
5965                break;
5966
5967            case eEncodingT2:
5968                // if Rn == '1111' then SEE LDR (literal);
5969                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5970                t = Bits32 (opcode, 15, 12);
5971                n = Bits32 (opcode, 19, 16);
5972                m = Bits32 (opcode, 3, 0);
5973
5974                // index = TRUE; add = TRUE; wback = FALSE;
5975                index = true;
5976                add = true;
5977                wback = false;
5978
5979                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
5980                shift_t = SRType_LSL;
5981                shift_n = Bits32 (opcode, 5, 4);
5982
5983                // if BadReg(m) then UNPREDICTABLE;
5984                if (BadReg (m))
5985                    return false;
5986
5987                // if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE;
5988                if ((t == 15) && InITBlock() && !LastInITBlock())
5989                    return false;
5990
5991                break;
5992
5993            case eEncodingA1:
5994            {
5995                // if P == '0' && W == '1' then SEE LDRT;
5996                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
5997                t = Bits32 (opcode, 15, 12);
5998                n = Bits32 (opcode, 19, 16);
5999                m = Bits32 (opcode, 3, 0);
6000
6001                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6002                index = BitIsSet (opcode, 24);
6003                add = BitIsSet (opcode, 23);
6004                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6005
6006                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6007                uint32_t type = Bits32 (opcode, 6, 5);
6008                uint32_t imm5 = Bits32 (opcode, 11, 7);
6009                shift_n = DecodeImmShift (type, imm5, shift_t);
6010
6011                // if m == 15 then UNPREDICTABLE;
6012                if (m == 15)
6013                    return false;
6014
6015                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6016                if (wback && ((n == 15) || (n == t)))
6017                    return false;
6018            }
6019                break;
6020
6021
6022            default:
6023                return false;
6024        }
6025
6026        uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6027        if (!success)
6028            return false;
6029
6030        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6031        if (!success)
6032            return false;
6033
6034        addr_t offset_addr;
6035        addr_t address;
6036
6037        // offset = Shift(R[m], shift_t, shift_n, APSR.C);   -- Note "The APSR is an application level alias for the CPSR".
6038        addr_t offset = Shift (Rm, shift_t, shift_n, Bit32 (m_opcode_cpsr, APSR_C), &success);
6039        if (!success)
6040            return false;
6041
6042        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6043        if (add)
6044            offset_addr = Rn + offset;
6045        else
6046            offset_addr = Rn - offset;
6047
6048        // address = if index then offset_addr else R[n];
6049            if (index)
6050                address = offset_addr;
6051            else
6052                address = Rn;
6053
6054        // data = MemU[address,4];
6055        RegisterInfo base_reg;
6056        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6057
6058        EmulateInstruction::Context context;
6059        context.type = eContextRegisterLoad;
6060        context.SetRegisterPlusOffset (base_reg, address - Rn);
6061
6062        uint64_t data = MemURead (context, address, addr_byte_size, 0, &success);
6063        if (!success)
6064            return false;
6065
6066        // if wback then R[n] = offset_addr;
6067        if (wback)
6068        {
6069            context.type = eContextAdjustBaseRegister;
6070            context.SetAddress (offset_addr);
6071            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6072                return false;
6073        }
6074
6075        // if t == 15 then
6076        if (t == 15)
6077        {
6078            // if address<1:0> == '00' then LoadWritePC(data); else UNPREDICTABLE;
6079            if (BitIsClear (address, 1) && BitIsClear (address, 0))
6080            {
6081                context.type = eContextRegisterLoad;
6082                context.SetRegisterPlusOffset (base_reg, address - Rn);
6083                LoadWritePC (context, data);
6084            }
6085            else
6086                return false;
6087        }
6088        // elsif UnalignedSupport() || address<1:0> = '00' then
6089        else if (UnalignedSupport () || (BitIsClear (address, 1) && BitIsClear (address, 0)))
6090        {
6091            // R[t] = data;
6092            context.type = eContextRegisterLoad;
6093            context.SetRegisterPlusOffset (base_reg, address - Rn);
6094            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6095                return false;
6096        }
6097        else // Can only apply before ARMv7
6098        {
6099            // if CurrentInstrSet() == InstrSet_ARM then
6100            if (CurrentInstrSet () == eModeARM)
6101            {
6102                // R[t] = ROR(data, 8*UInt(address<1:0>));
6103                data = ROR (data, Bits32 (address, 1, 0), &success);
6104                if (!success)
6105                    return false;
6106                context.type = eContextRegisterLoad;
6107                context.SetImmediate (data);
6108                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6109                    return false;
6110            }
6111            else
6112            {
6113                // R[t] = bits(32) UNKNOWN;
6114                WriteBits32Unknown (t);
6115            }
6116        }
6117    }
6118    return true;
6119}
6120
6121// LDRB (immediate, Thumb)
6122bool
6123EmulateInstructionARM::EmulateLDRBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6124{
6125#if 0
6126    if ConditionPassed() then
6127        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6128        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6129        address = if index then offset_addr else R[n];
6130        R[t] = ZeroExtend(MemU[address,1], 32);
6131        if wback then R[n] = offset_addr;
6132#endif
6133
6134    bool success = false;
6135
6136    if (ConditionPassed(opcode))
6137    {
6138        uint32_t t;
6139        uint32_t n;
6140        uint32_t imm32;
6141        bool index;
6142        bool add;
6143        bool wback;
6144
6145        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6146        switch (encoding)
6147        {
6148            case eEncodingT1:
6149                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5, 32);
6150                t = Bits32 (opcode, 2, 0);
6151                n = Bits32 (opcode, 5, 3);
6152                imm32 = Bits32 (opcode, 10, 6);
6153
6154                // index = TRUE; add = TRUE; wback = FALSE;
6155                index = true;
6156                add = true;
6157                wback= false;
6158
6159                break;
6160
6161            case eEncodingT2:
6162                // if Rt == '1111' then SEE PLD;
6163                // if Rn == '1111' then SEE LDRB (literal);
6164                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6165                t = Bits32 (opcode, 15, 12);
6166                n = Bits32 (opcode, 19, 16);
6167                imm32 = Bits32 (opcode, 11, 0);
6168
6169                // index = TRUE; add = TRUE; wback = FALSE;
6170                index = true;
6171                add = true;
6172                wback = false;
6173
6174                // if t == 13 then UNPREDICTABLE;
6175                if (t == 13)
6176                    return false;
6177
6178                break;
6179
6180            case eEncodingT3:
6181                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD;
6182                // if Rn == '1111' then SEE LDRB (literal);
6183                // if P == '1' && U == '1' && W == '0' then SEE LDRBT;
6184                // if P == '0' && W == '0' then UNDEFINED;
6185                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6186                    return false;
6187
6188                  // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6189                t = Bits32 (opcode, 15, 12);
6190                n = Bits32 (opcode, 19, 16);
6191                imm32 = Bits32 (opcode, 7, 0);
6192
6193                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6194                index = BitIsSet (opcode, 10);
6195                add = BitIsSet (opcode, 9);
6196                wback = BitIsSet (opcode, 8);
6197
6198                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6199                if (BadReg (t) || (wback && (n == t)))
6200                    return false;
6201
6202                break;
6203
6204            default:
6205                return false;
6206        }
6207
6208        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6209        if (!success)
6210            return false;
6211
6212        addr_t address;
6213        addr_t offset_addr;
6214
6215        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6216        if (add)
6217            offset_addr = Rn + imm32;
6218        else
6219            offset_addr = Rn - imm32;
6220
6221        // address = if index then offset_addr else R[n];
6222        if (index)
6223            address = offset_addr;
6224        else
6225            address = Rn;
6226
6227        // R[t] = ZeroExtend(MemU[address,1], 32);
6228        RegisterInfo base_reg;
6229        RegisterInfo data_reg;
6230        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6231        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
6232
6233        EmulateInstruction::Context context;
6234        context.type = eContextRegisterLoad;
6235        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
6236
6237        uint64_t data = MemURead (context, address, 1, 0, &success);
6238        if (!success)
6239            return false;
6240
6241        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6242            return false;
6243
6244        // if wback then R[n] = offset_addr;
6245        if (wback)
6246        {
6247            context.type = eContextAdjustBaseRegister;
6248            context.SetAddress (offset_addr);
6249            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6250                return false;
6251        }
6252    }
6253    return true;
6254}
6255
6256// LDRB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
6257// zero-extends it to form a 32-bit word and writes it to a register.
6258bool
6259EmulateInstructionARM::EmulateLDRBLiteral (const uint32_t opcode, const ARMEncoding encoding)
6260{
6261#if 0
6262    if ConditionPassed() then
6263        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6264        base = Align(PC,4);
6265        address = if add then (base + imm32) else (base - imm32);
6266        R[t] = ZeroExtend(MemU[address,1], 32);
6267#endif
6268
6269    bool success = false;
6270
6271    if (ConditionPassed(opcode))
6272    {
6273        uint32_t t;
6274        uint32_t imm32;
6275        bool add;
6276        switch (encoding)
6277        {
6278            case eEncodingT1:
6279                // if Rt == '1111' then SEE PLD;
6280                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6281                t = Bits32 (opcode, 15, 12);
6282                imm32 = Bits32 (opcode, 11, 0);
6283                add = BitIsSet (opcode, 23);
6284
6285                // if t == 13 then UNPREDICTABLE;
6286                if (t == 13)
6287                    return false;
6288
6289                break;
6290
6291            case eEncodingA1:
6292                // t == UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6293                t = Bits32 (opcode, 15, 12);
6294                imm32 = Bits32 (opcode, 11, 0);
6295                add = BitIsSet (opcode, 23);
6296
6297                // if t == 15 then UNPREDICTABLE;
6298                if (t == 15)
6299                    return false;
6300                break;
6301
6302            default:
6303                return false;
6304        }
6305
6306        // base = Align(PC,4);
6307        uint32_t pc_val = ReadCoreReg (PC_REG, &success);
6308        if (!success)
6309            return false;
6310
6311        uint32_t base = AlignPC (pc_val);
6312
6313        addr_t address;
6314        // address = if add then (base + imm32) else (base - imm32);
6315        if (add)
6316            address = base + imm32;
6317        else
6318            address = base - imm32;
6319
6320        // R[t] = ZeroExtend(MemU[address,1], 32);
6321        EmulateInstruction::Context context;
6322        context.type = eContextRelativeBranchImmediate;
6323        context.SetImmediate (address - base);
6324
6325        uint64_t data = MemURead (context, address, 1, 0, &success);
6326        if (!success)
6327            return false;
6328
6329        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6330            return false;
6331    }
6332    return true;
6333}
6334
6335// LDRB (register) calculates an address from a base register value and an offset rigister value, loads a byte from
6336// memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6337// optionally be shifted.
6338bool
6339EmulateInstructionARM::EmulateLDRBRegister (const uint32_t opcode, const ARMEncoding encoding)
6340{
6341#if 0
6342    if ConditionPassed() then
6343        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6344        offset = Shift(R[m], shift_t, shift_n, APSR.C);
6345        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6346        address = if index then offset_addr else R[n];
6347        R[t] = ZeroExtend(MemU[address,1],32);
6348        if wback then R[n] = offset_addr;
6349#endif
6350
6351    bool success = false;
6352
6353    if (ConditionPassed(opcode))
6354    {
6355        uint32_t t;
6356        uint32_t n;
6357        uint32_t m;
6358        bool index;
6359        bool add;
6360        bool wback;
6361        ARM_ShifterType shift_t;
6362        uint32_t shift_n;
6363
6364        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6365        switch (encoding)
6366        {
6367            case eEncodingT1:
6368                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6369                t = Bits32 (opcode, 2, 0);
6370                n = Bits32 (opcode, 5, 3);
6371                m = Bits32 (opcode, 8, 6);
6372
6373                // index = TRUE; add = TRUE; wback = FALSE;
6374                index = true;
6375                add = true;
6376                wback = false;
6377
6378                // (shift_t, shift_n) = (SRType_LSL, 0);
6379                shift_t = SRType_LSL;
6380                shift_n = 0;
6381                break;
6382
6383            case eEncodingT2:
6384                // if Rt == '1111' then SEE PLD;
6385                // if Rn == '1111' then SEE LDRB (literal);
6386                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6387                t = Bits32 (opcode, 15, 12);
6388                n = Bits32 (opcode, 19, 16);
6389                m = Bits32 (opcode, 3, 0);
6390
6391                // index = TRUE; add = TRUE; wback = FALSE;
6392                index = true;
6393                add = true;
6394                wback = false;
6395
6396                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6397                shift_t = SRType_LSL;
6398                shift_n = Bits32 (opcode, 5, 4);
6399
6400                // if t == 13 || BadReg(m) then UNPREDICTABLE;
6401                if ((t == 13) || BadReg (m))
6402                    return false;
6403                break;
6404
6405            case eEncodingA1:
6406            {
6407                // if P == '0' && W == '1' then SEE LDRBT;
6408                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6409                t = Bits32 (opcode, 15, 12);
6410                n = Bits32 (opcode, 19, 16);
6411                m = Bits32 (opcode, 3, 0);
6412
6413                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6414                index = BitIsSet (opcode, 24);
6415                add = BitIsSet (opcode, 23);
6416                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6417
6418                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
6419                uint32_t type = Bits32 (opcode, 6, 5);
6420                uint32_t imm5 = Bits32 (opcode, 11, 7);
6421                shift_n = DecodeImmShift (type, imm5, shift_t);
6422
6423                // if t == 15 || m == 15 then UNPREDICTABLE;
6424                if ((t == 15) || (m == 15))
6425                    return false;
6426
6427                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6428                if (wback && ((n == 15) || (n == t)))
6429                    return false;
6430            }
6431                break;
6432
6433            default:
6434                return false;
6435        }
6436
6437        addr_t offset_addr;
6438        addr_t address;
6439
6440        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6441        uint32_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6442        if (!success)
6443            return false;
6444
6445        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6446        if (!success)
6447            return false;
6448
6449        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6450        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6451        if (!success)
6452            return false;
6453
6454        if (add)
6455            offset_addr = Rn + offset;
6456        else
6457            offset_addr = Rn - offset;
6458
6459        // address = if index then offset_addr else R[n];
6460        if (index)
6461            address = offset_addr;
6462        else
6463            address = Rn;
6464
6465        // R[t] = ZeroExtend(MemU[address,1],32);
6466        RegisterInfo base_reg;
6467        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6468
6469        EmulateInstruction::Context context;
6470        context.type = eContextRegisterLoad;
6471        context.SetRegisterPlusOffset (base_reg, address - Rn);
6472
6473        uint64_t data = MemURead (context, address, 1, 0, &success);
6474        if (!success)
6475            return false;
6476
6477        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6478            return false;
6479
6480        // if wback then R[n] = offset_addr;
6481        if (wback)
6482        {
6483            context.type = eContextAdjustBaseRegister;
6484            context.SetAddress (offset_addr);
6485            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6486                return false;
6487        }
6488    }
6489    return true;
6490}
6491
6492// LDRH (immediate, Thumb) calculates an address from a base register value and an immediate offset, loads a
6493// halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register.  It can use offset,
6494// post-indexed, or pre-indexed addressing.
6495bool
6496EmulateInstructionARM::EmulateLDRHImmediate (const uint32_t opcode, const ARMEncoding encoding)
6497{
6498#if 0
6499    if ConditionPassed() then
6500        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6501        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6502        address = if index then offset_addr else R[n];
6503        data = MemU[address,2];
6504        if wback then R[n] = offset_addr;
6505        if UnalignedSupport() || address<0> = '0' then
6506            R[t] = ZeroExtend(data, 32);
6507        else // Can only apply before ARMv7
6508            R[t] = bits(32) UNKNOWN;
6509#endif
6510
6511
6512    bool success = false;
6513
6514    if (ConditionPassed(opcode))
6515    {
6516        uint32_t t;
6517        uint32_t n;
6518        uint32_t imm32;
6519        bool index;
6520        bool add;
6521        bool wback;
6522
6523        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6524        switch (encoding)
6525        {
6526            case eEncodingT1:
6527                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm5:'0', 32);
6528                t = Bits32 (opcode, 2, 0);
6529                n = Bits32 (opcode, 5, 3);
6530                imm32 = Bits32 (opcode, 10, 6) << 1;
6531
6532                // index = TRUE; add = TRUE; wback = FALSE;
6533                index = true;
6534                add = true;
6535                wback = false;
6536
6537                break;
6538
6539            case eEncodingT2:
6540                // if Rt == '1111' then SEE "Unallocated memory hints";
6541                // if Rn == '1111' then SEE LDRH (literal);
6542                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6543                t = Bits32 (opcode, 15, 12);
6544                n = Bits32 (opcode, 19, 16);
6545                imm32 = Bits32 (opcode, 11, 0);
6546
6547                // index = TRUE; add = TRUE; wback = FALSE;
6548                index = true;
6549                add = true;
6550                wback = false;
6551
6552                // if t == 13 then UNPREDICTABLE;
6553                if (t == 13)
6554                    return false;
6555                break;
6556
6557            case eEncodingT3:
6558                // if Rn == '1111' then SEE LDRH (literal);
6559                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
6560                // if P == '1' && U == '1' && W == '0' then SEE LDRHT;
6561                // if P == '0' && W == '0' then UNDEFINED;
6562                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6563                    return false;
6564
6565                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6566                t = Bits32 (opcode, 15, 12);
6567                n = Bits32 (opcode, 19, 16);
6568                imm32 = Bits32 (opcode, 7, 0);
6569
6570                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6571                index = BitIsSet (opcode, 10);
6572                add = BitIsSet (opcode, 9);
6573                wback = BitIsSet (opcode, 8);
6574
6575                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6576                if (BadReg (t) || (wback && (n == t)))
6577                    return false;
6578                break;
6579
6580            default:
6581                return false;
6582        }
6583
6584        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6585        uint32_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6586        if (!success)
6587            return false;
6588
6589        addr_t offset_addr;
6590        addr_t address;
6591
6592        if (add)
6593            offset_addr = Rn + imm32;
6594        else
6595            offset_addr = Rn - imm32;
6596
6597        // address = if index then offset_addr else R[n];
6598        if (index)
6599            address = offset_addr;
6600        else
6601            address = Rn;
6602
6603        // data = MemU[address,2];
6604        RegisterInfo base_reg;
6605        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6606
6607        EmulateInstruction::Context context;
6608        context.type = eContextRegisterLoad;
6609        context.SetRegisterPlusOffset (base_reg, address - Rn);
6610
6611        uint64_t data = MemURead (context, address, 2, 0, &success);
6612        if (!success)
6613            return false;
6614
6615        // if wback then R[n] = offset_addr;
6616        if (wback)
6617        {
6618            context.type = eContextAdjustBaseRegister;
6619            context.SetAddress (offset_addr);
6620            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6621                return false;
6622        }
6623
6624        // if UnalignedSupport() || address<0> = '0' then
6625        if (UnalignedSupport () || BitIsClear (address, 0))
6626        {
6627            // R[t] = ZeroExtend(data, 32);
6628            context.type = eContextRegisterLoad;
6629            context.SetRegisterPlusOffset (base_reg, address - Rn);
6630            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6631                return false;
6632        }
6633        else // Can only apply before ARMv7
6634        {
6635            // R[t] = bits(32) UNKNOWN;
6636            WriteBits32Unknown (t);
6637        }
6638    }
6639    return true;
6640}
6641
6642// LDRH (literal) caculates an address from the PC value and an immediate offset, loads a halfword from memory,
6643// zero-extends it to form a 32-bit word, and writes it to a register.
6644bool
6645EmulateInstructionARM::EmulateLDRHLiteral (const uint32_t opcode, const ARMEncoding encoding)
6646{
6647#if 0
6648    if ConditionPassed() then
6649        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6650        base = Align(PC,4);
6651        address = if add then (base + imm32) else (base - imm32);
6652        data = MemU[address,2];
6653        if UnalignedSupport() || address<0> = '0' then
6654            R[t] = ZeroExtend(data, 32);
6655        else // Can only apply before ARMv7
6656            R[t] = bits(32) UNKNOWN;
6657#endif
6658
6659    bool success = false;
6660
6661    if (ConditionPassed(opcode))
6662    {
6663        uint32_t t;
6664        uint32_t imm32;
6665        bool add;
6666
6667        // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
6668        switch (encoding)
6669        {
6670            case eEncodingT1:
6671                // if Rt == '1111' then SEE "Unallocated memory hints";
6672                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
6673                t = Bits32 (opcode, 15, 12);
6674                imm32 = Bits32 (opcode, 11, 0);
6675                add = BitIsSet (opcode, 23);
6676
6677                // if t == 13 then UNPREDICTABLE;
6678                if (t == 13)
6679                    return false;
6680
6681                break;
6682
6683            case eEncodingA1:
6684            {
6685                uint32_t imm4H = Bits32 (opcode, 11, 8);
6686                uint32_t imm4L = Bits32 (opcode, 3, 0);
6687
6688                // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
6689                t = Bits32 (opcode, 15, 12);
6690                imm32 = (imm4H << 4) | imm4L;
6691                add = BitIsSet (opcode, 23);
6692
6693                // if t == 15 then UNPREDICTABLE;
6694                if (t == 15)
6695                    return false;
6696                break;
6697            }
6698
6699            default:
6700                return false;
6701        }
6702
6703        // base = Align(PC,4);
6704        uint64_t pc_value = ReadCoreReg (PC_REG, &success);
6705        if (!success)
6706            return false;
6707
6708        addr_t base = AlignPC (pc_value);
6709        addr_t address;
6710
6711        // address = if add then (base + imm32) else (base - imm32);
6712        if (add)
6713            address = base + imm32;
6714        else
6715            address = base - imm32;
6716
6717        // data = MemU[address,2];
6718        RegisterInfo base_reg;
6719        GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
6720
6721        EmulateInstruction::Context context;
6722        context.type = eContextRegisterLoad;
6723        context.SetRegisterPlusOffset (base_reg, address - base);
6724
6725        uint64_t data = MemURead (context, address, 2, 0, &success);
6726        if (!success)
6727            return false;
6728
6729
6730        // if UnalignedSupport() || address<0> = '0' then
6731        if (UnalignedSupport () || BitIsClear (address, 0))
6732        {
6733            // R[t] = ZeroExtend(data, 32);
6734            context.type = eContextRegisterLoad;
6735            context.SetRegisterPlusOffset (base_reg, address - base);
6736            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6737                return false;
6738
6739        }
6740        else // Can only apply before ARMv7
6741        {
6742            // R[t] = bits(32) UNKNOWN;
6743            WriteBits32Unknown (t);
6744        }
6745    }
6746    return true;
6747}
6748
6749// LDRH (literal) calculates an address from a base register value and an offset register value, loads a halfword
6750// from memory, zero-extends it to form a 32-bit word, and writes it to a register.  The offset register value can
6751// be shifted left by 0, 1, 2, or 3 bits.
6752bool
6753EmulateInstructionARM::EmulateLDRHRegister (const uint32_t opcode, const ARMEncoding encoding)
6754{
6755#if 0
6756    if ConditionPassed() then
6757        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6758        offset = Shift(R[m], shift_t, shift_n, APSR.C);
6759        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6760        address = if index then offset_addr else R[n];
6761        data = MemU[address,2];
6762        if wback then R[n] = offset_addr;
6763        if UnalignedSupport() || address<0> = '0' then
6764            R[t] = ZeroExtend(data, 32);
6765        else // Can only apply before ARMv7
6766            R[t] = bits(32) UNKNOWN;
6767#endif
6768
6769    bool success = false;
6770
6771    if (ConditionPassed(opcode))
6772    {
6773        uint32_t t;
6774        uint32_t n;
6775        uint32_t m;
6776        bool index;
6777        bool add;
6778        bool wback;
6779        ARM_ShifterType shift_t;
6780        uint32_t shift_n;
6781
6782        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6783        switch (encoding)
6784        {
6785            case eEncodingT1:
6786                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
6787                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6788                t = Bits32 (opcode, 2, 0);
6789                n = Bits32 (opcode, 5, 3);
6790                m = Bits32 (opcode, 8, 6);
6791
6792                // index = TRUE; add = TRUE; wback = FALSE;
6793                index = true;
6794                add = true;
6795                wback = false;
6796
6797                // (shift_t, shift_n) = (SRType_LSL, 0);
6798                shift_t = SRType_LSL;
6799                shift_n = 0;
6800
6801                break;
6802
6803            case eEncodingT2:
6804                // if Rn == '1111' then SEE LDRH (literal);
6805                // if Rt == '1111' then SEE "Unallocated memory hints";
6806                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6807                t = Bits32 (opcode, 15, 12);
6808                n = Bits32 (opcode, 19, 16);
6809                m = Bits32 (opcode, 3, 0);
6810
6811                // index = TRUE; add = TRUE; wback = FALSE;
6812                index = true;
6813                add = true;
6814                wback = false;
6815
6816                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
6817                shift_t = SRType_LSL;
6818                shift_n = Bits32 (opcode, 5, 4);
6819
6820                // if t == 13 || BadReg(m) then UNPREDICTABLE;
6821                if ((t == 13) || BadReg (m))
6822                    return false;
6823                break;
6824
6825            case eEncodingA1:
6826                // if P == '0' && W == '1' then SEE LDRHT;
6827                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
6828                t = Bits32 (opcode, 15, 12);
6829                n = Bits32 (opcode, 19, 16);
6830                m = Bits32 (opcode, 3, 0);
6831
6832                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
6833                index = BitIsSet (opcode, 24);
6834                add = BitIsSet (opcode, 23);
6835                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
6836
6837                // (shift_t, shift_n) = (SRType_LSL, 0);
6838                shift_t = SRType_LSL;
6839                shift_n = 0;
6840
6841                // if t == 15 || m == 15 then UNPREDICTABLE;
6842                if ((t == 15) || (m == 15))
6843                    return false;
6844
6845                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
6846                if (wback && ((n == 15) || (n == t)))
6847                    return false;
6848
6849                break;
6850
6851            default:
6852                return false;
6853        }
6854
6855        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
6856
6857        uint64_t Rm  = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
6858        if (!success)
6859            return false;
6860
6861        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
6862        if (!success)
6863            return false;
6864
6865        addr_t offset_addr;
6866        addr_t address;
6867
6868        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
6869        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
6870        if (!success)
6871            return false;
6872
6873        if (add)
6874            offset_addr = Rn + offset;
6875        else
6876            offset_addr = Rn - offset;
6877
6878        // address = if index then offset_addr else R[n];
6879        if (index)
6880            address = offset_addr;
6881        else
6882            address = Rn;
6883
6884        // data = MemU[address,2];
6885        RegisterInfo base_reg;
6886        RegisterInfo offset_reg;
6887        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
6888        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
6889
6890        EmulateInstruction::Context context;
6891        context.type = eContextRegisterLoad;
6892        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6893        uint64_t data = MemURead (context, address, 2, 0, &success);
6894        if (!success)
6895            return false;
6896
6897        // if wback then R[n] = offset_addr;
6898        if (wback)
6899        {
6900            context.type = eContextAdjustBaseRegister;
6901            context.SetAddress (offset_addr);
6902            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
6903                return false;
6904        }
6905
6906        // if UnalignedSupport() || address<0> = '0' then
6907        if (UnalignedSupport() || BitIsClear (address, 0))
6908        {
6909            // R[t] = ZeroExtend(data, 32);
6910            context.type = eContextRegisterLoad;
6911            context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
6912            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
6913                return false;
6914        }
6915        else // Can only apply before ARMv7
6916        {
6917            // R[t] = bits(32) UNKNOWN;
6918            WriteBits32Unknown (t);
6919        }
6920    }
6921    return true;
6922}
6923
6924// LDRSB (immediate) calculates an address from a base register value and an immediate offset, loads a byte from
6925// memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed,
6926// or pre-indexed addressing.
6927bool
6928EmulateInstructionARM::EmulateLDRSBImmediate (const uint32_t opcode, const ARMEncoding encoding)
6929{
6930#if 0
6931    if ConditionPassed() then
6932        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6933        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
6934        address = if index then offset_addr else R[n];
6935        R[t] = SignExtend(MemU[address,1], 32);
6936        if wback then R[n] = offset_addr;
6937#endif
6938
6939    bool success = false;
6940
6941    if (ConditionPassed(opcode))
6942    {
6943        uint32_t t;
6944        uint32_t n;
6945        uint32_t imm32;
6946        bool index;
6947        bool add;
6948        bool wback;
6949
6950        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
6951        switch (encoding)
6952        {
6953            case eEncodingT1:
6954                // if Rt == '1111' then SEE PLI;
6955                // if Rn == '1111' then SEE LDRSB (literal);
6956                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
6957                t = Bits32 (opcode, 15, 12);
6958                n = Bits32 (opcode, 19, 16);
6959                imm32 = Bits32 (opcode, 11, 0);
6960
6961                // index = TRUE; add = TRUE; wback = FALSE;
6962                index = true;
6963                add = true;
6964                wback = false;
6965
6966                // if t == 13 then UNPREDICTABLE;
6967                if (t == 13)
6968                    return false;
6969
6970                break;
6971
6972            case eEncodingT2:
6973                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLI;
6974                // if Rn == '1111' then SEE LDRSB (literal);
6975                // if P == '1' && U == '1' && W == '0' then SEE LDRSBT;
6976                // if P == '0' && W == '0' then UNDEFINED;
6977                if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
6978                    return false;
6979
6980                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
6981                t = Bits32 (opcode, 15, 12);
6982                n = Bits32 (opcode, 19, 16);
6983                imm32 = Bits32 (opcode, 7, 0);
6984
6985                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
6986                index = BitIsSet (opcode, 10);
6987                add = BitIsSet (opcode, 9);
6988                wback = BitIsSet (opcode, 8);
6989
6990                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
6991                  if (((t == 13) || ((t == 15)
6992                                     && (BitIsClear (opcode, 10) || BitIsSet (opcode, 9) || BitIsSet (opcode, 8))))
6993                      || (wback && (n == t)))
6994                    return false;
6995
6996                break;
6997
6998            case eEncodingA1:
6999            {
7000                // if Rn == '1111' then SEE LDRSB (literal);
7001                // if P == '0' && W == '1' then SEE LDRSBT;
7002                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7003                t = Bits32 (opcode, 15, 12);
7004                n = Bits32 (opcode, 19, 16);
7005
7006                uint32_t imm4H = Bits32 (opcode, 11, 8);
7007                uint32_t imm4L = Bits32 (opcode, 3, 0);
7008                imm32 = (imm4H << 4) | imm4L;
7009
7010                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7011                index = BitIsSet (opcode, 24);
7012                add = BitIsSet (opcode, 23);
7013                wback = (BitIsClear (opcode, 24) || BitIsSet (opcode, 21));
7014
7015                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7016                if ((t == 15) || (wback && (n == t)))
7017                    return false;
7018
7019                break;
7020            }
7021
7022            default:
7023                return false;
7024        }
7025
7026        uint64_t Rn = ReadCoreReg (n, &success);
7027        if (!success)
7028            return false;
7029
7030        addr_t offset_addr;
7031        addr_t address;
7032
7033        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7034        if (add)
7035            offset_addr = Rn + imm32;
7036        else
7037            offset_addr = Rn - imm32;
7038
7039        // address = if index then offset_addr else R[n];
7040        if (index)
7041            address = offset_addr;
7042        else
7043            address = Rn;
7044
7045        // R[t] = SignExtend(MemU[address,1], 32);
7046        RegisterInfo base_reg;
7047        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7048
7049        EmulateInstruction::Context context;
7050        context.type = eContextRegisterLoad;
7051        context.SetRegisterPlusOffset (base_reg, address - Rn);
7052
7053        uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7054        if (!success)
7055            return false;
7056
7057        int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7058        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7059            return false;
7060
7061        // if wback then R[n] = offset_addr;
7062        if (wback)
7063        {
7064            context.type = eContextAdjustBaseRegister;
7065            context.SetAddress (offset_addr);
7066            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7067                return false;
7068        }
7069    }
7070
7071    return true;
7072}
7073
7074// LDRSB (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory,
7075// sign-extends it to form a 32-bit word, and writes tit to a register.
7076bool
7077EmulateInstructionARM::EmulateLDRSBLiteral (const uint32_t opcode, const ARMEncoding encoding)
7078{
7079#if 0
7080    if ConditionPassed() then
7081        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7082        base = Align(PC,4);
7083        address = if add then (base + imm32) else (base - imm32);
7084        R[t] = SignExtend(MemU[address,1], 32);
7085#endif
7086
7087    bool success = false;
7088
7089    if (ConditionPassed(opcode))
7090    {
7091        uint32_t t;
7092        uint32_t imm32;
7093        bool add;
7094
7095        // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7096        switch (encoding)
7097        {
7098            case eEncodingT1:
7099                // if Rt == '1111' then SEE PLI;
7100                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7101                t = Bits32 (opcode, 15, 12);
7102                imm32 = Bits32 (opcode, 11, 0);
7103                add = BitIsSet (opcode, 23);
7104
7105                // if t == 13 then UNPREDICTABLE;
7106                if (t == 13)
7107                    return false;
7108
7109                break;
7110
7111            case eEncodingA1:
7112            {
7113                // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7114                t = Bits32 (opcode, 15, 12);
7115                uint32_t imm4H = Bits32 (opcode, 11, 8);
7116                uint32_t imm4L = Bits32 (opcode, 3, 0);
7117                imm32 = (imm4H << 4) | imm4L;
7118                add = BitIsSet (opcode, 23);
7119
7120                // if t == 15 then UNPREDICTABLE;
7121                if (t == 15)
7122                    return false;
7123
7124                break;
7125            }
7126
7127            default:
7128                return false;
7129        }
7130
7131        // base = Align(PC,4);
7132        uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7133        if (!success)
7134            return false;
7135        uint64_t base = AlignPC (pc_value);
7136
7137        // address = if add then (base + imm32) else (base - imm32);
7138        addr_t address;
7139        if (add)
7140            address = base + imm32;
7141        else
7142            address = base - imm32;
7143
7144        // R[t] = SignExtend(MemU[address,1], 32);
7145        RegisterInfo base_reg;
7146        GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7147
7148        EmulateInstruction::Context context;
7149        context.type = eContextRegisterLoad;
7150        context.SetRegisterPlusOffset (base_reg, address - base);
7151
7152        uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7153        if (!success)
7154            return false;
7155
7156        int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7157        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7158            return false;
7159    }
7160    return true;
7161}
7162
7163// LDRSB (register) calculates an address from a base register value and an offset register value, loadsa byte from
7164// memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7165// shifted left by 0, 1, 2, or 3 bits.
7166bool
7167EmulateInstructionARM::EmulateLDRSBRegister (const uint32_t opcode, const ARMEncoding encoding)
7168{
7169#if 0
7170    if ConditionPassed() then
7171        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7172        offset = Shift(R[m], shift_t, shift_n, APSR.C);
7173        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7174        address = if index then offset_addr else R[n];
7175        R[t] = SignExtend(MemU[address,1], 32);
7176        if wback then R[n] = offset_addr;
7177#endif
7178
7179    bool success = false;
7180
7181    if (ConditionPassed(opcode))
7182    {
7183        uint32_t t;
7184        uint32_t n;
7185        uint32_t m;
7186        bool index;
7187        bool add;
7188        bool wback;
7189        ARM_ShifterType shift_t;
7190        uint32_t shift_n;
7191
7192        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7193        switch (encoding)
7194        {
7195            case eEncodingT1:
7196                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7197                t = Bits32 (opcode, 2, 0);
7198                n = Bits32 (opcode, 5, 3);
7199                m = Bits32 (opcode, 8, 6);
7200
7201                // index = TRUE; add = TRUE; wback = FALSE;
7202                index = true;
7203                add = true;
7204                wback = false;
7205
7206                // (shift_t, shift_n) = (SRType_LSL, 0);
7207                shift_t = SRType_LSL;
7208                shift_n = 0;
7209
7210                break;
7211
7212            case eEncodingT2:
7213                // if Rt == '1111' then SEE PLI;
7214                // if Rn == '1111' then SEE LDRSB (literal);
7215                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7216                t = Bits32 (opcode, 15, 12);
7217                n = Bits32 (opcode, 19, 16);
7218                m = Bits32 (opcode, 3, 0);
7219
7220                // index = TRUE; add = TRUE; wback = FALSE;
7221                index = true;
7222                add = true;
7223                wback = false;
7224
7225                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7226                shift_t = SRType_LSL;
7227                shift_n = Bits32 (opcode, 5, 4);
7228
7229                // if t == 13 || BadReg(m) then UNPREDICTABLE;
7230                if ((t == 13) || BadReg (m))
7231                    return false;
7232                break;
7233
7234            case eEncodingA1:
7235                // if P == '0' && W == '1' then SEE LDRSBT;
7236                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7237                t = Bits32 (opcode, 15, 12);
7238                n = Bits32 (opcode, 19, 16);
7239                m = Bits32 (opcode, 3, 0);
7240
7241                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7242                index = BitIsSet (opcode, 24);
7243                add = BitIsSet (opcode, 23);
7244                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7245
7246                // (shift_t, shift_n) = (SRType_LSL, 0);
7247                shift_t = SRType_LSL;
7248                shift_n = 0;
7249
7250                // if t == 15 || m == 15 then UNPREDICTABLE;
7251                if ((t == 15) || (m == 15))
7252                    return false;
7253
7254                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7255                if (wback && ((n == 15) || (n == t)))
7256                    return false;
7257                break;
7258
7259            default:
7260                return false;
7261        }
7262
7263        uint64_t Rm =  ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7264        if (!success)
7265            return false;
7266
7267        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7268        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7269        if (!success)
7270            return false;
7271
7272        addr_t offset_addr;
7273        addr_t address;
7274
7275        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7276        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7277        if (!success)
7278            return false;
7279
7280        if (add)
7281            offset_addr = Rn + offset;
7282        else
7283            offset_addr = Rn - offset;
7284
7285        // address = if index then offset_addr else R[n];
7286        if (index)
7287            address = offset_addr;
7288        else
7289            address = Rn;
7290
7291        // R[t] = SignExtend(MemU[address,1], 32);
7292        RegisterInfo base_reg;
7293        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7294        RegisterInfo offset_reg;
7295        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7296
7297        EmulateInstruction::Context context;
7298        context.type = eContextRegisterLoad;
7299        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7300
7301        uint64_t unsigned_data = MemURead (context, address, 1, 0, &success);
7302        if (!success)
7303            return false;
7304
7305        int64_t signed_data = llvm::SignExtend64<8>(unsigned_data);
7306        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7307            return false;
7308
7309        // if wback then R[n] = offset_addr;
7310        if (wback)
7311        {
7312            context.type = eContextAdjustBaseRegister;
7313            context.SetAddress (offset_addr);
7314            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7315                return false;
7316        }
7317    }
7318    return true;
7319}
7320
7321// LDRSH (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from
7322// memory, sign-extends it to form a 32-bit word, and writes it to a register.  It can use offset, post-indexed, or
7323// pre-indexed addressing.
7324bool
7325EmulateInstructionARM::EmulateLDRSHImmediate (const uint32_t opcode, const ARMEncoding encoding)
7326{
7327#if 0
7328    if ConditionPassed() then
7329        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7330        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7331        address = if index then offset_addr else R[n];
7332        data = MemU[address,2];
7333        if wback then R[n] = offset_addr;
7334        if UnalignedSupport() || address<0> = '0' then
7335            R[t] = SignExtend(data, 32);
7336        else // Can only apply before ARMv7
7337            R[t] = bits(32) UNKNOWN;
7338#endif
7339
7340    bool success = false;
7341
7342    if (ConditionPassed(opcode))
7343    {
7344        uint32_t t;
7345        uint32_t n;
7346        uint32_t imm32;
7347        bool index;
7348        bool add;
7349        bool wback;
7350
7351        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7352        switch (encoding)
7353        {
7354            case eEncodingT1:
7355                // if Rn == '1111' then SEE LDRSH (literal);
7356                // if Rt == '1111' then SEE "Unallocated memory hints";
7357                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
7358                t = Bits32 (opcode, 15, 12);
7359                n = Bits32 (opcode, 19, 16);
7360                imm32 = Bits32 (opcode, 11, 0);
7361
7362                // index = TRUE; add = TRUE; wback = FALSE;
7363                index = true;
7364                add = true;
7365                wback = false;
7366
7367                // if t == 13 then UNPREDICTABLE;
7368                if (t == 13)
7369                    return false;
7370
7371                break;
7372
7373            case eEncodingT2:
7374                // if Rn == '1111' then SEE LDRSH (literal);
7375                // if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE "Unallocated memory hints";
7376                // if P == '1' && U == '1' && W == '0' then SEE LDRSHT;
7377                // if P == '0' && W == '0' then UNDEFINED;
7378                  if (BitIsClear (opcode, 10) && BitIsClear (opcode, 8))
7379                  return false;
7380
7381                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8, 32);
7382                t = Bits32 (opcode, 15, 12);
7383                n = Bits32 (opcode, 19, 16);
7384                imm32 = Bits32 (opcode, 7, 0);
7385
7386                // index = (P == '1'); add = (U == '1'); wback = (W == '1');
7387                index = BitIsSet (opcode, 10);
7388                add = BitIsSet (opcode, 9);
7389                wback = BitIsSet (opcode, 8);
7390
7391                // if BadReg(t) || (wback && n == t) then UNPREDICTABLE;
7392                if (BadReg (t) || (wback && (n == t)))
7393                    return false;
7394
7395                break;
7396
7397            case eEncodingA1:
7398            {
7399                // if Rn == '1111' then SEE LDRSH (literal);
7400                // if P == '0' && W == '1' then SEE LDRSHT;
7401                // t == UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
7402                t = Bits32 (opcode, 15, 12);
7403                n = Bits32 (opcode, 19, 16);
7404                uint32_t imm4H = Bits32 (opcode, 11,8);
7405                uint32_t imm4L = Bits32 (opcode, 3, 0);
7406                imm32 = (imm4H << 4) | imm4L;
7407
7408                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7409                index = BitIsSet (opcode, 24);
7410                add = BitIsSet (opcode, 23);
7411                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7412
7413                // if t == 15 || (wback && n == t) then UNPREDICTABLE;
7414                if ((t == 15) || (wback && (n == t)))
7415                    return false;
7416
7417                break;
7418            }
7419
7420            default:
7421                return false;
7422        }
7423
7424        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
7425        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7426        if (!success)
7427            return false;
7428
7429        addr_t offset_addr;
7430        if (add)
7431            offset_addr = Rn + imm32;
7432        else
7433            offset_addr = Rn - imm32;
7434
7435        // address = if index then offset_addr else R[n];
7436        addr_t address;
7437        if (index)
7438            address = offset_addr;
7439        else
7440            address = Rn;
7441
7442        // data = MemU[address,2];
7443        RegisterInfo base_reg;
7444        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7445
7446        EmulateInstruction::Context context;
7447        context.type = eContextRegisterLoad;
7448        context.SetRegisterPlusOffset (base_reg, address - Rn);
7449
7450        uint64_t data = MemURead (context, address, 2, 0, &success);
7451        if (!success)
7452            return false;
7453
7454        // if wback then R[n] = offset_addr;
7455        if (wback)
7456        {
7457            context.type = eContextAdjustBaseRegister;
7458            context.SetAddress (offset_addr);
7459            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7460                return false;
7461        }
7462
7463        // if UnalignedSupport() || address<0> = '0' then
7464        if (UnalignedSupport() || BitIsClear (address, 0))
7465        {
7466            // R[t] = SignExtend(data, 32);
7467            int64_t signed_data = llvm::SignExtend64<16>(data);
7468            context.type = eContextRegisterLoad;
7469            context.SetRegisterPlusOffset (base_reg, address - Rn);
7470            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7471                return false;
7472        }
7473        else // Can only apply before ARMv7
7474        {
7475            // R[t] = bits(32) UNKNOWN;
7476            WriteBits32Unknown (t);
7477        }
7478    }
7479    return true;
7480}
7481
7482// LDRSH (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory,
7483// sign-extends it to from a 32-bit word, and writes it to a register.
7484bool
7485EmulateInstructionARM::EmulateLDRSHLiteral (const uint32_t opcode, const ARMEncoding encoding)
7486{
7487#if 0
7488    if ConditionPassed() then
7489        EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7490        base = Align(PC,4);
7491        address = if add then (base + imm32) else (base - imm32);
7492        data = MemU[address,2];
7493        if UnalignedSupport() || address<0> = '0' then
7494            R[t] = SignExtend(data, 32);
7495        else // Can only apply before ARMv7
7496            R[t] = bits(32) UNKNOWN;
7497#endif
7498
7499    bool success = false;
7500
7501    if (ConditionPassed(opcode))
7502    {
7503        uint32_t t;
7504        uint32_t imm32;
7505        bool add;
7506
7507        // EncodingSpecificOperations(); NullCheckIfThumbEE(15);
7508        switch (encoding)
7509        {
7510            case eEncodingT1:
7511                // if Rt == '1111' then SEE "Unallocated memory hints";
7512                // t = UInt(Rt); imm32 = ZeroExtend(imm12, 32); add = (U == '1');
7513                t = Bits32  (opcode, 15, 12);
7514                imm32 = Bits32 (opcode, 11, 0);
7515                add = BitIsSet (opcode, 23);
7516
7517                // if t == 13 then UNPREDICTABLE;
7518                if (t == 13)
7519                    return false;
7520
7521                break;
7522
7523            case eEncodingA1:
7524            {
7525                // t == UInt(Rt); imm32 = ZeroExtend(imm4H:imm4L, 32); add = (U == '1');
7526                t = Bits32 (opcode, 15, 12);
7527                uint32_t imm4H = Bits32 (opcode, 11, 8);
7528                uint32_t imm4L = Bits32 (opcode, 3, 0);
7529                imm32 = (imm4H << 4) | imm4L;
7530                add = BitIsSet (opcode, 23);
7531
7532                // if t == 15 then UNPREDICTABLE;
7533                if (t == 15)
7534                    return false;
7535
7536                break;
7537            }
7538            default:
7539                return false;
7540        }
7541
7542        // base = Align(PC,4);
7543        uint64_t pc_value = ReadCoreReg (PC_REG, &success);
7544        if (!success)
7545            return false;
7546
7547        uint64_t base = AlignPC (pc_value);
7548
7549        addr_t address;
7550        // address = if add then (base + imm32) else (base - imm32);
7551        if (add)
7552            address = base + imm32;
7553        else
7554            address = base - imm32;
7555
7556        // data = MemU[address,2];
7557        RegisterInfo base_reg;
7558        GetRegisterInfo (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, base_reg);
7559
7560        EmulateInstruction::Context context;
7561        context.type = eContextRegisterLoad;
7562        context.SetRegisterPlusOffset (base_reg, imm32);
7563
7564        uint64_t data = MemURead (context, address, 2, 0, &success);
7565        if (!success)
7566            return false;
7567
7568        // if UnalignedSupport() || address<0> = '0' then
7569        if (UnalignedSupport() || BitIsClear (address, 0))
7570        {
7571            // R[t] = SignExtend(data, 32);
7572            int64_t signed_data = llvm::SignExtend64<16>(data);
7573            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7574                return false;
7575        }
7576        else // Can only apply before ARMv7
7577        {
7578            // R[t] = bits(32) UNKNOWN;
7579            WriteBits32Unknown (t);
7580        }
7581    }
7582    return true;
7583}
7584
7585// LDRSH (register) calculates an address from a base register value and an offset register value, loads a halfword
7586// from memory, sign-extends it to form a 32-bit word, and writes it to a register.  The offset register value can be
7587// shifted left by 0, 1, 2, or 3 bits.
7588bool
7589EmulateInstructionARM::EmulateLDRSHRegister (const uint32_t opcode, const ARMEncoding encoding)
7590{
7591#if 0
7592    if ConditionPassed() then
7593        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7594        offset = Shift(R[m], shift_t, shift_n, APSR.C);
7595        offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7596        address = if index then offset_addr else R[n];
7597        data = MemU[address,2];
7598        if wback then R[n] = offset_addr;
7599        if UnalignedSupport() || address<0> = '0' then
7600            R[t] = SignExtend(data, 32);
7601        else // Can only apply before ARMv7
7602            R[t] = bits(32) UNKNOWN;
7603#endif
7604
7605    bool success = false;
7606
7607    if (ConditionPassed(opcode))
7608    {
7609        uint32_t t;
7610        uint32_t n;
7611        uint32_t m;
7612        bool index;
7613        bool add;
7614        bool wback;
7615        ARM_ShifterType shift_t;
7616        uint32_t shift_n;
7617
7618        // EncodingSpecificOperations(); NullCheckIfThumbEE(n);
7619        switch (encoding)
7620        {
7621            case eEncodingT1:
7622                // if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE";
7623                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7624                t = Bits32 (opcode, 2, 0);
7625                n = Bits32 (opcode, 5, 3);
7626                m = Bits32 (opcode, 8, 6);
7627
7628                // index = TRUE; add = TRUE; wback = FALSE;
7629                index = true;
7630                add = true;
7631                wback = false;
7632
7633                // (shift_t, shift_n) = (SRType_LSL, 0);
7634                shift_t = SRType_LSL;
7635                shift_n = 0;
7636
7637                break;
7638
7639            case eEncodingT2:
7640                // if Rn == '1111' then SEE LDRSH (literal);
7641                // if Rt == '1111' then SEE "Unallocated memory hints";
7642                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7643                t = Bits32 (opcode, 15, 12);
7644                n = Bits32 (opcode, 19, 16);
7645                m = Bits32 (opcode, 3, 0);
7646
7647                // index = TRUE; add = TRUE; wback = FALSE;
7648                index = true;
7649                add = true;
7650                wback = false;
7651
7652                // (shift_t, shift_n) = (SRType_LSL, UInt(imm2));
7653                shift_t = SRType_LSL;
7654                shift_n = Bits32 (opcode, 5, 4);
7655
7656                // if t == 13 || BadReg(m) then UNPREDICTABLE;
7657                if ((t == 13) || BadReg (m))
7658                    return false;
7659
7660                break;
7661
7662            case eEncodingA1:
7663                // if P == '0' && W == '1' then SEE LDRSHT;
7664                // t = UInt(Rt); n = UInt(Rn); m = UInt(Rm);
7665                t = Bits32 (opcode, 15, 12);
7666                n = Bits32 (opcode, 19, 16);
7667                m = Bits32 (opcode, 3, 0);
7668
7669                // index = (P == '1');	add = (U == '1');	wback = (P == '0') || (W == '1');
7670                index = BitIsSet (opcode, 24);
7671                add = BitIsSet (opcode, 23);
7672                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
7673
7674                // (shift_t, shift_n) = (SRType_LSL, 0);
7675                shift_t = SRType_LSL;
7676                shift_n = 0;
7677
7678                // if t == 15 || m == 15 then UNPREDICTABLE;
7679                if ((t == 15) || (m == 15))
7680                    return false;
7681
7682                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
7683                if (wback && ((n == 15) || (n == t)))
7684                    return false;
7685
7686                break;
7687
7688            default:
7689                return false;
7690        }
7691
7692        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7693        if (!success)
7694            return false;
7695
7696        uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
7697        if (!success)
7698            return false;
7699
7700        // offset = Shift(R[m], shift_t, shift_n, APSR.C);
7701        addr_t offset = Shift (Rm, shift_t, shift_n, APSR_C, &success);
7702        if (!success)
7703            return false;
7704
7705        addr_t offset_addr;
7706        addr_t address;
7707
7708        // offset_addr = if add then (R[n] + offset) else (R[n] - offset);
7709        if (add)
7710            offset_addr = Rn + offset;
7711        else
7712            offset_addr = Rn - offset;
7713
7714        // address = if index then offset_addr else R[n];
7715        if (index)
7716            address = offset_addr;
7717        else
7718            address = Rn;
7719
7720        // data = MemU[address,2];
7721        RegisterInfo base_reg;
7722        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
7723
7724        RegisterInfo offset_reg;
7725        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
7726
7727        EmulateInstruction::Context context;
7728        context.type = eContextRegisterLoad;
7729        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7730
7731        uint64_t data = MemURead (context, address, 2, 0, &success);
7732        if (!success)
7733            return false;
7734
7735        // if wback then R[n] = offset_addr;
7736        if (wback)
7737        {
7738            context.type = eContextAdjustBaseRegister;
7739            context.SetAddress (offset_addr);
7740            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
7741                return false;
7742        }
7743
7744        // if UnalignedSupport() || address<0> = '0' then
7745        if (UnalignedSupport() || BitIsClear (address, 0))
7746        {
7747            // R[t] = SignExtend(data, 32);
7748            context.type = eContextRegisterLoad;
7749            context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
7750
7751            int64_t signed_data = llvm::SignExtend64<16>(data);
7752            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, (uint64_t) signed_data))
7753                return false;
7754        }
7755        else // Can only apply before ARMv7
7756        {
7757            // R[t] = bits(32) UNKNOWN;
7758            WriteBits32Unknown (t);
7759        }
7760    }
7761    return true;
7762}
7763
7764// SXTB extracts an 8-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7765// register.  You can specifiy a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7766bool
7767EmulateInstructionARM::EmulateSXTB (const uint32_t opcode, const ARMEncoding encoding)
7768{
7769#if 0
7770    if ConditionPassed() then
7771        EncodingSpecificOperations();
7772        rotated = ROR(R[m], rotation);
7773        R[d] = SignExtend(rotated<7:0>, 32);
7774#endif
7775
7776    bool success = false;
7777
7778    if (ConditionPassed(opcode))
7779    {
7780        uint32_t d;
7781        uint32_t m;
7782        uint32_t rotation;
7783
7784        // EncodingSpecificOperations();
7785        switch (encoding)
7786        {
7787            case eEncodingT1:
7788                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7789                d = Bits32 (opcode, 2, 0);
7790                m = Bits32 (opcode, 5, 3);
7791                rotation = 0;
7792
7793                break;
7794
7795            case eEncodingT2:
7796                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7797                d = Bits32 (opcode, 11, 8);
7798                m = Bits32 (opcode, 3, 0);
7799                rotation = Bits32 (opcode, 5, 4) << 3;
7800
7801                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7802                if (BadReg (d) || BadReg (m))
7803                    return false;
7804
7805                break;
7806
7807            case eEncodingA1:
7808                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7809                d = Bits32 (opcode, 15, 12);
7810                m = Bits32 (opcode, 3, 0);
7811                rotation = Bits32 (opcode, 11, 10) << 3;
7812
7813                // if d == 15 || m == 15 then UNPREDICTABLE;
7814                if ((d == 15) || (m == 15))
7815                    return false;
7816
7817                break;
7818
7819            default:
7820                return false;
7821        }
7822
7823        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7824        if (!success)
7825            return false;
7826
7827        // rotated = ROR(R[m], rotation);
7828        uint64_t rotated = ROR (Rm, rotation, &success);
7829        if (!success)
7830            return false;
7831
7832        // R[d] = SignExtend(rotated<7:0>, 32);
7833        int64_t data = llvm::SignExtend64<8>(rotated);
7834
7835        RegisterInfo source_reg;
7836        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7837
7838        EmulateInstruction::Context context;
7839        context.type = eContextRegisterLoad;
7840        context.SetRegister (source_reg);
7841
7842        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7843            return false;
7844    }
7845    return true;
7846}
7847
7848// SXTH extracts a 16-bit value from a register, sign-extends it to 32 bits, and writes the result to the destination
7849// register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
7850bool
7851EmulateInstructionARM::EmulateSXTH (const uint32_t opcode, const ARMEncoding encoding)
7852{
7853#if 0
7854    if ConditionPassed() then
7855        EncodingSpecificOperations();
7856        rotated = ROR(R[m], rotation);
7857        R[d] = SignExtend(rotated<15:0>, 32);
7858#endif
7859
7860    bool success = false;
7861
7862    if (ConditionPassed(opcode))
7863    {
7864        uint32_t d;
7865        uint32_t m;
7866        uint32_t rotation;
7867
7868        // EncodingSpecificOperations();
7869        switch (encoding)
7870        {
7871            case eEncodingT1:
7872                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7873                d = Bits32 (opcode, 2, 0);
7874                m = Bits32 (opcode, 5, 3);
7875                rotation = 0;
7876
7877                break;
7878
7879            case eEncodingT2:
7880                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7881                d = Bits32 (opcode, 11, 8);
7882                m = Bits32 (opcode, 3, 0);
7883                rotation = Bits32 (opcode, 5, 4) << 3;
7884
7885                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7886                if (BadReg (d) || BadReg (m))
7887                    return false;
7888
7889                break;
7890
7891            case eEncodingA1:
7892                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7893                d = Bits32 (opcode, 15, 12);
7894                m = Bits32 (opcode, 3, 0);
7895                rotation = Bits32 (opcode, 11, 10) << 3;
7896
7897                // if d == 15 || m == 15 then UNPREDICTABLE;
7898                if ((d == 15) || (m == 15))
7899                    return false;
7900
7901                break;
7902
7903            default:
7904                return false;
7905        }
7906
7907        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7908        if (!success)
7909            return false;
7910
7911        // rotated = ROR(R[m], rotation);
7912        uint64_t rotated = ROR (Rm, rotation, &success);
7913        if (!success)
7914            return false;
7915
7916        // R[d] = SignExtend(rotated<15:0>, 32);
7917        RegisterInfo source_reg;
7918        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
7919
7920        EmulateInstruction::Context context;
7921        context.type = eContextRegisterLoad;
7922        context.SetRegister (source_reg);
7923
7924        int64_t data = llvm::SignExtend64<16> (rotated);
7925        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, (uint64_t) data))
7926            return false;
7927    }
7928
7929    return true;
7930}
7931
7932// UXTB extracts an 8-bit value from a register, zero-extneds it to 32 bits, and writes the result to the destination
7933// register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.
7934bool
7935EmulateInstructionARM::EmulateUXTB (const uint32_t opcode, const ARMEncoding encoding)
7936{
7937#if 0
7938    if ConditionPassed() then
7939        EncodingSpecificOperations();
7940        rotated = ROR(R[m], rotation);
7941        R[d] = ZeroExtend(rotated<7:0>, 32);
7942#endif
7943
7944    bool success = false;
7945
7946    if (ConditionPassed(opcode))
7947    {
7948        uint32_t d;
7949        uint32_t m;
7950        uint32_t rotation;
7951
7952        // EncodingSpecificOperations();
7953        switch (encoding)
7954        {
7955            case eEncodingT1:
7956                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
7957                d = Bits32 (opcode, 2, 0);
7958                m = Bits32 (opcode, 5, 3);
7959                rotation = 0;
7960
7961                break;
7962
7963            case eEncodingT2:
7964                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7965                d = Bits32 (opcode, 11, 8);
7966                m = Bits32 (opcode, 3, 0);
7967                  rotation = Bits32 (opcode, 5, 4) << 3;
7968
7969                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
7970                if (BadReg (d) || BadReg (m))
7971                  return false;
7972
7973                break;
7974
7975            case eEncodingA1:
7976                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
7977                d = Bits32 (opcode, 15, 12);
7978                m = Bits32 (opcode, 3, 0);
7979                rotation = Bits32 (opcode, 11, 10) << 3;
7980
7981                // if d == 15 || m == 15 then UNPREDICTABLE;
7982                if ((d == 15) || (m == 15))
7983                    return false;
7984
7985                break;
7986
7987            default:
7988                return false;
7989        }
7990
7991        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
7992        if (!success)
7993            return false;
7994
7995        // rotated = ROR(R[m], rotation);
7996        uint64_t rotated = ROR (Rm, rotation, &success);
7997        if (!success)
7998            return false;
7999
8000        // R[d] = ZeroExtend(rotated<7:0>, 32);
8001        RegisterInfo source_reg;
8002        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8003
8004        EmulateInstruction::Context context;
8005        context.type = eContextRegisterLoad;
8006        context.SetRegister (source_reg);
8007
8008        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 7, 0)))
8009            return false;
8010    }
8011    return true;
8012}
8013
8014// UXTH extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination
8015// register.  You can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.
8016bool
8017EmulateInstructionARM::EmulateUXTH (const uint32_t opcode, const ARMEncoding encoding)
8018{
8019#if 0
8020    if ConditionPassed() then
8021        EncodingSpecificOperations();
8022        rotated = ROR(R[m], rotation);
8023        R[d] = ZeroExtend(rotated<15:0>, 32);
8024#endif
8025
8026    bool success = false;
8027
8028    if (ConditionPassed(opcode))
8029    {
8030        uint32_t d;
8031        uint32_t m;
8032        uint32_t rotation;
8033
8034        switch (encoding)
8035        {
8036            case eEncodingT1:
8037                // d = UInt(Rd); m = UInt(Rm); rotation = 0;
8038                d = Bits32 (opcode, 2, 0);
8039                m = Bits32 (opcode, 5, 3);
8040                rotation = 0;
8041
8042                break;
8043
8044            case eEncodingT2:
8045                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8046                d = Bits32 (opcode, 11, 8);
8047                m = Bits32 (opcode, 3, 0);
8048                rotation = Bits32 (opcode, 5, 4) << 3;
8049
8050                // if BadReg(d) || BadReg(m) then UNPREDICTABLE;
8051                if (BadReg (d) || BadReg (m))
8052                  return false;
8053
8054                break;
8055
8056            case eEncodingA1:
8057                // d = UInt(Rd); m = UInt(Rm); rotation = UInt(rotate:'000');
8058                d = Bits32 (opcode, 15, 12);
8059                m = Bits32 (opcode, 3, 0);
8060                rotation = Bits32 (opcode, 11, 10) << 3;
8061
8062                // if d == 15 || m == 15 then UNPREDICTABLE;
8063                if ((d == 15) || (m == 15))
8064                    return false;
8065
8066                break;
8067
8068            default:
8069                return false;
8070        }
8071
8072        uint64_t Rm = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + m, 0, &success);
8073        if (!success)
8074            return false;
8075
8076        // rotated = ROR(R[m], rotation);
8077        uint64_t rotated = ROR (Rm, rotation, &success);
8078        if (!success)
8079            return false;
8080
8081        // R[d] = ZeroExtend(rotated<15:0>, 32);
8082        RegisterInfo source_reg;
8083        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, source_reg);
8084
8085        EmulateInstruction::Context context;
8086        context.type = eContextRegisterLoad;
8087        context.SetRegister (source_reg);
8088
8089        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, Bits32 (rotated, 15, 0)))
8090            return false;
8091    }
8092    return true;
8093}
8094
8095// RFE (Return From Exception) loads the PC and the CPSR from the word at the specified address and the following
8096// word respectively.
8097bool
8098EmulateInstructionARM::EmulateRFE (const uint32_t opcode, const ARMEncoding encoding)
8099{
8100#if 0
8101    if ConditionPassed() then
8102        EncodingSpecificOperations();
8103        if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8104            UNPREDICTABLE;
8105        else
8106            address = if increment then R[n] else R[n]-8;
8107            if wordhigher then address = address+4;
8108            CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8109            BranchWritePC(MemA[address,4]);
8110            if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8111#endif
8112
8113    bool success = false;
8114
8115    if (ConditionPassed(opcode))
8116    {
8117        uint32_t n;
8118        bool wback;
8119        bool increment;
8120        bool wordhigher;
8121
8122        // EncodingSpecificOperations();
8123        switch (encoding)
8124        {
8125            case eEncodingT1:
8126                // n = UInt(Rn); wback = (W == '1'); increment = FALSE; wordhigher = FALSE;
8127                n = Bits32 (opcode, 19, 16);
8128                wback = BitIsSet (opcode, 21);
8129                increment = false;
8130                wordhigher = false;
8131
8132                // if n == 15 then UNPREDICTABLE;
8133                if (n == 15)
8134                    return false;
8135
8136                // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8137                if (InITBlock() && !LastInITBlock())
8138                    return false;
8139
8140                break;
8141
8142            case eEncodingT2:
8143                // n = UInt(Rn); wback = (W == '1'); increment = TRUE; wordhigher = FALSE;
8144                n = Bits32 (opcode, 19, 16);
8145                wback = BitIsSet (opcode, 21);
8146                increment = true;
8147                wordhigher = false;
8148
8149                // if n == 15 then UNPREDICTABLE;
8150                if (n == 15)
8151                    return false;
8152
8153                // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
8154                if (InITBlock() && !LastInITBlock())
8155                    return false;
8156
8157                break;
8158
8159            case eEncodingA1:
8160                // n = UInt(Rn);
8161                n = Bits32 (opcode, 19, 16);
8162
8163                // wback = (W == '1'); inc = (U == '1'); wordhigher = (P == U);
8164                wback = BitIsSet (opcode, 21);
8165                increment = BitIsSet (opcode, 23);
8166                wordhigher = (Bit32 (opcode, 24) == Bit32 (opcode, 23));
8167
8168                // if n == 15 then UNPREDICTABLE;
8169                if (n == 15)
8170                    return false;
8171
8172                break;
8173
8174            default:
8175                return false;
8176        }
8177
8178        // if !CurrentModeIsPrivileged() || CurrentInstrSet() == InstrSet_ThumbEE then
8179        if (!CurrentModeIsPrivileged ())
8180            // UNPREDICTABLE;
8181            return false;
8182        else
8183        {
8184            uint64_t Rn = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + n, 0, &success);
8185            if (!success)
8186                return false;
8187
8188            addr_t address;
8189            // address = if increment then R[n] else R[n]-8;
8190            if (increment)
8191                address = Rn;
8192            else
8193                address = Rn - 8;
8194
8195            // if wordhigher then address = address+4;
8196            if (wordhigher)
8197                address = address + 4;
8198
8199            // CPSRWriteByInstr(MemA[address+4,4], '1111', TRUE);
8200            RegisterInfo base_reg;
8201            GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
8202
8203            EmulateInstruction::Context context;
8204            context.type = eContextReturnFromException;
8205            context.SetRegisterPlusOffset (base_reg, address - Rn);
8206
8207            uint64_t data = MemARead (context, address + 4, 4, 0, &success);
8208            if (!success)
8209                return false;
8210
8211            CPSRWriteByInstr (data, 15, true);
8212
8213            // BranchWritePC(MemA[address,4]);
8214            uint64_t data2 = MemARead (context, address, 4, 0, &success);
8215            if (!success)
8216                return false;
8217
8218            BranchWritePC (context, data2);
8219
8220            // if wback then R[n] = if increment then R[n]+8 else R[n]-8;
8221            if (wback)
8222            {
8223                context.type = eContextAdjustBaseRegister;
8224                if (increment)
8225                {
8226                    context.SetOffset (8);
8227                    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + 8))
8228                        return false;
8229                }
8230                else
8231                {
8232                    context.SetOffset (-8);
8233                    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn - 8))
8234                        return false;
8235                }
8236            } // if wback
8237        }
8238    } // if ConditionPassed()
8239    return true;
8240}
8241
8242// Bitwise Exclusive OR (immediate) performs a bitwise exclusive OR of a register value and an immediate value,
8243// and writes the result to the destination register.  It can optionally update the condition flags based on
8244// the result.
8245bool
8246EmulateInstructionARM::EmulateEORImm (const uint32_t opcode, const ARMEncoding encoding)
8247{
8248#if 0
8249    // ARM pseudo code...
8250    if ConditionPassed() then
8251        EncodingSpecificOperations();
8252        result = R[n] EOR imm32;
8253        if d == 15 then         // Can only occur for ARM encoding
8254            ALUWritePC(result); // setflags is always FALSE here
8255        else
8256            R[d] = result;
8257            if setflags then
8258                APSR.N = result<31>;
8259                APSR.Z = IsZeroBit(result);
8260                APSR.C = carry;
8261                // APSR.V unchanged
8262#endif
8263
8264    bool success = false;
8265
8266    if (ConditionPassed(opcode))
8267    {
8268        uint32_t Rd, Rn;
8269        uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8270        bool setflags;
8271        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8272        switch (encoding)
8273        {
8274        case eEncodingT1:
8275            Rd = Bits32(opcode, 11, 8);
8276            Rn = Bits32(opcode, 19, 16);
8277            setflags = BitIsSet(opcode, 20);
8278            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8279            // if Rd == '1111' && S == '1' then SEE TEQ (immediate);
8280            if (Rd == 15 && setflags)
8281                return EmulateTEQImm (opcode, eEncodingT1);
8282            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn))
8283                return false;
8284            break;
8285        case eEncodingA1:
8286            Rd = Bits32(opcode, 15, 12);
8287            Rn = Bits32(opcode, 19, 16);
8288            setflags = BitIsSet(opcode, 20);
8289            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8290
8291            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8292            if (Rd == 15 && setflags)
8293                return EmulateSUBSPcLrEtc (opcode, encoding);
8294            break;
8295        default:
8296            return false;
8297        }
8298
8299        // Read the first operand.
8300        uint32_t val1 = ReadCoreReg(Rn, &success);
8301        if (!success)
8302            return false;
8303
8304        uint32_t result = val1 ^ imm32;
8305
8306        EmulateInstruction::Context context;
8307        context.type = EmulateInstruction::eContextImmediate;
8308        context.SetNoArgs ();
8309
8310        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8311            return false;
8312    }
8313    return true;
8314}
8315
8316// Bitwise Exclusive OR (register) performs a bitwise exclusive OR of a register value and an
8317// optionally-shifted register value, and writes the result to the destination register.
8318// It can optionally update the condition flags based on the result.
8319bool
8320EmulateInstructionARM::EmulateEORReg (const uint32_t opcode, const ARMEncoding encoding)
8321{
8322#if 0
8323    // ARM pseudo code...
8324    if ConditionPassed() then
8325        EncodingSpecificOperations();
8326        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8327        result = R[n] EOR shifted;
8328        if d == 15 then         // Can only occur for ARM encoding
8329            ALUWritePC(result); // setflags is always FALSE here
8330        else
8331            R[d] = result;
8332            if setflags then
8333                APSR.N = result<31>;
8334                APSR.Z = IsZeroBit(result);
8335                APSR.C = carry;
8336                // APSR.V unchanged
8337#endif
8338
8339    bool success = false;
8340
8341    if (ConditionPassed(opcode))
8342    {
8343        uint32_t Rd, Rn, Rm;
8344        ARM_ShifterType shift_t;
8345        uint32_t shift_n; // the shift applied to the value read from Rm
8346        bool setflags;
8347        uint32_t carry;
8348        switch (encoding)
8349        {
8350        case eEncodingT1:
8351            Rd = Rn = Bits32(opcode, 2, 0);
8352            Rm = Bits32(opcode, 5, 3);
8353            setflags = !InITBlock();
8354            shift_t = SRType_LSL;
8355            shift_n = 0;
8356            break;
8357        case eEncodingT2:
8358            Rd = Bits32(opcode, 11, 8);
8359            Rn = Bits32(opcode, 19, 16);
8360            Rm = Bits32(opcode, 3, 0);
8361            setflags = BitIsSet(opcode, 20);
8362            shift_n = DecodeImmShiftThumb(opcode, shift_t);
8363            // if Rd == '1111' && S == '1' then SEE TEQ (register);
8364            if (Rd == 15 && setflags)
8365                return EmulateTEQReg (opcode, eEncodingT1);
8366            if (Rd == 13 || (Rd == 15 && !setflags) || BadReg(Rn) || BadReg(Rm))
8367                return false;
8368            break;
8369        case eEncodingA1:
8370            Rd = Bits32(opcode, 15, 12);
8371            Rn = Bits32(opcode, 19, 16);
8372            Rm = Bits32(opcode, 3, 0);
8373            setflags = BitIsSet(opcode, 20);
8374            shift_n = DecodeImmShiftARM(opcode, shift_t);
8375
8376            // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8377            if (Rd == 15 && setflags)
8378                return EmulateSUBSPcLrEtc (opcode, encoding);
8379            break;
8380        default:
8381            return false;
8382        }
8383
8384        // Read the first operand.
8385        uint32_t val1 = ReadCoreReg(Rn, &success);
8386        if (!success)
8387            return false;
8388
8389        // Read the second operand.
8390        uint32_t val2 = ReadCoreReg(Rm, &success);
8391        if (!success)
8392            return false;
8393
8394        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8395        if (!success)
8396            return false;
8397        uint32_t result = val1 ^ shifted;
8398
8399        EmulateInstruction::Context context;
8400        context.type = EmulateInstruction::eContextImmediate;
8401        context.SetNoArgs ();
8402
8403        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8404            return false;
8405    }
8406    return true;
8407}
8408
8409// Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and
8410// writes the result to the destination register.  It can optionally update the condition flags based
8411// on the result.
8412bool
8413EmulateInstructionARM::EmulateORRImm (const uint32_t opcode, const ARMEncoding encoding)
8414{
8415#if 0
8416    // ARM pseudo code...
8417    if ConditionPassed() then
8418        EncodingSpecificOperations();
8419        result = R[n] OR imm32;
8420        if d == 15 then         // Can only occur for ARM encoding
8421            ALUWritePC(result); // setflags is always FALSE here
8422        else
8423            R[d] = result;
8424            if setflags then
8425                APSR.N = result<31>;
8426                APSR.Z = IsZeroBit(result);
8427                APSR.C = carry;
8428                // APSR.V unchanged
8429#endif
8430
8431    bool success = false;
8432
8433    if (ConditionPassed(opcode))
8434    {
8435        uint32_t Rd, Rn;
8436        uint32_t imm32; // the immediate value to be ORed to the value obtained from Rn
8437        bool setflags;
8438        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
8439        switch (encoding)
8440        {
8441        case eEncodingT1:
8442            Rd = Bits32(opcode, 11, 8);
8443            Rn = Bits32(opcode, 19, 16);
8444            setflags = BitIsSet(opcode, 20);
8445            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
8446            // if Rn == '1111' then SEE MOV (immediate);
8447            if (Rn == 15)
8448                return EmulateMOVRdImm (opcode, eEncodingT2);
8449            if (BadReg(Rd) || Rn == 13)
8450                return false;
8451            break;
8452        case eEncodingA1:
8453            Rd = Bits32(opcode, 15, 12);
8454            Rn = Bits32(opcode, 19, 16);
8455            setflags = BitIsSet(opcode, 20);
8456            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
8457
8458            if (Rd == 15 && setflags)
8459                return EmulateSUBSPcLrEtc (opcode, encoding);
8460            break;
8461        default:
8462            return false;
8463        }
8464
8465        // Read the first operand.
8466        uint32_t val1 = ReadCoreReg(Rn, &success);
8467        if (!success)
8468            return false;
8469
8470        uint32_t result = val1 | imm32;
8471
8472        EmulateInstruction::Context context;
8473        context.type = EmulateInstruction::eContextImmediate;
8474        context.SetNoArgs ();
8475
8476        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8477            return false;
8478    }
8479    return true;
8480}
8481
8482// Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register
8483// value, and writes the result to the destination register.  It can optionally update the condition flags based
8484// on the result.
8485bool
8486EmulateInstructionARM::EmulateORRReg (const uint32_t opcode, const ARMEncoding encoding)
8487{
8488#if 0
8489    // ARM pseudo code...
8490    if ConditionPassed() then
8491        EncodingSpecificOperations();
8492        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
8493        result = R[n] OR shifted;
8494        if d == 15 then         // Can only occur for ARM encoding
8495            ALUWritePC(result); // setflags is always FALSE here
8496        else
8497            R[d] = result;
8498            if setflags then
8499                APSR.N = result<31>;
8500                APSR.Z = IsZeroBit(result);
8501                APSR.C = carry;
8502                // APSR.V unchanged
8503#endif
8504
8505    bool success = false;
8506
8507    if (ConditionPassed(opcode))
8508    {
8509        uint32_t Rd, Rn, Rm;
8510        ARM_ShifterType shift_t;
8511        uint32_t shift_n; // the shift applied to the value read from Rm
8512        bool setflags;
8513        uint32_t carry;
8514        switch (encoding)
8515        {
8516        case eEncodingT1:
8517            Rd = Rn = Bits32(opcode, 2, 0);
8518            Rm = Bits32(opcode, 5, 3);
8519            setflags = !InITBlock();
8520            shift_t = SRType_LSL;
8521            shift_n = 0;
8522            break;
8523        case eEncodingT2:
8524            Rd = Bits32(opcode, 11, 8);
8525            Rn = Bits32(opcode, 19, 16);
8526            Rm = Bits32(opcode, 3, 0);
8527            setflags = BitIsSet(opcode, 20);
8528            shift_n = DecodeImmShiftThumb(opcode, shift_t);
8529            // if Rn == '1111' then SEE MOV (register);
8530            if (Rn == 15)
8531                return EmulateMOVRdRm (opcode, eEncodingT3);
8532            if (BadReg(Rd) || Rn == 13 || BadReg(Rm))
8533                return false;
8534            break;
8535        case eEncodingA1:
8536            Rd = Bits32(opcode, 15, 12);
8537            Rn = Bits32(opcode, 19, 16);
8538            Rm = Bits32(opcode, 3, 0);
8539            setflags = BitIsSet(opcode, 20);
8540            shift_n = DecodeImmShiftARM(opcode, shift_t);
8541
8542            if (Rd == 15 && setflags)
8543                return EmulateSUBSPcLrEtc (opcode, encoding);
8544            break;
8545        default:
8546            return false;
8547        }
8548
8549        // Read the first operand.
8550        uint32_t val1 = ReadCoreReg(Rn, &success);
8551        if (!success)
8552            return false;
8553
8554        // Read the second operand.
8555        uint32_t val2 = ReadCoreReg(Rm, &success);
8556        if (!success)
8557            return false;
8558
8559        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
8560        if (!success)
8561            return false;
8562        uint32_t result = val1 | shifted;
8563
8564        EmulateInstruction::Context context;
8565        context.type = EmulateInstruction::eContextImmediate;
8566        context.SetNoArgs ();
8567
8568        if (!WriteCoreRegOptionalFlags(context, result, Rd, setflags, carry))
8569            return false;
8570    }
8571    return true;
8572}
8573
8574// Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to
8575// the destination register. It can optionally update the condition flags based on the result.
8576bool
8577EmulateInstructionARM::EmulateRSBImm (const uint32_t opcode, const ARMEncoding encoding)
8578{
8579#if 0
8580    // ARM pseudo code...
8581    if ConditionPassed() then
8582        EncodingSpecificOperations();
8583        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, '1');
8584        if d == 15 then         // Can only occur for ARM encoding
8585            ALUWritePC(result); // setflags is always FALSE here
8586        else
8587            R[d] = result;
8588            if setflags then
8589                APSR.N = result<31>;
8590                APSR.Z = IsZeroBit(result);
8591                APSR.C = carry;
8592                APSR.V = overflow;
8593#endif
8594
8595    bool success = false;
8596
8597    uint32_t Rd; // the destination register
8598    uint32_t Rn; // the first operand
8599    bool setflags;
8600    uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8601    switch (encoding) {
8602    case eEncodingT1:
8603        Rd = Bits32(opcode, 2, 0);
8604        Rn = Bits32(opcode, 5, 3);
8605        setflags = !InITBlock();
8606        imm32 = 0;
8607        break;
8608    case eEncodingT2:
8609        Rd = Bits32(opcode, 11, 8);
8610        Rn = Bits32(opcode, 19, 16);
8611        setflags = BitIsSet(opcode, 20);
8612        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8613        if (BadReg(Rd) || BadReg(Rn))
8614            return false;
8615        break;
8616    case eEncodingA1:
8617        Rd = Bits32(opcode, 15, 12);
8618        Rn = Bits32(opcode, 19, 16);
8619        setflags = BitIsSet(opcode, 20);
8620        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8621
8622        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8623        if (Rd == 15 && setflags)
8624            return EmulateSUBSPcLrEtc (opcode, encoding);
8625        break;
8626    default:
8627        return false;
8628    }
8629    // Read the register value from the operand register Rn.
8630    uint32_t reg_val = ReadCoreReg(Rn, &success);
8631    if (!success)
8632        return false;
8633
8634    AddWithCarryResult res = AddWithCarry(~reg_val, imm32, 1);
8635
8636    EmulateInstruction::Context context;
8637    context.type = EmulateInstruction::eContextImmediate;
8638    context.SetNoArgs ();
8639
8640    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8641        return false;
8642
8643    return true;
8644}
8645
8646// Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the
8647// result to the destination register. It can optionally update the condition flags based on the result.
8648bool
8649EmulateInstructionARM::EmulateRSBReg (const uint32_t opcode, const ARMEncoding encoding)
8650{
8651#if 0
8652    // ARM pseudo code...
8653    if ConditionPassed() then
8654        EncodingSpecificOperations();
8655        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8656        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, '1');
8657        if d == 15 then         // Can only occur for ARM encoding
8658            ALUWritePC(result); // setflags is always FALSE here
8659        else
8660            R[d] = result;
8661            if setflags then
8662                APSR.N = result<31>;
8663                APSR.Z = IsZeroBit(result);
8664                APSR.C = carry;
8665                APSR.V = overflow;
8666#endif
8667
8668    bool success = false;
8669
8670    uint32_t Rd; // the destination register
8671    uint32_t Rn; // the first operand
8672    uint32_t Rm; // the second operand
8673    bool setflags;
8674    ARM_ShifterType shift_t;
8675    uint32_t shift_n; // the shift applied to the value read from Rm
8676    switch (encoding) {
8677    case eEncodingT1:
8678        Rd = Bits32(opcode, 11, 8);
8679        Rn = Bits32(opcode, 19, 16);
8680        Rm = Bits32(opcode, 3, 0);
8681        setflags = BitIsSet(opcode, 20);
8682        shift_n = DecodeImmShiftThumb(opcode, shift_t);
8683        // if (BadReg(d) || BadReg(m)) then UNPREDICTABLE;
8684        if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8685            return false;
8686        break;
8687    case eEncodingA1:
8688        Rd = Bits32(opcode, 15, 12);
8689        Rn = Bits32(opcode, 19, 16);
8690        Rm = Bits32(opcode, 3, 0);
8691        setflags = BitIsSet(opcode, 20);
8692        shift_n = DecodeImmShiftARM(opcode, shift_t);
8693
8694        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8695        if (Rd == 15 && setflags)
8696            return EmulateSUBSPcLrEtc (opcode, encoding);
8697        break;
8698    default:
8699        return false;
8700    }
8701    // Read the register value from register Rn.
8702    uint32_t val1 = ReadCoreReg(Rn, &success);
8703    if (!success)
8704        return false;
8705
8706    // Read the register value from register Rm.
8707    uint32_t val2 = ReadCoreReg(Rm, &success);
8708    if (!success)
8709        return false;
8710
8711    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8712    if (!success)
8713        return false;
8714    AddWithCarryResult res = AddWithCarry(~val1, shifted, 1);
8715
8716    EmulateInstruction::Context context;
8717    context.type = EmulateInstruction::eContextImmediate;
8718    context.SetNoArgs();
8719    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8720        return false;
8721
8722    return true;
8723}
8724
8725// Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from
8726// an immediate value, and writes the result to the destination register. It can optionally update the condition
8727// flags based on the result.
8728bool
8729EmulateInstructionARM::EmulateRSCImm (const uint32_t opcode, const ARMEncoding encoding)
8730{
8731#if 0
8732    // ARM pseudo code...
8733    if ConditionPassed() then
8734        EncodingSpecificOperations();
8735        (result, carry, overflow) = AddWithCarry(NOT(R[n]), imm32, APSR.C);
8736        if d == 15 then
8737            ALUWritePC(result); // setflags is always FALSE here
8738        else
8739            R[d] = result;
8740            if setflags then
8741                APSR.N = result<31>;
8742                APSR.Z = IsZeroBit(result);
8743                APSR.C = carry;
8744                APSR.V = overflow;
8745#endif
8746
8747    bool success = false;
8748
8749    uint32_t Rd; // the destination register
8750    uint32_t Rn; // the first operand
8751    bool setflags;
8752    uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8753    switch (encoding) {
8754    case eEncodingA1:
8755        Rd = Bits32(opcode, 15, 12);
8756        Rn = Bits32(opcode, 19, 16);
8757        setflags = BitIsSet(opcode, 20);
8758        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8759
8760        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8761        if (Rd == 15 && setflags)
8762            return EmulateSUBSPcLrEtc  (opcode, encoding);
8763        break;
8764    default:
8765        return false;
8766    }
8767    // Read the register value from the operand register Rn.
8768    uint32_t reg_val = ReadCoreReg(Rn, &success);
8769    if (!success)
8770        return false;
8771
8772    AddWithCarryResult res = AddWithCarry(~reg_val, imm32, APSR_C);
8773
8774    EmulateInstruction::Context context;
8775    context.type = EmulateInstruction::eContextImmediate;
8776    context.SetNoArgs ();
8777
8778    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8779        return false;
8780
8781    return true;
8782}
8783
8784// Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an
8785// optionally-shifted register value, and writes the result to the destination register. It can optionally update the
8786// condition flags based on the result.
8787bool
8788EmulateInstructionARM::EmulateRSCReg (const uint32_t opcode, const ARMEncoding encoding)
8789{
8790#if 0
8791    // ARM pseudo code...
8792    if ConditionPassed() then
8793        EncodingSpecificOperations();
8794        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8795        (result, carry, overflow) = AddWithCarry(NOT(R[n]), shifted, APSR.C);
8796        if d == 15 then
8797            ALUWritePC(result); // setflags is always FALSE here
8798        else
8799            R[d] = result;
8800            if setflags then
8801                APSR.N = result<31>;
8802                APSR.Z = IsZeroBit(result);
8803                APSR.C = carry;
8804                APSR.V = overflow;
8805#endif
8806
8807    bool success = false;
8808
8809    uint32_t Rd; // the destination register
8810    uint32_t Rn; // the first operand
8811    uint32_t Rm; // the second operand
8812    bool setflags;
8813    ARM_ShifterType shift_t;
8814    uint32_t shift_n; // the shift applied to the value read from Rm
8815    switch (encoding) {
8816    case eEncodingA1:
8817        Rd = Bits32(opcode, 15, 12);
8818        Rn = Bits32(opcode, 19, 16);
8819        Rm = Bits32(opcode, 3, 0);
8820        setflags = BitIsSet(opcode, 20);
8821        shift_n = DecodeImmShiftARM(opcode, shift_t);
8822
8823        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8824        if (Rd == 15 && setflags)
8825            return EmulateSUBSPcLrEtc (opcode, encoding);
8826        break;
8827    default:
8828        return false;
8829    }
8830    // Read the register value from register Rn.
8831    uint32_t val1 = ReadCoreReg(Rn, &success);
8832    if (!success)
8833        return false;
8834
8835    // Read the register value from register Rm.
8836    uint32_t val2 = ReadCoreReg(Rm, &success);
8837    if (!success)
8838        return false;
8839
8840    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8841    if (!success)
8842        return false;
8843    AddWithCarryResult res = AddWithCarry(~val1, shifted, APSR_C);
8844
8845    EmulateInstruction::Context context;
8846    context.type = EmulateInstruction::eContextImmediate;
8847    context.SetNoArgs();
8848    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8849        return false;
8850
8851    return true;
8852}
8853
8854// Subtract with Carry (immediate) subtracts an immediate value and the value of
8855// NOT (Carry flag) from a register value, and writes the result to the destination register.
8856// It can optionally update the condition flags based on the result.
8857bool
8858EmulateInstructionARM::EmulateSBCImm (const uint32_t opcode, const ARMEncoding encoding)
8859{
8860#if 0
8861    // ARM pseudo code...
8862    if ConditionPassed() then
8863        EncodingSpecificOperations();
8864        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), APSR.C);
8865        if d == 15 then         // Can only occur for ARM encoding
8866            ALUWritePC(result); // setflags is always FALSE here
8867        else
8868            R[d] = result;
8869            if setflags then
8870                APSR.N = result<31>;
8871                APSR.Z = IsZeroBit(result);
8872                APSR.C = carry;
8873                APSR.V = overflow;
8874#endif
8875
8876    bool success = false;
8877
8878    uint32_t Rd; // the destination register
8879    uint32_t Rn; // the first operand
8880    bool setflags;
8881    uint32_t imm32; // the immediate value to be added to the value obtained from Rn
8882    switch (encoding) {
8883    case eEncodingT1:
8884        Rd = Bits32(opcode, 11, 8);
8885        Rn = Bits32(opcode, 19, 16);
8886        setflags = BitIsSet(opcode, 20);
8887        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
8888        if (BadReg(Rd) || BadReg(Rn))
8889            return false;
8890        break;
8891    case eEncodingA1:
8892        Rd = Bits32(opcode, 15, 12);
8893        Rn = Bits32(opcode, 19, 16);
8894        setflags = BitIsSet(opcode, 20);
8895        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
8896
8897        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8898        if (Rd == 15 && setflags)
8899            return EmulateSUBSPcLrEtc (opcode, encoding);
8900        break;
8901    default:
8902        return false;
8903    }
8904    // Read the register value from the operand register Rn.
8905    uint32_t reg_val = ReadCoreReg(Rn, &success);
8906    if (!success)
8907        return false;
8908
8909    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, APSR_C);
8910
8911    EmulateInstruction::Context context;
8912    context.type = EmulateInstruction::eContextImmediate;
8913    context.SetNoArgs ();
8914
8915    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
8916        return false;
8917
8918    return true;
8919}
8920
8921// Subtract with Carry (register) subtracts an optionally-shifted register value and the value of
8922// NOT (Carry flag) from a register value, and writes the result to the destination register.
8923// It can optionally update the condition flags based on the result.
8924bool
8925EmulateInstructionARM::EmulateSBCReg (const uint32_t opcode, const ARMEncoding encoding)
8926{
8927#if 0
8928    // ARM pseudo code...
8929    if ConditionPassed() then
8930        EncodingSpecificOperations();
8931        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
8932        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), APSR.C);
8933        if d == 15 then         // Can only occur for ARM encoding
8934            ALUWritePC(result); // setflags is always FALSE here
8935        else
8936            R[d] = result;
8937            if setflags then
8938                APSR.N = result<31>;
8939                APSR.Z = IsZeroBit(result);
8940                APSR.C = carry;
8941                APSR.V = overflow;
8942#endif
8943
8944    bool success = false;
8945
8946    uint32_t Rd; // the destination register
8947    uint32_t Rn; // the first operand
8948    uint32_t Rm; // the second operand
8949    bool setflags;
8950    ARM_ShifterType shift_t;
8951    uint32_t shift_n; // the shift applied to the value read from Rm
8952    switch (encoding) {
8953    case eEncodingT1:
8954        Rd = Rn = Bits32(opcode, 2, 0);
8955        Rm = Bits32(opcode, 5, 3);
8956        setflags = !InITBlock();
8957        shift_t = SRType_LSL;
8958        shift_n = 0;
8959        break;
8960    case eEncodingT2:
8961        Rd = Bits32(opcode, 11, 8);
8962        Rn = Bits32(opcode, 19, 16);
8963        Rm = Bits32(opcode, 3, 0);
8964        setflags = BitIsSet(opcode, 20);
8965        shift_n = DecodeImmShiftThumb(opcode, shift_t);
8966        if (BadReg(Rd) || BadReg(Rn) || BadReg(Rm))
8967            return false;
8968        break;
8969    case eEncodingA1:
8970        Rd = Bits32(opcode, 15, 12);
8971        Rn = Bits32(opcode, 19, 16);
8972        Rm = Bits32(opcode, 3, 0);
8973        setflags = BitIsSet(opcode, 20);
8974        shift_n = DecodeImmShiftARM(opcode, shift_t);
8975
8976        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
8977        if (Rd == 15 && setflags)
8978            return EmulateSUBSPcLrEtc (opcode, encoding);
8979        break;
8980    default:
8981        return false;
8982    }
8983    // Read the register value from register Rn.
8984    uint32_t val1 = ReadCoreReg(Rn, &success);
8985    if (!success)
8986        return false;
8987
8988    // Read the register value from register Rm.
8989    uint32_t val2 = ReadCoreReg(Rm, &success);
8990    if (!success)
8991        return false;
8992
8993    uint32_t shifted = Shift(val2, shift_t, shift_n, APSR_C, &success);
8994    if (!success)
8995        return false;
8996    AddWithCarryResult res = AddWithCarry(val1, ~shifted, APSR_C);
8997
8998    EmulateInstruction::Context context;
8999    context.type = EmulateInstruction::eContextImmediate;
9000    context.SetNoArgs();
9001    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9002        return false;
9003
9004    return true;
9005}
9006
9007// This instruction subtracts an immediate value from a register value, and writes the result
9008// to the destination register.  It can optionally update the condition flags based on the result.
9009bool
9010EmulateInstructionARM::EmulateSUBImmThumb (const uint32_t opcode, const ARMEncoding encoding)
9011{
9012#if 0
9013    // ARM pseudo code...
9014    if ConditionPassed() then
9015        EncodingSpecificOperations();
9016        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9017        R[d] = result;
9018        if setflags then
9019            APSR.N = result<31>;
9020            APSR.Z = IsZeroBit(result);
9021            APSR.C = carry;
9022            APSR.V = overflow;
9023#endif
9024
9025    bool success = false;
9026
9027    uint32_t Rd; // the destination register
9028    uint32_t Rn; // the first operand
9029    bool setflags;
9030    uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9031    switch (encoding) {
9032    case eEncodingT1:
9033        Rd = Bits32(opcode, 2, 0);
9034        Rn = Bits32(opcode, 5, 3);
9035        setflags = !InITBlock();
9036        imm32 = Bits32(opcode, 8, 6); // imm32 = ZeroExtend(imm3, 32)
9037        break;
9038    case eEncodingT2:
9039        Rd = Rn = Bits32(opcode, 10, 8);
9040        setflags = !InITBlock();
9041        imm32 = Bits32(opcode, 7, 0); // imm32 = ZeroExtend(imm8, 32)
9042        break;
9043    case eEncodingT3:
9044        Rd = Bits32(opcode, 11, 8);
9045        Rn = Bits32(opcode, 19, 16);
9046        setflags = BitIsSet(opcode, 20);
9047        imm32 = ThumbExpandImm(opcode); // imm32 = ThumbExpandImm(i:imm3:imm8)
9048
9049        // if Rd == '1111' && S == '1' then SEE CMP (immediate);
9050        if (Rd == 15 && setflags)
9051            return EmulateCMPImm (opcode, eEncodingT2);
9052
9053        // if Rn == '1101' then SEE SUB (SP minus immediate);
9054        if (Rn == 13)
9055            return EmulateSUBSPImm (opcode, eEncodingT2);
9056
9057        // if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE;
9058        if (Rd == 13 || (Rd == 15 && !setflags) || Rn == 15)
9059            return false;
9060        break;
9061    case eEncodingT4:
9062        Rd = Bits32(opcode, 11, 8);
9063        Rn = Bits32(opcode, 19, 16);
9064        setflags = BitIsSet(opcode, 20);
9065        imm32 = ThumbImm12(opcode); // imm32 = ZeroExtend(i:imm3:imm8, 32)
9066
9067        // if Rn == '1111' then SEE ADR;
9068        if (Rn == 15)
9069            return EmulateADR (opcode, eEncodingT2);
9070
9071        // if Rn == '1101' then SEE SUB (SP minus immediate);
9072        if (Rn == 13)
9073            return EmulateSUBSPImm (opcode, eEncodingT3);
9074
9075        if (BadReg(Rd))
9076            return false;
9077        break;
9078    default:
9079        return false;
9080    }
9081    // Read the register value from the operand register Rn.
9082    uint32_t reg_val = ReadCoreReg(Rn, &success);
9083    if (!success)
9084        return false;
9085
9086    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9087
9088    EmulateInstruction::Context context;
9089    context.type = EmulateInstruction::eContextImmediate;
9090    context.SetNoArgs ();
9091
9092    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9093        return false;
9094
9095    return true;
9096}
9097
9098// This instruction subtracts an immediate value from a register value, and writes the result
9099// to the destination register.  It can optionally update the condition flags based on the result.
9100bool
9101EmulateInstructionARM::EmulateSUBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9102{
9103#if 0
9104    // ARM pseudo code...
9105    if ConditionPassed() then
9106        EncodingSpecificOperations();
9107        (result, carry, overflow) = AddWithCarry(R[n], NOT(imm32), '1');
9108        if d == 15 then
9109            ALUWritePC(result); // setflags is always FALSE here
9110        else
9111            R[d] = result;
9112            if setflags then
9113                APSR.N = result<31>;
9114                APSR.Z = IsZeroBit(result);
9115                APSR.C = carry;
9116                APSR.V = overflow;
9117#endif
9118
9119    bool success = false;
9120
9121    uint32_t Rd; // the destination register
9122    uint32_t Rn; // the first operand
9123    bool setflags;
9124    uint32_t imm32; // the immediate value to be subtracted from the value obtained from Rn
9125    switch (encoding) {
9126    case eEncodingA1:
9127        Rd = Bits32(opcode, 15, 12);
9128        Rn = Bits32(opcode, 19, 16);
9129        setflags = BitIsSet(opcode, 20);
9130        imm32 = ARMExpandImm(opcode); // imm32 = ARMExpandImm(imm12)
9131
9132        // if Rn == '1111' && S == '0' then SEE ADR;
9133        if (Rn == 15 && !setflags)
9134            return EmulateADR (opcode, eEncodingA2);
9135
9136        // if Rn == '1101' then SEE SUB (SP minus immediate);
9137        if (Rn == 13)
9138            return EmulateSUBSPImm (opcode, eEncodingA1);
9139
9140        // if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions;
9141        if (Rd == 15 && setflags)
9142            return EmulateSUBSPcLrEtc (opcode, encoding);
9143        break;
9144    default:
9145        return false;
9146    }
9147    // Read the register value from the operand register Rn.
9148    uint32_t reg_val = ReadCoreReg(Rn, &success);
9149    if (!success)
9150        return false;
9151
9152    AddWithCarryResult res = AddWithCarry(reg_val, ~imm32, 1);
9153
9154    EmulateInstruction::Context context;
9155    context.type = EmulateInstruction::eContextImmediate;
9156    context.SetNoArgs ();
9157
9158    if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, res.carry_out, res.overflow))
9159        return false;
9160
9161    return true;
9162}
9163
9164// Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an
9165// immediate value.  It updates the condition flags based on the result, and discards the result.
9166bool
9167EmulateInstructionARM::EmulateTEQImm (const uint32_t opcode, const ARMEncoding encoding)
9168{
9169#if 0
9170    // ARM pseudo code...
9171    if ConditionPassed() then
9172        EncodingSpecificOperations();
9173        result = R[n] EOR imm32;
9174        APSR.N = result<31>;
9175        APSR.Z = IsZeroBit(result);
9176        APSR.C = carry;
9177        // APSR.V unchanged
9178#endif
9179
9180    bool success = false;
9181
9182    if (ConditionPassed(opcode))
9183    {
9184        uint32_t Rn;
9185        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9186        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9187        switch (encoding)
9188        {
9189        case eEncodingT1:
9190            Rn = Bits32(opcode, 19, 16);
9191            imm32 = ThumbExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9192            if (BadReg(Rn))
9193                return false;
9194            break;
9195        case eEncodingA1:
9196            Rn = Bits32(opcode, 19, 16);
9197            imm32 = ARMExpandImm_C (opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9198            break;
9199        default:
9200            return false;
9201        }
9202
9203        // Read the first operand.
9204        uint32_t val1 = ReadCoreReg(Rn, &success);
9205        if (!success)
9206            return false;
9207
9208        uint32_t result = val1 ^ imm32;
9209
9210        EmulateInstruction::Context context;
9211        context.type = EmulateInstruction::eContextImmediate;
9212        context.SetNoArgs ();
9213
9214        if (!WriteFlags(context, result, carry))
9215            return false;
9216    }
9217    return true;
9218}
9219
9220// Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an
9221// optionally-shifted register value.  It updates the condition flags based on the result, and discards
9222// the result.
9223bool
9224EmulateInstructionARM::EmulateTEQReg (const uint32_t opcode, const ARMEncoding encoding)
9225{
9226#if 0
9227    // ARM pseudo code...
9228    if ConditionPassed() then
9229        EncodingSpecificOperations();
9230        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9231        result = R[n] EOR shifted;
9232        APSR.N = result<31>;
9233        APSR.Z = IsZeroBit(result);
9234        APSR.C = carry;
9235        // APSR.V unchanged
9236#endif
9237
9238    bool success = false;
9239
9240    if (ConditionPassed(opcode))
9241    {
9242        uint32_t Rn, Rm;
9243        ARM_ShifterType shift_t;
9244        uint32_t shift_n; // the shift applied to the value read from Rm
9245        uint32_t carry;
9246        switch (encoding)
9247        {
9248        case eEncodingT1:
9249            Rn = Bits32(opcode, 19, 16);
9250            Rm = Bits32(opcode, 3, 0);
9251            shift_n = DecodeImmShiftThumb(opcode, shift_t);
9252            if (BadReg(Rn) || BadReg(Rm))
9253                return false;
9254            break;
9255        case eEncodingA1:
9256            Rn = Bits32(opcode, 19, 16);
9257            Rm = Bits32(opcode, 3, 0);
9258            shift_n = DecodeImmShiftARM(opcode, shift_t);
9259            break;
9260        default:
9261            return false;
9262        }
9263
9264        // Read the first operand.
9265        uint32_t val1 = ReadCoreReg(Rn, &success);
9266        if (!success)
9267            return false;
9268
9269        // Read the second operand.
9270        uint32_t val2 = ReadCoreReg(Rm, &success);
9271        if (!success)
9272            return false;
9273
9274        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9275        if (!success)
9276            return false;
9277        uint32_t result = val1 ^ shifted;
9278
9279        EmulateInstruction::Context context;
9280        context.type = EmulateInstruction::eContextImmediate;
9281        context.SetNoArgs ();
9282
9283        if (!WriteFlags(context, result, carry))
9284            return false;
9285    }
9286    return true;
9287}
9288
9289// Test (immediate) performs a bitwise AND operation on a register value and an immediate value.
9290// It updates the condition flags based on the result, and discards the result.
9291bool
9292EmulateInstructionARM::EmulateTSTImm (const uint32_t opcode, const ARMEncoding encoding)
9293{
9294#if 0
9295    // ARM pseudo code...
9296    if ConditionPassed() then
9297        EncodingSpecificOperations();
9298        result = R[n] AND imm32;
9299        APSR.N = result<31>;
9300        APSR.Z = IsZeroBit(result);
9301        APSR.C = carry;
9302        // APSR.V unchanged
9303#endif
9304
9305    bool success = false;
9306
9307    if (ConditionPassed(opcode))
9308    {
9309        uint32_t Rn;
9310        uint32_t imm32; // the immediate value to be ANDed to the value obtained from Rn
9311        uint32_t carry; // the carry bit after ARM/Thumb Expand operation
9312        switch (encoding)
9313        {
9314        case eEncodingT1:
9315            Rn = Bits32(opcode, 19, 16);
9316            imm32 = ThumbExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ThumbExpandImm(i:imm3:imm8, APSR.C)
9317            if (BadReg(Rn))
9318                return false;
9319            break;
9320        case eEncodingA1:
9321            Rn = Bits32(opcode, 19, 16);
9322            imm32 = ARMExpandImm_C(opcode, APSR_C, carry); // (imm32, carry) = ARMExpandImm(imm12, APSR.C)
9323            break;
9324        default:
9325            return false;
9326        }
9327
9328        // Read the first operand.
9329        uint32_t val1 = ReadCoreReg(Rn, &success);
9330        if (!success)
9331            return false;
9332
9333        uint32_t result = val1 & imm32;
9334
9335        EmulateInstruction::Context context;
9336        context.type = EmulateInstruction::eContextImmediate;
9337        context.SetNoArgs ();
9338
9339        if (!WriteFlags(context, result, carry))
9340            return false;
9341    }
9342    return true;
9343}
9344
9345// Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value.
9346// It updates the condition flags based on the result, and discards the result.
9347bool
9348EmulateInstructionARM::EmulateTSTReg (const uint32_t opcode, const ARMEncoding encoding)
9349{
9350#if 0
9351    // ARM pseudo code...
9352    if ConditionPassed() then
9353        EncodingSpecificOperations();
9354        (shifted, carry) = Shift_C(R[m], shift_t, shift_n, APSR.C);
9355        result = R[n] AND shifted;
9356        APSR.N = result<31>;
9357        APSR.Z = IsZeroBit(result);
9358        APSR.C = carry;
9359        // APSR.V unchanged
9360#endif
9361
9362    bool success = false;
9363
9364    if (ConditionPassed(opcode))
9365    {
9366        uint32_t Rn, Rm;
9367        ARM_ShifterType shift_t;
9368        uint32_t shift_n; // the shift applied to the value read from Rm
9369        uint32_t carry;
9370        switch (encoding)
9371        {
9372        case eEncodingT1:
9373            Rn = Bits32(opcode, 2, 0);
9374            Rm = Bits32(opcode, 5, 3);
9375            shift_t = SRType_LSL;
9376            shift_n = 0;
9377            break;
9378        case eEncodingT2:
9379            Rn = Bits32(opcode, 19, 16);
9380            Rm = Bits32(opcode, 3, 0);
9381            shift_n = DecodeImmShiftThumb(opcode, shift_t);
9382            if (BadReg(Rn) || BadReg(Rm))
9383                return false;
9384            break;
9385        case eEncodingA1:
9386            Rn = Bits32(opcode, 19, 16);
9387            Rm = Bits32(opcode, 3, 0);
9388            shift_n = DecodeImmShiftARM(opcode, shift_t);
9389            break;
9390        default:
9391            return false;
9392        }
9393
9394        // Read the first operand.
9395        uint32_t val1 = ReadCoreReg(Rn, &success);
9396        if (!success)
9397            return false;
9398
9399        // Read the second operand.
9400        uint32_t val2 = ReadCoreReg(Rm, &success);
9401        if (!success)
9402            return false;
9403
9404        uint32_t shifted = Shift_C(val2, shift_t, shift_n, APSR_C, carry, &success);
9405        if (!success)
9406            return false;
9407        uint32_t result = val1 & shifted;
9408
9409        EmulateInstruction::Context context;
9410        context.type = EmulateInstruction::eContextImmediate;
9411        context.SetNoArgs ();
9412
9413        if (!WriteFlags(context, result, carry))
9414            return false;
9415    }
9416    return true;
9417}
9418
9419// A8.6.216 SUB (SP minus register)
9420bool
9421EmulateInstructionARM::EmulateSUBSPReg (const uint32_t opcode, const ARMEncoding encoding)
9422{
9423#if 0
9424    if ConditionPassed() then
9425        EncodingSpecificOperations();
9426        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9427        (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9428        if d == 15 then // Can only occur for ARM encoding
9429            ALUWritePC(result); // setflags is always FALSE here
9430        else
9431            R[d] = result;
9432            if setflags then
9433                APSR.N = result<31>;
9434                APSR.Z = IsZeroBit(result);
9435                APSR.C = carry;
9436                APSR.V = overflow;
9437#endif
9438
9439    bool success = false;
9440
9441    if (ConditionPassed(opcode))
9442    {
9443        uint32_t d;
9444        uint32_t m;
9445        bool setflags;
9446        ARM_ShifterType shift_t;
9447        uint32_t shift_n;
9448
9449        switch (encoding)
9450        {
9451            case eEncodingT1:
9452                // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9453                d = Bits32 (opcode, 11, 8);
9454                m = Bits32 (opcode, 3, 0);
9455                setflags = BitIsSet (opcode, 20);
9456
9457                // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9458                shift_n = DecodeImmShiftThumb (opcode, shift_t);
9459
9460                // if d == 13 && (shift_t != SRType_LSL || shift_n > 3) then UNPREDICTABLE;
9461                if ((d == 13) && ((shift_t != SRType_LSL) || (shift_n > 3)))
9462                    return false;
9463
9464                // if d == 15 || BadReg(m) then UNPREDICTABLE;
9465                if ((d == 15) || BadReg (m))
9466                    return false;
9467                break;
9468
9469            case eEncodingA1:
9470                // d = UInt(Rd); m = UInt(Rm); setflags = (S == �1�);
9471                d = Bits32 (opcode, 15, 12);
9472                m = Bits32 (opcode, 3, 0);
9473                setflags = BitIsSet (opcode, 20);
9474
9475                // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9476                if (d == 15 && setflags)
9477                    EmulateSUBSPcLrEtc (opcode, encoding);
9478
9479                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9480                shift_n = DecodeImmShiftARM (opcode, shift_t);
9481                break;
9482
9483            default:
9484                return false;
9485        }
9486
9487        // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9488        uint32_t Rm = ReadCoreReg (m, &success);
9489        if (!success)
9490            return false;
9491
9492        uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9493        if (!success)
9494            return false;
9495
9496        // (result, carry, overflow) = AddWithCarry(SP, NOT(shifted), �1�);
9497        uint32_t sp_val = ReadCoreReg (SP_REG, &success);
9498        if (!success)
9499            return false;
9500
9501        AddWithCarryResult res = AddWithCarry (sp_val, ~shifted, 1);
9502
9503        EmulateInstruction::Context context;
9504        context.type = eContextArithmetic;
9505        RegisterInfo sp_reg;
9506        GetRegisterInfo (eRegisterKindDWARF, dwarf_sp, sp_reg);
9507        RegisterInfo dwarf_reg;
9508        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, dwarf_reg);
9509        context.SetRegisterRegisterOperands (sp_reg, dwarf_reg);
9510
9511        if (!WriteCoreRegOptionalFlags(context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9512            return false;
9513    }
9514    return true;
9515}
9516
9517
9518// A8.6.7 ADD (register-shifted register)
9519bool
9520EmulateInstructionARM::EmulateADDRegShift (const uint32_t opcode, const ARMEncoding encoding)
9521{
9522#if 0
9523    if ConditionPassed() then
9524        EncodingSpecificOperations();
9525        shift_n = UInt(R[s]<7:0>);
9526        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9527        (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9528        R[d] = result;
9529        if setflags then
9530            APSR.N = result<31>;
9531            APSR.Z = IsZeroBit(result);
9532            APSR.C = carry;
9533            APSR.V = overflow;
9534#endif
9535
9536    bool success = false;
9537
9538    if (ConditionPassed(opcode))
9539    {
9540        uint32_t d;
9541        uint32_t n;
9542        uint32_t m;
9543        uint32_t s;
9544        bool setflags;
9545        ARM_ShifterType shift_t;
9546
9547        switch (encoding)
9548        {
9549            case eEncodingA1:
9550                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); s = UInt(Rs);
9551                d = Bits32 (opcode, 15, 12);
9552                n = Bits32 (opcode, 19, 16);
9553                m = Bits32 (opcode, 3, 0);
9554                s = Bits32 (opcode, 11, 8);
9555
9556                // setflags = (S == �1�); shift_t = DecodeRegShift(type);
9557                setflags = BitIsSet (opcode, 20);
9558                shift_t = DecodeRegShift (Bits32 (opcode, 6, 5));
9559
9560                // if d == 15 || n == 15 || m == 15 || s == 15 then UNPREDICTABLE;
9561                if ((d == 15) || (m == 15) || (m == 15) || (s == 15))
9562                    return false;
9563                break;
9564
9565            default:
9566                return false;
9567        }
9568
9569        // shift_n = UInt(R[s]<7:0>);
9570        uint32_t Rs = ReadCoreReg (s, &success);
9571        if (!success)
9572            return false;
9573
9574        uint32_t shift_n = Bits32 (Rs, 7, 0);
9575
9576        // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9577        uint32_t Rm = ReadCoreReg (m, &success);
9578        if (!success)
9579            return false;
9580
9581        uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9582        if (!success)
9583            return false;
9584
9585        // (result, carry, overflow) = AddWithCarry(R[n], shifted, �0�);
9586        uint32_t Rn = ReadCoreReg (n, &success);
9587        if (!success)
9588            return false;
9589
9590        AddWithCarryResult res = AddWithCarry (Rn, shifted, 0);
9591
9592        // R[d] = result;
9593        EmulateInstruction::Context context;
9594        context.type = eContextArithmetic;
9595        RegisterInfo reg_n;
9596        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9597        RegisterInfo reg_m;
9598        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9599
9600        context.SetRegisterRegisterOperands (reg_n, reg_m);
9601
9602        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, res.result))
9603            return false;
9604
9605        // if setflags then
9606            // APSR.N = result<31>;
9607            // APSR.Z = IsZeroBit(result);
9608            // APSR.C = carry;
9609            // APSR.V = overflow;
9610        if (setflags)
9611            return WriteFlags (context, res.result, res.carry_out, res.overflow);
9612    }
9613    return true;
9614}
9615
9616// A8.6.213 SUB (register)
9617bool
9618EmulateInstructionARM::EmulateSUBReg (const uint32_t opcode, const ARMEncoding encoding)
9619{
9620#if 0
9621    if ConditionPassed() then
9622        EncodingSpecificOperations();
9623        shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9624        (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9625        if d == 15 then // Can only occur for ARM encoding
9626            ALUWritePC(result); // setflags is always FALSE here
9627        else
9628            R[d] = result;
9629            if setflags then
9630                APSR.N = result<31>;
9631                APSR.Z = IsZeroBit(result);
9632                APSR.C = carry;
9633                APSR.V = overflow;
9634#endif
9635
9636    bool success = false;
9637
9638    if (ConditionPassed(opcode))
9639    {
9640        uint32_t d;
9641        uint32_t n;
9642        uint32_t m;
9643        bool setflags;
9644        ARM_ShifterType shift_t;
9645        uint32_t shift_n;
9646
9647        switch (encoding)
9648        {
9649            case eEncodingT1:
9650                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = !InITBlock();
9651                d = Bits32 (opcode, 2, 0);
9652                n = Bits32 (opcode, 5, 3);
9653                m = Bits32 (opcode, 8, 6);
9654                setflags = !InITBlock();
9655
9656                // (shift_t, shift_n) = (SRType_LSL, 0);
9657                shift_t = SRType_LSL;
9658                shift_n = 0;
9659
9660                break;
9661
9662            case eEncodingT2:
9663                // if Rd == �1111� && S == �1� then SEE CMP (register);
9664                // if Rn == �1101� then SEE SUB (SP minus register);
9665                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9666                d = Bits32 (opcode, 11, 8);
9667                n = Bits32 (opcode, 19, 16);
9668                m = Bits32 (opcode, 3, 0);
9669                setflags = BitIsSet (opcode, 20);
9670
9671                // (shift_t, shift_n) = DecodeImmShift(type, imm3:imm2);
9672                shift_n = DecodeImmShiftThumb (opcode, shift_t);
9673
9674                // if d == 13 || (d == 15 && S == '0') || n == 15 || BadReg(m) then UNPREDICTABLE;
9675                if ((d == 13) || ((d == 15) && BitIsClear (opcode, 20)) || (n == 15) || BadReg (m))
9676                    return false;
9677
9678                break;
9679
9680            case eEncodingA1:
9681                // if Rn == �1101� then SEE SUB (SP minus register);
9682                // d = UInt(Rd); n = UInt(Rn); m = UInt(Rm); setflags = (S == �1�);
9683                d = Bits32 (opcode, 15, 12);
9684                n = Bits32 (opcode, 19, 16);
9685                m = Bits32 (opcode, 3, 0);
9686                setflags = BitIsSet (opcode, 20);
9687
9688                // if Rd == �1111� && S == �1� then SEE SUBS PC, LR and related instructions;
9689                if ((d == 15) && setflags)
9690                    EmulateSUBSPcLrEtc (opcode, encoding);
9691
9692                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
9693                shift_n = DecodeImmShiftARM (opcode, shift_t);
9694
9695                break;
9696
9697            default:
9698                return false;
9699        }
9700
9701        // shifted = Shift(R[m], shift_t, shift_n, APSR.C);
9702        uint32_t Rm = ReadCoreReg (m, &success);
9703        if (!success)
9704            return false;
9705
9706        uint32_t shifted = Shift (Rm, shift_t, shift_n, APSR_C, &success);
9707        if (!success)
9708            return false;
9709
9710        // (result, carry, overflow) = AddWithCarry(R[n], NOT(shifted), �1�);
9711        uint32_t Rn = ReadCoreReg (n, &success);
9712        if (!success)
9713            return false;
9714
9715        AddWithCarryResult res = AddWithCarry (Rn, ~shifted, 1);
9716
9717        // if d == 15 then // Can only occur for ARM encoding
9718            // ALUWritePC(result); // setflags is always FALSE here
9719        // else
9720            // R[d] = result;
9721            // if setflags then
9722                // APSR.N = result<31>;
9723                // APSR.Z = IsZeroBit(result);
9724                // APSR.C = carry;
9725                // APSR.V = overflow;
9726
9727        EmulateInstruction::Context context;
9728        context.type = eContextArithmetic;
9729        RegisterInfo reg_n;
9730        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, reg_n);
9731        RegisterInfo reg_m;
9732        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, reg_m);
9733        context.SetRegisterRegisterOperands (reg_n, reg_m);
9734
9735        if (!WriteCoreRegOptionalFlags (context, res.result, dwarf_r0 + d, setflags, res.carry_out, res.overflow))
9736            return false;
9737    }
9738    return true;
9739}
9740
9741// A8.6.202 STREX
9742// Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a
9743// word from a register to memory if the executing processor has exclusive access to the memory addressed.
9744bool
9745EmulateInstructionARM::EmulateSTREX (const uint32_t opcode, const ARMEncoding encoding)
9746{
9747#if 0
9748    if ConditionPassed() then
9749        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
9750        address = R[n] + imm32;
9751        if ExclusiveMonitorsPass(address,4) then
9752            MemA[address,4] = R[t];
9753            R[d] = 0;
9754        else
9755            R[d] = 1;
9756#endif
9757
9758    bool success = false;
9759
9760    if (ConditionPassed(opcode))
9761    {
9762        uint32_t d;
9763        uint32_t t;
9764        uint32_t n;
9765        uint32_t imm32;
9766        const uint32_t addr_byte_size = GetAddressByteSize();
9767
9768        switch (encoding)
9769        {
9770            case eEncodingT1:
9771                // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
9772                d = Bits32 (opcode, 11, 8);
9773                t = Bits32 (opcode, 15, 12);
9774                n = Bits32 (opcode, 19, 16);
9775                imm32 = Bits32 (opcode, 7, 0) << 2;
9776
9777                // if BadReg(d) || BadReg(t) || n == 15 then UNPREDICTABLE;
9778                if (BadReg (d) || BadReg (t) || (n == 15))
9779                  return false;
9780
9781                // if d == n || d == t then UNPREDICTABLE;
9782                if ((d == n) || (d == t))
9783                  return false;
9784
9785                break;
9786
9787            case eEncodingA1:
9788                // d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); imm32 = Zeros(32); // Zero offset
9789                d = Bits32 (opcode, 15, 12);
9790                t = Bits32 (opcode, 3, 0);
9791                n = Bits32 (opcode, 19, 16);
9792                imm32 = 0;
9793
9794                // if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
9795                if ((d == 15) || (t == 15) || (n == 15))
9796                    return false;
9797
9798                // if d == n || d == t then UNPREDICTABLE;
9799                if ((d == n) || (d == t))
9800                    return false;
9801
9802                break;
9803
9804            default:
9805                return false;
9806        }
9807
9808        // address = R[n] + imm32;
9809        uint32_t Rn = ReadCoreReg (n, &success);
9810        if (!success)
9811            return false;
9812
9813        addr_t address = Rn + imm32;
9814
9815        RegisterInfo base_reg;
9816        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9817        RegisterInfo data_reg;
9818        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9819        EmulateInstruction::Context context;
9820        context.type = eContextRegisterStore;
9821        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, imm32);
9822
9823        // if ExclusiveMonitorsPass(address,4) then
9824        // if (ExclusiveMonitorsPass (address, addr_byte_size)) -- For now, for the sake of emulation, we will say this
9825        //                                                         always return true.
9826        if (true)
9827        {
9828            // MemA[address,4] = R[t];
9829            uint32_t Rt = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_r0 + t, 0, &success);
9830            if (!success)
9831                return false;
9832
9833            if (!MemAWrite (context, address, Rt, addr_byte_size))
9834                return false;
9835
9836            // R[d] = 0;
9837            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 0))
9838                return false;
9839        }
9840        else
9841        {
9842            // R[d] = 1;
9843            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, 1))
9844                return false;
9845        }
9846    }
9847    return true;
9848}
9849
9850// A8.6.197 STRB (immediate, ARM)
9851bool
9852EmulateInstructionARM::EmulateSTRBImmARM (const uint32_t opcode, const ARMEncoding encoding)
9853{
9854#if 0
9855    if ConditionPassed() then
9856        EncodingSpecificOperations();
9857        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9858        address = if index then offset_addr else R[n];
9859        MemU[address,1] = R[t]<7:0>;
9860        if wback then R[n] = offset_addr;
9861#endif
9862
9863    bool success = false;
9864
9865    if (ConditionPassed(opcode))
9866    {
9867        uint32_t t;
9868        uint32_t n;
9869        uint32_t imm32;
9870        bool index;
9871        bool add;
9872        bool wback;
9873
9874        switch (encoding)
9875        {
9876            case eEncodingA1:
9877                // if P == �0� && W == �1� then SEE STRBT;
9878                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9879                t = Bits32 (opcode, 15, 12);
9880                n = Bits32 (opcode, 19, 16);
9881                imm32 = Bits32 (opcode, 11, 0);
9882
9883                // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9884                index = BitIsSet (opcode, 24);
9885                add = BitIsSet (opcode, 23);
9886                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9887
9888                // if t == 15 then UNPREDICTABLE;
9889                if (t == 15)
9890                    return false;
9891
9892                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9893                if (wback && ((n == 15) || (n == t)))
9894                    return false;
9895
9896                break;
9897
9898            default:
9899                return false;
9900        }
9901
9902        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9903        uint32_t Rn = ReadCoreReg (n, &success);
9904        if (!success)
9905            return false;
9906
9907        addr_t offset_addr;
9908        if (add)
9909            offset_addr = Rn + imm32;
9910        else
9911            offset_addr = Rn - imm32;
9912
9913        // address = if index then offset_addr else R[n];
9914        addr_t address;
9915        if (index)
9916            address = offset_addr;
9917        else
9918            address = Rn;
9919
9920        // MemU[address,1] = R[t]<7:0>;
9921        uint32_t Rt = ReadCoreReg (t, &success);
9922        if (!success)
9923            return false;
9924
9925        RegisterInfo base_reg;
9926        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
9927        RegisterInfo data_reg;
9928        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
9929        EmulateInstruction::Context context;
9930        context.type = eContextRegisterStore;
9931        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
9932
9933        if (!MemUWrite (context, address, Bits32 (Rt, 7, 0), 1))
9934            return false;
9935
9936        // if wback then R[n] = offset_addr;
9937        if (wback)
9938        {
9939            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
9940                return false;
9941        }
9942    }
9943    return true;
9944}
9945
9946// A8.6.194 STR (immediate, ARM)
9947bool
9948EmulateInstructionARM::EmulateSTRImmARM (const uint32_t opcode, const ARMEncoding encoding)
9949{
9950#if 0
9951    if ConditionPassed() then
9952        EncodingSpecificOperations();
9953        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9954        address = if index then offset_addr else R[n];
9955        MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
9956        if wback then R[n] = offset_addr;
9957#endif
9958
9959    bool success = false;
9960
9961    if (ConditionPassed(opcode))
9962    {
9963        uint32_t t;
9964        uint32_t n;
9965        uint32_t imm32;
9966        bool index;
9967        bool add;
9968        bool wback;
9969
9970        const uint32_t addr_byte_size = GetAddressByteSize();
9971
9972        switch (encoding)
9973        {
9974            case eEncodingA1:
9975                // if P == �0� && W == �1� then SEE STRT;
9976                // if Rn == �1101� && P == �1� && U == �0� && W == �1� && imm12 == �000000000100� then SEE PUSH;
9977                // t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32);
9978                t = Bits32 (opcode, 15, 12);
9979                n = Bits32 (opcode, 19, 16);
9980                imm32 = Bits32 (opcode, 11, 0);
9981
9982                // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
9983                index = BitIsSet (opcode, 24);
9984                add = BitIsSet (opcode, 23);
9985                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
9986
9987                // if wback && (n == 15 || n == t) then UNPREDICTABLE;
9988                if (wback && ((n == 15) || (n == t)))
9989                    return false;
9990
9991                break;
9992
9993            default:
9994                return false;
9995        }
9996
9997        // offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
9998        uint32_t Rn = ReadCoreReg (n, &success);
9999        if (!success)
10000            return false;
10001
10002        addr_t offset_addr;
10003        if (add)
10004            offset_addr = Rn + imm32;
10005        else
10006            offset_addr = Rn - imm32;
10007
10008        // address = if index then offset_addr else R[n];
10009        addr_t address;
10010        if (index)
10011            address = offset_addr;
10012        else
10013            address = Rn;
10014
10015        RegisterInfo base_reg;
10016        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10017        RegisterInfo data_reg;
10018        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10019        EmulateInstruction::Context context;
10020        context.type = eContextRegisterStore;
10021        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10022
10023        // MemU[address,4] = if t == 15 then PCStoreValue() else R[t];
10024        uint32_t Rt = ReadCoreReg (t, &success);
10025        if (!success)
10026            return false;
10027
10028        if (t == 15)
10029        {
10030            uint32_t pc_value = ReadCoreReg (PC_REG, &success);
10031            if (!success)
10032                return false;
10033
10034            if (!MemUWrite (context, address, pc_value, addr_byte_size))
10035                return false;
10036        }
10037        else
10038        {
10039            if (!MemUWrite (context, address, Rt, addr_byte_size))
10040                  return false;
10041        }
10042
10043        // if wback then R[n] = offset_addr;
10044        if (wback)
10045        {
10046            context.type = eContextAdjustBaseRegister;
10047            context.SetImmediate (offset_addr);
10048
10049            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10050                return false;
10051        }
10052    }
10053    return true;
10054}
10055
10056// A8.6.66 LDRD (immediate)
10057// Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two
10058// words from memory, and writes them to two registers.  It can use offset, post-indexed, or pre-indexed addressing.
10059bool
10060EmulateInstructionARM::EmulateLDRDImmediate (const uint32_t opcode, const ARMEncoding encoding)
10061{
10062#if 0
10063    if ConditionPassed() then
10064        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10065        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10066        address = if index then offset_addr else R[n];
10067        R[t] = MemA[address,4];
10068        R[t2] = MemA[address+4,4];
10069        if wback then R[n] = offset_addr;
10070#endif
10071
10072    bool success = false;
10073
10074    if (ConditionPassed(opcode))
10075    {
10076        uint32_t t;
10077        uint32_t t2;
10078        uint32_t n;
10079        uint32_t imm32;
10080        bool index;
10081        bool add;
10082        bool wback;
10083
10084        switch (encoding)
10085        {
10086            case eEncodingT1:
10087                //if P == �0� && W == �0� then SEE �Related encodings�;
10088                //if Rn == �1111� then SEE LDRD (literal);
10089                //t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10090                t = Bits32 (opcode, 15, 12);
10091                t2 = Bits32 (opcode, 11, 8);
10092                n = Bits32 (opcode, 19, 16);
10093                imm32 = Bits32 (opcode, 7, 0) << 2;
10094
10095                //index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10096                index = BitIsSet (opcode, 24);
10097                add = BitIsSet (opcode, 23);
10098                wback = BitIsSet (opcode, 21);
10099
10100                //if wback && (n == t || n == t2) then UNPREDICTABLE;
10101                if (wback && ((n == t) || (n == t2)))
10102                    return false;
10103
10104                //if BadReg(t) || BadReg(t2) || t == t2 then UNPREDICTABLE;
10105                if (BadReg (t) || BadReg (t2) || (t == t2))
10106                    return false;
10107
10108                break;
10109
10110            case eEncodingA1:
10111                //if Rn == �1111� then SEE LDRD (literal);
10112                //if Rt<0> == �1� then UNPREDICTABLE;
10113                //t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10114                t = Bits32 (opcode, 15, 12);
10115                if (BitIsSet (t, 0))
10116                    return false;
10117                t2 = t + 1;
10118                n = Bits32 (opcode, 19, 16);
10119                imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10120
10121                //index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10122                index = BitIsSet (opcode, 24);
10123                add = BitIsSet (opcode, 23);
10124                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10125
10126                //if P == �0� && W == �1� then UNPREDICTABLE;
10127                if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10128                    return false;
10129
10130                //if wback && (n == t || n == t2) then UNPREDICTABLE;
10131                if (wback && ((n == t) || (n == t2)))
10132                    return false;
10133
10134                //if t2 == 15 then UNPREDICTABLE;
10135                if (t2 == 15)
10136                    return false;
10137
10138                break;
10139
10140            default:
10141                return false;
10142        }
10143
10144        //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10145        uint32_t Rn = ReadCoreReg (n, &success);
10146        if (!success)
10147            return false;
10148
10149        addr_t offset_addr;
10150        if (add)
10151                  offset_addr = Rn + imm32;
10152        else
10153            offset_addr = Rn - imm32;
10154
10155        //address = if index then offset_addr else R[n];
10156        addr_t address;
10157        if (index)
10158            address = offset_addr;
10159        else
10160            address = Rn;
10161
10162        //R[t] = MemA[address,4];
10163        RegisterInfo base_reg;
10164        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10165
10166        EmulateInstruction::Context context;
10167        context.type = eContextRegisterLoad;
10168        context.SetRegisterPlusOffset (base_reg, address - Rn);
10169
10170        const uint32_t addr_byte_size = GetAddressByteSize();
10171        uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10172        if (!success)
10173            return false;
10174
10175        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10176            return false;
10177
10178        //R[t2] = MemA[address+4,4];
10179
10180        context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10181        data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10182        if (!success)
10183            return false;
10184
10185        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10186            return false;
10187
10188        //if wback then R[n] = offset_addr;
10189        if (wback)
10190        {
10191            context.type = eContextAdjustBaseRegister;
10192            context.SetAddress (offset_addr);
10193
10194            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10195                return false;
10196        }
10197    }
10198    return true;
10199}
10200
10201// A8.6.68 LDRD (register)
10202// Load Register Dual (register) calculates an address from a base register value and a register offset, loads two
10203// words from memory, and writes them to two registers.  It can use offset, post-indexed or pre-indexed addressing.
10204bool
10205EmulateInstructionARM::EmulateLDRDRegister (const uint32_t opcode, const ARMEncoding encoding)
10206{
10207#if 0
10208    if ConditionPassed() then
10209        EncodingSpecificOperations();
10210        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10211        address = if index then offset_addr else R[n];
10212        R[t] = MemA[address,4];
10213        R[t2] = MemA[address+4,4];
10214        if wback then R[n] = offset_addr;
10215#endif
10216
10217    bool success = false;
10218
10219    if (ConditionPassed(opcode))
10220    {
10221        uint32_t t;
10222        uint32_t t2;
10223        uint32_t n;
10224        uint32_t m;
10225        bool index;
10226        bool add;
10227        bool wback;
10228
10229        switch (encoding)
10230        {
10231            case eEncodingA1:
10232                // if Rt<0> == �1� then UNPREDICTABLE;
10233                // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10234                t = Bits32 (opcode, 15, 12);
10235                if (BitIsSet (t, 0))
10236                    return false;
10237                t2 = t + 1;
10238                n = Bits32 (opcode, 19, 16);
10239                m = Bits32 (opcode, 3, 0);
10240
10241                // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10242                index = BitIsSet (opcode, 24);
10243                add = BitIsSet (opcode, 23);
10244                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10245
10246                // if P == �0� && W == �1� then UNPREDICTABLE;
10247                  if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10248                  return false;
10249
10250                // if t2 == 15 || m == 15 || m == t || m == t2 then UNPREDICTABLE;
10251                  if ((t2 == 15) || (m == 15) || (m == t) || (m == t2))
10252                  return false;
10253
10254                // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10255                  if (wback && ((n == 15) || (n == t) || (n == t2)))
10256                  return false;
10257
10258                // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10259                if ((ArchVersion() < 6) && wback && (m == n))
10260                  return false;
10261                break;
10262
10263            default:
10264                return false;
10265        }
10266
10267        uint32_t Rn = ReadCoreReg (n, &success);
10268        if (!success)
10269            return false;
10270        RegisterInfo base_reg;
10271        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10272
10273        uint32_t Rm = ReadCoreReg (m, &success);
10274        if (!success)
10275            return false;
10276        RegisterInfo offset_reg;
10277        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10278
10279        // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10280        addr_t offset_addr;
10281        if (add)
10282            offset_addr = Rn + Rm;
10283        else
10284            offset_addr = Rn - Rm;
10285
10286        // address = if index then offset_addr else R[n];
10287        addr_t address;
10288        if (index)
10289            address = offset_addr;
10290        else
10291            address = Rn;
10292
10293        EmulateInstruction::Context context;
10294        context.type = eContextRegisterLoad;
10295        context.SetRegisterPlusIndirectOffset (base_reg, offset_reg);
10296
10297        // R[t] = MemA[address,4];
10298        const uint32_t addr_byte_size = GetAddressByteSize();
10299        uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10300        if (!success)
10301            return false;
10302
10303        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t, data))
10304            return false;
10305
10306        // R[t2] = MemA[address+4,4];
10307
10308        data = MemARead (context, address + 4, addr_byte_size, 0, &success);
10309        if (!success)
10310            return false;
10311
10312        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + t2, data))
10313            return false;
10314
10315        // if wback then R[n] = offset_addr;
10316        if (wback)
10317        {
10318            context.type = eContextAdjustBaseRegister;
10319            context.SetAddress (offset_addr);
10320
10321            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10322                return false;
10323        }
10324    }
10325    return true;
10326}
10327
10328// A8.6.200 STRD (immediate)
10329// Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and
10330// stores two words from two registers to memory.  It can use offset, post-indexed, or pre-indexed addressing.
10331bool
10332EmulateInstructionARM::EmulateSTRDImm (const uint32_t opcode, const ARMEncoding encoding)
10333{
10334#if 0
10335    if ConditionPassed() then
10336        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
10337        offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10338        address = if index then offset_addr else R[n];
10339        MemA[address,4] = R[t];
10340        MemA[address+4,4] = R[t2];
10341        if wback then R[n] = offset_addr;
10342#endif
10343
10344    bool success = false;
10345
10346    if (ConditionPassed(opcode))
10347    {
10348        uint32_t t;
10349        uint32_t t2;
10350        uint32_t n;
10351        uint32_t imm32;
10352        bool index;
10353        bool add;
10354        bool wback;
10355
10356        switch (encoding)
10357        {
10358            case eEncodingT1:
10359                // if P == �0� && W == �0� then SEE �Related encodings�;
10360                // t = UInt(Rt); t2 = UInt(Rt2); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10361                t = Bits32 (opcode, 15, 12);
10362                t2 = Bits32 (opcode, 11, 8);
10363                n = Bits32 (opcode, 19, 16);
10364                imm32 = Bits32 (opcode, 7, 0) << 2;
10365
10366                // index = (P == �1�); add = (U == �1�); wback = (W == �1�);
10367                index = BitIsSet (opcode, 24);
10368                add = BitIsSet (opcode, 23);
10369                wback = BitIsSet (opcode, 21);
10370
10371                // if wback && (n == t || n == t2) then UNPREDICTABLE;
10372                if (wback && ((n == t) || (n == t2)))
10373                    return false;
10374
10375                // if n == 15 || BadReg(t) || BadReg(t2) then UNPREDICTABLE;
10376                if ((n == 15) || BadReg (t) || BadReg (t2))
10377                    return false;
10378
10379                break;
10380
10381            case eEncodingA1:
10382                // if Rt<0> == �1� then UNPREDICTABLE;
10383                // t = UInt(Rt); t2 = t+1; n = UInt(Rn); imm32 = ZeroExtend(imm4H:imm4L, 32);
10384                t = Bits32 (opcode, 15, 12);
10385                if (BitIsSet (t, 0))
10386                    return false;
10387
10388                t2 = t + 1;
10389                n = Bits32 (opcode, 19, 16);
10390                imm32 = (Bits32 (opcode, 11, 8) << 4) | Bits32 (opcode, 3, 0);
10391
10392                // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10393                index = BitIsSet (opcode, 24);
10394                add = BitIsSet (opcode, 23);
10395                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10396
10397                // if P == �0� && W == �1� then UNPREDICTABLE;
10398                if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10399                    return false;
10400
10401                // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10402                if (wback && ((n == 15) || (n == t) || (n == t2)))
10403                    return false;
10404
10405                // if t2 == 15 then UNPREDICTABLE;
10406                if (t2 == 15)
10407                    return false;
10408
10409                break;
10410
10411            default:
10412                return false;
10413        }
10414
10415        RegisterInfo base_reg;
10416        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10417
10418        uint32_t Rn = ReadCoreReg (n, &success);
10419        if (!success)
10420            return false;
10421
10422        //offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
10423        addr_t offset_addr;
10424        if (add)
10425            offset_addr = Rn + imm32;
10426        else
10427            offset_addr = Rn - imm32;
10428
10429        //address = if index then offset_addr else R[n];
10430        addr_t address;
10431        if (index)
10432            address = offset_addr;
10433        else
10434            address = Rn;
10435
10436        //MemA[address,4] = R[t];
10437        RegisterInfo data_reg;
10438        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10439
10440        uint32_t data = ReadCoreReg (t, &success);
10441        if (!success)
10442            return false;
10443
10444        EmulateInstruction::Context context;
10445        context.type = eContextRegisterStore;
10446        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10447
10448        const uint32_t addr_byte_size = GetAddressByteSize();
10449
10450        if (!MemAWrite (context, address, data, addr_byte_size))
10451            return false;
10452
10453        //MemA[address+4,4] = R[t2];
10454        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10455        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10456
10457        data = ReadCoreReg (t2, &success);
10458        if (!success)
10459            return false;
10460
10461        if (!MemAWrite (context, address + 4, data, addr_byte_size))
10462            return false;
10463
10464        //if wback then R[n] = offset_addr;
10465        if (wback)
10466        {
10467            context.type = eContextAdjustBaseRegister;
10468            context.SetAddress (offset_addr);
10469
10470            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10471                return false;
10472        }
10473    }
10474    return true;
10475}
10476
10477
10478// A8.6.201 STRD (register)
10479bool
10480EmulateInstructionARM::EmulateSTRDReg (const uint32_t opcode, const ARMEncoding encoding)
10481{
10482#if 0
10483    if ConditionPassed() then
10484        EncodingSpecificOperations();
10485        offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10486        address = if index then offset_addr else R[n];
10487        MemA[address,4] = R[t];
10488        MemA[address+4,4] = R[t2];
10489        if wback then R[n] = offset_addr;
10490#endif
10491
10492    bool success = false;
10493
10494    if (ConditionPassed(opcode))
10495    {
10496        uint32_t t;
10497        uint32_t t2;
10498        uint32_t n;
10499        uint32_t m;
10500        bool index;
10501        bool add;
10502        bool wback;
10503
10504        switch (encoding)
10505        {
10506            case eEncodingA1:
10507                // if Rt<0> == �1� then UNPREDICTABLE;
10508                // t = UInt(Rt); t2 = t+1; n = UInt(Rn); m = UInt(Rm);
10509                t = Bits32 (opcode, 15, 12);
10510                if (BitIsSet (t, 0))
10511                   return false;
10512
10513                t2 = t+1;
10514                n = Bits32 (opcode, 19, 16);
10515                m = Bits32 (opcode, 3, 0);
10516
10517                // index = (P == �1�); add = (U == �1�); wback = (P == �0�) || (W == �1�);
10518                index = BitIsSet (opcode, 24);
10519                add = BitIsSet (opcode, 23);
10520                wback = BitIsClear (opcode, 24) || BitIsSet (opcode, 21);
10521
10522                // if P == �0� && W == �1� then UNPREDICTABLE;
10523                if (BitIsClear (opcode, 24) && BitIsSet (opcode, 21))
10524                   return false;
10525
10526                // if t2 == 15 || m == 15 then UNPREDICTABLE;
10527                if ((t2 == 15) || (m == 15))
10528                   return false;
10529
10530                // if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
10531                if (wback && ((n == 15) || (n == t) || (n == t2)))
10532                   return false;
10533
10534                // if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE;
10535                if ((ArchVersion() < 6) && wback && (m == n))
10536                   return false;
10537
10538                break;
10539
10540            default:
10541                return false;
10542        }
10543
10544        RegisterInfo base_reg;
10545        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10546        RegisterInfo offset_reg;
10547        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + m, offset_reg);
10548        RegisterInfo data_reg;
10549
10550        uint32_t Rn = ReadCoreReg (n, &success);
10551        if (!success)
10552            return false;
10553
10554        uint32_t Rm = ReadCoreReg (m, &success);
10555        if (!success)
10556            return false;
10557
10558        // offset_addr = if add then (R[n] + R[m]) else (R[n] - R[m]);
10559        addr_t offset_addr;
10560        if (add)
10561            offset_addr = Rn + Rm;
10562        else
10563            offset_addr = Rn - Rm;
10564
10565        // address = if index then offset_addr else R[n];
10566        addr_t address;
10567        if (index)
10568            address = offset_addr;
10569        else
10570            address = Rn;
10571                          // MemA[address,4] = R[t];
10572        uint32_t Rt = ReadCoreReg (t, &success);
10573        if (!success)
10574            return false;
10575
10576        EmulateInstruction::Context context;
10577        context.type = eContextRegisterStore;
10578        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t, data_reg);
10579        context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10580
10581        const uint32_t addr_byte_size = GetAddressByteSize();
10582
10583        if (!MemAWrite (context, address, Rt, addr_byte_size))
10584            return false;
10585
10586        // MemA[address+4,4] = R[t2];
10587        uint32_t Rt2 = ReadCoreReg (t2, &success);
10588        if (!success)
10589            return false;
10590
10591        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + t2, data_reg);
10592
10593        context.SetRegisterToRegisterPlusIndirectOffset (base_reg, offset_reg, data_reg);
10594
10595        if (!MemAWrite (context, address + 4, Rt2, addr_byte_size))
10596            return false;
10597
10598        // if wback then R[n] = offset_addr;
10599        if (wback)
10600        {
10601            context.type = eContextAdjustBaseRegister;
10602            context.SetAddress (offset_addr);
10603
10604            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, offset_addr))
10605                return false;
10606
10607        }
10608    }
10609    return true;
10610}
10611
10612// A8.6.319 VLDM
10613// Vector Load Multiple loads multiple extension registers from consecutive memory locations using an address from
10614// an ARM core register.
10615bool
10616EmulateInstructionARM::EmulateVLDM (const uint32_t opcode, const ARMEncoding encoding)
10617{
10618#if 0
10619    if ConditionPassed() then
10620        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10621        address = if add then R[n] else R[n]-imm32;
10622        if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10623        for r = 0 to regs-1
10624            if single_regs then
10625                S[d+r] = MemA[address,4]; address = address+4;
10626            else
10627                word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10628                // Combine the word-aligned words in the correct order for current endianness.
10629                D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10630#endif
10631
10632    bool success = false;
10633
10634    if (ConditionPassed(opcode))
10635    {
10636        bool single_regs;
10637        bool add;
10638        bool wback;
10639        uint32_t d;
10640        uint32_t n;
10641        uint32_t imm32;
10642        uint32_t regs;
10643
10644        switch (encoding)
10645        {
10646            case eEncodingT1:
10647            case eEncodingA1:
10648                // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10649                // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10650                // if P == �1� && W == �0� then SEE VLDR;
10651                // if P == U && W == �1� then UNDEFINED;
10652                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10653                    return false;
10654
10655                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10656                // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10657                single_regs = false;
10658                add = BitIsSet (opcode, 23);
10659                wback = BitIsSet (opcode, 21);
10660
10661                // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10662                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10663                n = Bits32 (opcode, 19, 16);
10664                imm32 = Bits32 (opcode, 7, 0) << 2;
10665
10666                // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FLDMX�.
10667                regs = Bits32 (opcode, 7, 0) / 2;
10668
10669                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10670                if (n == 15 && (wback || CurrentInstrSet() != eModeARM))
10671                    return false;
10672
10673                // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10674                if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10675                    return false;
10676
10677                break;
10678
10679            case eEncodingT2:
10680            case eEncodingA2:
10681                // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10682                // if P == �0� && U == �1� && W == �1� && Rn == �1101� then SEE VPOP;
10683                // if P == �1� && W == �0� then SEE VLDR;
10684                // if P == U && W == �1� then UNDEFINED;
10685                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10686                    return false;
10687
10688                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10689                // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10690                single_regs = true;
10691                add = BitIsSet (opcode, 23);
10692                wback = BitIsSet (opcode, 21);
10693                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10694                n = Bits32 (opcode, 19, 16);
10695
10696                // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10697                imm32 = Bits32 (opcode, 7, 0) << 2;
10698                regs = Bits32 (opcode, 7, 0);
10699
10700                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10701                if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10702                    return false;
10703
10704                // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10705                if ((regs == 0) || ((d + regs) > 32))
10706                    return false;
10707                break;
10708
10709            default:
10710                return false;
10711        }
10712
10713        RegisterInfo base_reg;
10714        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10715
10716        uint32_t Rn = ReadCoreReg (n, &success);
10717        if (!success)
10718            return false;
10719
10720        // address = if add then R[n] else R[n]-imm32;
10721        addr_t address;
10722        if (add)
10723            address = Rn;
10724        else
10725            address = Rn - imm32;
10726
10727        // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10728        EmulateInstruction::Context context;
10729
10730        if (wback)
10731        {
10732            uint32_t value;
10733            if (add)
10734                value = Rn + imm32;
10735            else
10736                value = Rn - imm32;
10737
10738            context.type = eContextAdjustBaseRegister;
10739            context.SetImmediateSigned (value - Rn);
10740            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10741                return false;
10742
10743        }
10744
10745        const uint32_t addr_byte_size = GetAddressByteSize();
10746        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10747
10748        context.type = eContextRegisterLoad;
10749
10750        // for r = 0 to regs-1
10751        for (uint32_t r = 0; r < regs; ++r)
10752        {
10753            if (single_regs)
10754            {
10755                // S[d+r] = MemA[address,4]; address = address+4;
10756                context.SetRegisterPlusOffset (base_reg, address - Rn);
10757
10758                uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
10759                if (!success)
10760                    return false;
10761
10762                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10763                    return false;
10764
10765                address = address + 4;
10766            }
10767            else
10768            {
10769                // word1 = MemA[address,4]; word2 = MemA[address+4,4]; address = address+8;
10770                context.SetRegisterPlusOffset (base_reg, address - Rn);
10771                uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
10772                if (!success)
10773                    return false;
10774
10775                context.SetRegisterPlusOffset (base_reg, (address + 4) - Rn);
10776                uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
10777                if (!success)
10778                    return false;
10779
10780                address = address + 8;
10781                // // Combine the word-aligned words in the correct order for current endianness.
10782                // D[d+r] = if BigEndian() then word1:word2 else word2:word1;
10783                uint64_t data;
10784                if (GetByteOrder() == eByteOrderBig)
10785                {
10786                    data = word1;
10787                    data = (data << 32) | word2;
10788                }
10789                else
10790                {
10791                    data = word2;
10792                    data = (data << 32) | word1;
10793                }
10794
10795                if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d + r, data))
10796                    return false;
10797            }
10798        }
10799    }
10800    return true;
10801}
10802
10803// A8.6.399 VSTM
10804// Vector Store Multiple stores multiple extension registers to consecutive memory locations using an address from an
10805// ARM core register.
10806bool
10807EmulateInstructionARM::EmulateVSTM (const uint32_t opcode, const ARMEncoding encoding)
10808{
10809#if 0
10810    if ConditionPassed() then
10811        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
10812        address = if add then R[n] else R[n]-imm32;
10813        if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10814        for r = 0 to regs-1
10815            if single_regs then
10816                MemA[address,4] = S[d+r]; address = address+4;
10817            else
10818                // Store as two word-aligned words in the correct order for current endianness.
10819                MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10820                MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10821                address = address+8;
10822#endif
10823
10824    bool success = false;
10825
10826    if (ConditionPassed (opcode))
10827    {
10828        bool single_regs;
10829        bool add;
10830        bool wback;
10831        uint32_t d;
10832        uint32_t n;
10833        uint32_t imm32;
10834        uint32_t regs;
10835
10836        switch (encoding)
10837        {
10838            case eEncodingT1:
10839            case eEncodingA1:
10840                // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10841                // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10842                // if P == �1� && W == �0� then SEE VSTR;
10843                // if P == U && W == �1� then UNDEFINED;
10844                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10845                    return false;
10846
10847                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10848                // single_regs = FALSE; add = (U == �1�); wback = (W == �1�);
10849                single_regs = false;
10850                add = BitIsSet (opcode, 23);
10851                wback = BitIsSet (opcode, 21);
10852
10853                // d = UInt(D:Vd); n = UInt(Rn); imm32 = ZeroExtend(imm8:�00�, 32);
10854                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
10855                n = Bits32 (opcode, 19, 16);
10856                imm32 = Bits32 (opcode, 7, 0) << 2;
10857
10858                // regs = UInt(imm8) DIV 2; // If UInt(imm8) is odd, see �FSTMX�.
10859                regs = Bits32 (opcode, 7, 0) / 2;
10860
10861                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10862                if ((n == 15) && (wback || (CurrentInstrSet() != eModeARM)))
10863                    return false;
10864
10865                // if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
10866                if ((regs == 0) || (regs > 16) || ((d + regs) > 32))
10867                    return false;
10868
10869                break;
10870
10871            case eEncodingT2:
10872            case eEncodingA2:
10873                // if P == �0� && U == �0� && W == �0� then SEE �Related encodings�;
10874                // if P == �1� && U == �0� && W == �1� && Rn == �1101� then SEE VPUSH;
10875                // if P == �1� && W == �0� then SEE VSTR;
10876                // if P == U && W == �1� then UNDEFINED;
10877                if ((Bit32 (opcode, 24) == Bit32 (opcode, 23)) && BitIsSet (opcode, 21))
10878                    return false;
10879
10880                // // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
10881                // single_regs = TRUE; add = (U == �1�); wback = (W == �1�); d = UInt(Vd:D); n = UInt(Rn);
10882                single_regs = true;
10883                add = BitIsSet (opcode, 23);
10884                wback = BitIsSet (opcode, 21);
10885                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
10886                n = Bits32 (opcode, 19, 16);
10887
10888                // imm32 = ZeroExtend(imm8:�00�, 32); regs = UInt(imm8);
10889                imm32 = Bits32 (opcode, 7, 0) << 2;
10890                regs = Bits32 (opcode, 7, 0);
10891
10892                // if n == 15 && (wback || CurrentInstrSet() != InstrSet_ARM) then UNPREDICTABLE;
10893                if ((n == 15) && (wback || (CurrentInstrSet () != eModeARM)))
10894                    return false;
10895
10896                // if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;
10897                if ((regs == 0) || ((d + regs) > 32))
10898                    return false;
10899
10900                break;
10901
10902            default:
10903                return false;
10904        }
10905
10906        RegisterInfo base_reg;
10907        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
10908
10909        uint32_t Rn = ReadCoreReg (n, &success);
10910        if (!success)
10911            return false;
10912
10913        // address = if add then R[n] else R[n]-imm32;
10914        addr_t address;
10915        if (add)
10916            address = Rn;
10917        else
10918            address = Rn - imm32;
10919
10920        EmulateInstruction::Context context;
10921        // if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
10922        if (wback)
10923        {
10924            uint32_t value;
10925            if (add)
10926                value = Rn + imm32;
10927            else
10928                value = Rn - imm32;
10929
10930            context.type = eContextAdjustBaseRegister;
10931            context.SetRegisterPlusOffset (base_reg, value - Rn);
10932
10933            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
10934                return false;
10935        }
10936
10937        const uint32_t addr_byte_size = GetAddressByteSize();
10938        uint32_t start_reg = single_regs ? dwarf_s0 : dwarf_d0;
10939
10940        context.type = eContextRegisterStore;
10941        // for r = 0 to regs-1
10942        for (int r = 0; r < regs; ++r)
10943        {
10944
10945            if (single_regs)
10946            {
10947                // MemA[address,4] = S[d+r]; address = address+4;
10948                uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10949                if (!success)
10950                    return false;
10951
10952                RegisterInfo data_reg;
10953                GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
10954                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10955                if (!MemAWrite (context, address, data, addr_byte_size))
10956                    return false;
10957
10958                address = address + 4;
10959            }
10960            else
10961            {
10962                // // Store as two word-aligned words in the correct order for current endianness.
10963                // MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
10964                // MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
10965                uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d + r, 0, &success);
10966                if (!success)
10967                    return false;
10968
10969                RegisterInfo data_reg;
10970                GetRegisterInfo (eRegisterKindDWARF, start_reg + d + r, data_reg);
10971
10972                if (GetByteOrder() == eByteOrderBig)
10973                {
10974                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10975                    if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
10976                        return false;
10977
10978                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10979                    if (!MemAWrite (context, address+ 4, Bits64 (data, 31, 0), addr_byte_size))
10980                        return false;
10981                }
10982                else
10983                {
10984                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
10985                    if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
10986                        return false;
10987
10988                    context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
10989                    if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
10990                        return false;
10991                }
10992                // address = address+8;
10993                address = address + 8;
10994            }
10995        }
10996    }
10997    return true;
10998}
10999
11000// A8.6.320
11001// This instruciton loads a single extension register fronm memory, using an address from an ARM core register, with
11002// an optional offset.
11003bool
11004EmulateInstructionARM::EmulateVLDR (const uint32_t opcode, ARMEncoding encoding)
11005{
11006#if 0
11007    if ConditionPassed() then
11008        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11009        base = if n == 15 then Align(PC,4) else R[n];
11010        address = if add then (base + imm32) else (base - imm32);
11011        if single_reg then
11012            S[d] = MemA[address,4];
11013        else
11014            word1 = MemA[address,4]; word2 = MemA[address+4,4];
11015            // Combine the word-aligned words in the correct order for current endianness.
11016            D[d] = if BigEndian() then word1:word2 else word2:word1;
11017#endif
11018
11019    bool success = false;
11020
11021    if (ConditionPassed (opcode))
11022    {
11023        bool single_reg;
11024        bool add;
11025        uint32_t imm32;
11026        uint32_t d;
11027        uint32_t n;
11028
11029        switch (encoding)
11030        {
11031            case eEncodingT1:
11032            case eEncodingA1:
11033                // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11034                single_reg = false;
11035                add = BitIsSet (opcode, 23);
11036                imm32 = Bits32 (opcode, 7, 0) << 2;
11037
11038                // d = UInt(D:Vd); n = UInt(Rn);
11039                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11040                n = Bits32 (opcode, 19, 16);
11041
11042                break;
11043
11044            case eEncodingT2:
11045            case eEncodingA2:
11046                // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11047                single_reg = true;
11048                add = BitIsSet (opcode, 23);
11049                imm32 = Bits32 (opcode, 7, 0) << 2;
11050
11051                // d = UInt(Vd:D); n = UInt(Rn);
11052                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11053                n = Bits32 (opcode, 19, 16);
11054
11055                break;
11056
11057            default:
11058                return false;
11059        }
11060        RegisterInfo base_reg;
11061        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11062
11063        uint32_t Rn = ReadCoreReg (n, &success);
11064        if (!success)
11065            return false;
11066
11067        // base = if n == 15 then Align(PC,4) else R[n];
11068        uint32_t base;
11069        if (n == 15)
11070            base = AlignPC (Rn);
11071        else
11072            base = Rn;
11073
11074        // address = if add then (base + imm32) else (base - imm32);
11075        addr_t address;
11076        if (add)
11077            address = base + imm32;
11078        else
11079            address = base - imm32;
11080
11081        const uint32_t addr_byte_size = GetAddressByteSize();
11082        uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11083
11084        EmulateInstruction::Context context;
11085        context.type = eContextRegisterLoad;
11086        context.SetRegisterPlusOffset (base_reg, address - base);
11087
11088        if (single_reg)
11089        {
11090            // S[d] = MemA[address,4];
11091            uint32_t data = MemARead (context, address, addr_byte_size, 0, &success);
11092            if (!success)
11093                return false;
11094
11095            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data))
11096                return false;
11097        }
11098        else
11099        {
11100            // word1 = MemA[address,4]; word2 = MemA[address+4,4];
11101            uint32_t word1 = MemARead (context, address, addr_byte_size, 0, &success);
11102            if (!success)
11103                return false;
11104
11105            context.SetRegisterPlusOffset (base_reg, (address + 4) - base);
11106            uint32_t word2 = MemARead (context, address + 4, addr_byte_size, 0, &success);
11107            if (!success)
11108                return false;
11109            // // Combine the word-aligned words in the correct order for current endianness.
11110            // D[d] = if BigEndian() then word1:word2 else word2:word1;
11111            uint64_t data64;
11112            if (GetByteOrder() == eByteOrderBig)
11113            {
11114                data64 = word1;
11115                data64 = (data64 << 32) | word2;
11116            }
11117            else
11118            {
11119                data64 = word2;
11120                data64 = (data64 << 32) | word1;
11121            }
11122
11123            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, start_reg + d, data64))
11124                return false;
11125        }
11126    }
11127    return true;
11128}
11129
11130// A8.6.400 VSTR
11131// This instruction stores a signle extension register to memory, using an address from an ARM core register, with an
11132// optional offset.
11133bool
11134EmulateInstructionARM::EmulateVSTR (const uint32_t opcode, ARMEncoding encoding)
11135{
11136#if 0
11137    if ConditionPassed() then
11138        EncodingSpecificOperations(); CheckVFPEnabled(TRUE); NullCheckIfThumbEE(n);
11139        address = if add then (R[n] + imm32) else (R[n] - imm32);
11140        if single_reg then
11141            MemA[address,4] = S[d];
11142        else
11143            // Store as two word-aligned words in the correct order for current endianness.
11144            MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11145            MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11146#endif
11147
11148    bool success = false;
11149
11150    if (ConditionPassed (opcode))
11151    {
11152        bool single_reg;
11153        bool add;
11154        uint32_t imm32;
11155        uint32_t d;
11156        uint32_t n;
11157
11158        switch (encoding)
11159        {
11160            case eEncodingT1:
11161            case eEncodingA1:
11162                // single_reg = FALSE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11163                single_reg = false;
11164                add = BitIsSet (opcode, 23);
11165                imm32 = Bits32 (opcode, 7, 0) << 2;
11166
11167                // d = UInt(D:Vd); n = UInt(Rn);
11168                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11169                n = Bits32 (opcode, 19, 16);
11170
11171                // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11172                if ((n == 15) && (CurrentInstrSet() != eModeARM))
11173                    return false;
11174
11175                break;
11176
11177            case eEncodingT2:
11178            case eEncodingA2:
11179                // single_reg = TRUE; add = (U == �1�); imm32 = ZeroExtend(imm8:�00�, 32);
11180                single_reg = true;
11181                add = BitIsSet (opcode, 23);
11182                imm32 = Bits32 (opcode, 7, 0) << 2;
11183
11184                // d = UInt(Vd:D); n = UInt(Rn);
11185                d = (Bits32 (opcode, 15, 12) << 1) | Bit32 (opcode, 22);
11186                n = Bits32 (opcode, 19, 16);
11187
11188                // if n == 15 && CurrentInstrSet() != InstrSet_ARM then UNPREDICTABLE;
11189                if ((n == 15) && (CurrentInstrSet() != eModeARM))
11190                    return false;
11191
11192                break;
11193
11194            default:
11195                return false;
11196        }
11197
11198        RegisterInfo base_reg;
11199        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11200
11201        uint32_t Rn = ReadCoreReg (n, &success);
11202        if (!success)
11203            return false;
11204
11205        // address = if add then (R[n] + imm32) else (R[n] - imm32);
11206        addr_t address;
11207        if (add)
11208            address = Rn + imm32;
11209        else
11210            address = Rn - imm32;
11211
11212        const uint32_t addr_byte_size = GetAddressByteSize();
11213        uint32_t start_reg = single_reg ? dwarf_s0 : dwarf_d0;
11214
11215        RegisterInfo data_reg;
11216        GetRegisterInfo (eRegisterKindDWARF, start_reg + d, data_reg);
11217        EmulateInstruction::Context context;
11218        context.type = eContextRegisterStore;
11219        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11220
11221        if (single_reg)
11222        {
11223            // MemA[address,4] = S[d];
11224            uint32_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11225            if (!success)
11226                return false;
11227
11228            if (!MemAWrite (context, address, data, addr_byte_size))
11229                return false;
11230        }
11231        else
11232        {
11233            // // Store as two word-aligned words in the correct order for current endianness.
11234            // MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
11235            // MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;
11236            uint64_t data = ReadRegisterUnsigned (eRegisterKindDWARF, start_reg + d, 0, &success);
11237            if (!success)
11238                return false;
11239
11240            if (GetByteOrder() == eByteOrderBig)
11241            {
11242                if (!MemAWrite (context, address, Bits64 (data, 63, 32), addr_byte_size))
11243                    return false;
11244
11245                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11246                if (!MemAWrite (context, address + 4, Bits64 (data, 31, 0), addr_byte_size))
11247                    return false;
11248            }
11249            else
11250            {
11251                if (!MemAWrite (context, address, Bits64 (data, 31, 0), addr_byte_size))
11252                    return false;
11253
11254                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, (address + 4) - Rn);
11255                if (!MemAWrite (context, address + 4, Bits64 (data, 63, 32), addr_byte_size))
11256                    return false;
11257            }
11258        }
11259    }
11260    return true;
11261}
11262
11263// A8.6.307 VLDI1 (multiple single elements)
11264// This instruction loads elements from memory into one, two, three or four registers, without de-interleaving.  Every
11265// element of each register is loaded.
11266bool
11267EmulateInstructionARM::EmulateVLD1Multiple (const uint32_t opcode, ARMEncoding encoding)
11268{
11269#if 0
11270    if ConditionPassed() then
11271        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11272        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11273        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11274        for r = 0 to regs-1
11275            for e = 0 to elements-1
11276                Elem[D[d+r],e,esize] = MemU[address,ebytes];
11277                address = address + ebytes;
11278#endif
11279
11280    bool success = false;
11281
11282    if (ConditionPassed (opcode))
11283    {
11284        uint32_t regs;
11285        uint32_t alignment;
11286        uint32_t ebytes;
11287        uint32_t esize;
11288        uint32_t elements;
11289        uint32_t d;
11290        uint32_t n;
11291        uint32_t m;
11292        bool wback;
11293        bool register_index;
11294
11295        switch (encoding)
11296        {
11297            case eEncodingT1:
11298            case eEncodingA1:
11299            {
11300                // case type of
11301                    // when �0111�
11302                        // regs = 1; if align<1> == �1� then UNDEFINED;
11303                    // when �1010�
11304                        // regs = 2; if align == �11� then UNDEFINED;
11305                    // when �0110�
11306                        // regs = 3; if align<1> == �1� then UNDEFINED;
11307                    // when �0010�
11308                        // regs = 4;
11309                    // otherwise
11310                        // SEE �Related encodings�;
11311                uint32_t type = Bits32 (opcode, 11, 8);
11312                uint32_t align = Bits32 (opcode, 5, 4);
11313                if (type == 7) // '0111'
11314                {
11315                    regs = 1;
11316                    if (BitIsSet (align, 1))
11317                        return false;
11318                }
11319                else if (type == 10) // '1010'
11320                {
11321                    regs = 2;
11322                    if (align == 3)
11323                        return false;
11324
11325                }
11326                else if (type == 6) // '0110'
11327                {
11328                    regs = 3;
11329                    if (BitIsSet (align, 1))
11330                        return false;
11331                }
11332                else if (type == 2) // '0010'
11333                {
11334                    regs = 4;
11335                }
11336                else
11337                    return false;
11338
11339                // alignment = if align == �00� then 1 else 4 << UInt(align);
11340                if (align == 0)
11341                    alignment = 1;
11342                else
11343                    alignment = 4 << align;
11344
11345                // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11346                ebytes = 1 << Bits32 (opcode, 7, 6);
11347                esize = 8 * ebytes;
11348                elements = 8 / ebytes;
11349
11350                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11351                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11352                n = Bits32 (opcode, 19, 15);
11353                m = Bits32 (opcode, 3, 0);
11354
11355                // wback = (m != 15); register_index = (m != 15 && m != 13);
11356                wback = (m != 15);
11357                register_index = ((m != 15) && (m != 13));
11358
11359                // if d+regs > 32 then UNPREDICTABLE;
11360                if ((d + regs) > 32)
11361                    return false;
11362            }
11363                break;
11364
11365            default:
11366                return false;
11367        }
11368
11369        RegisterInfo base_reg;
11370        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11371
11372        uint32_t Rn = ReadCoreReg (n, &success);
11373        if (!success)
11374            return false;
11375
11376        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11377        addr_t address = Rn;
11378        if ((address % alignment) != 0)
11379            return false;
11380
11381        EmulateInstruction::Context context;
11382        // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11383        if (wback)
11384        {
11385            uint32_t Rm = ReadCoreReg (m, &success);
11386            if (!success)
11387                return false;
11388
11389            uint32_t offset;
11390            if (register_index)
11391                offset = Rm;
11392            else
11393                offset = 8 * regs;
11394
11395            uint32_t value = Rn + offset;
11396            context.type = eContextAdjustBaseRegister;
11397            context.SetRegisterPlusOffset (base_reg, offset);
11398
11399            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11400                return false;
11401
11402        }
11403
11404        // for r = 0 to regs-1
11405        for (int r = 0; r < regs; ++r)
11406        {
11407            // for e = 0 to elements-1
11408            uint64_t assembled_data = 0;
11409            for (int e = 0; e < elements; ++e)
11410            {
11411                // Elem[D[d+r],e,esize] = MemU[address,ebytes];
11412                context.type = eContextRegisterLoad;
11413                context.SetRegisterPlusOffset (base_reg, address - Rn);
11414                uint64_t data = MemURead (context, address, ebytes, 0, &success);
11415                if (!success)
11416                    return false;
11417
11418                assembled_data = (data << (e * esize)) | assembled_data; // New data goes to the left of existing data
11419
11420                // address = address + ebytes;
11421                address = address + ebytes;
11422            }
11423            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, assembled_data))
11424                return false;
11425        }
11426    }
11427    return true;
11428}
11429
11430// A8.6.308 VLD1 (single element to one lane)
11431//
11432bool
11433EmulateInstructionARM::EmulateVLD1Single (const uint32_t opcode, const ARMEncoding encoding)
11434{
11435#if 0
11436    if ConditionPassed() then
11437        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11438        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11439        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11440        Elem[D[d],index,esize] = MemU[address,ebytes];
11441#endif
11442
11443    bool success = false;
11444
11445    if (ConditionPassed (opcode))
11446    {
11447        uint32_t ebytes;
11448        uint32_t esize;
11449        uint32_t index;
11450        uint32_t alignment;
11451        uint32_t d;
11452        uint32_t n;
11453        uint32_t m;
11454        bool wback;
11455        bool register_index;
11456
11457        switch (encoding)
11458        {
11459            case eEncodingT1:
11460            case eEncodingA1:
11461            {
11462                uint32_t size = Bits32 (opcode, 11, 10);
11463                uint32_t index_align = Bits32 (opcode, 7, 4);
11464                // if size == �11� then SEE VLD1 (single element to all lanes);
11465                if (size == 3)
11466                   return EmulateVLD1SingleAll (opcode, encoding);
11467                // case size of
11468                if (size == 0) // when '00'
11469                {
11470                    // if index_align<0> != �0� then UNDEFINED;
11471                    if (BitIsClear (index_align, 0))
11472                        return false;
11473
11474                    // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11475                    ebytes = 1;
11476                    esize = 8;
11477                    index = Bits32 (index_align, 3, 1);
11478                    alignment = 1;
11479                }
11480                else if (size == 1) // when �01�
11481                {
11482                    // if index_align<1> != �0� then UNDEFINED;
11483                    if (BitIsClear (index_align, 1))
11484                        return false;
11485
11486                    // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11487                    ebytes = 2;
11488                    esize = 16;
11489                    index = Bits32 (index_align, 3, 2);
11490
11491                    // alignment = if index_align<0> == �0� then 1 else 2;
11492                    if (BitIsClear (index_align, 0))
11493                        alignment = 1;
11494                    else
11495                        alignment = 2;
11496                }
11497                else if (size == 2) // when �10�
11498                {
11499                    // if index_align<2> != �0� then UNDEFINED;
11500                    if (BitIsClear (index_align, 2))
11501                        return false;
11502
11503                    // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11504                    if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11505                        return false;
11506
11507                    // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11508                    ebytes = 4;
11509                    esize = 32;
11510                    index = Bit32 (index_align, 3);
11511
11512                    // alignment = if index_align<1:0> == �00� then 1 else 4;
11513                    if (Bits32 (index_align, 1, 0) == 0)
11514                        alignment = 1;
11515                    else
11516                        alignment = 4;
11517                }
11518                else
11519                {
11520                    return false;
11521                }
11522                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11523                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11524                n = Bits32 (opcode, 19, 16);
11525                m = Bits32 (opcode, 3, 0);
11526
11527                // wback = (m != 15); register_index = (m != 15 && m != 13); if n == 15 then UNPREDICTABLE;
11528                wback = (m != 15);
11529                register_index = ((m != 15) && (m != 13));
11530
11531                if (n == 15)
11532                    return false;
11533
11534            }
11535                break;
11536
11537            default:
11538                return false;
11539        }
11540
11541        RegisterInfo base_reg;
11542        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11543
11544        uint32_t Rn = ReadCoreReg (n, &success);
11545        if (!success)
11546            return false;
11547
11548        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11549        addr_t address = Rn;
11550        if ((address % alignment) != 0)
11551            return false;
11552
11553        EmulateInstruction::Context context;
11554        // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11555        if (wback)
11556        {
11557            uint32_t Rm = ReadCoreReg (m, &success);
11558            if (!success)
11559                return false;
11560
11561            uint32_t offset;
11562            if (register_index)
11563                offset = Rm;
11564            else
11565                offset = ebytes;
11566
11567            uint32_t value = Rn + offset;
11568
11569            context.type = eContextAdjustBaseRegister;
11570            context.SetRegisterPlusOffset (base_reg, offset);
11571
11572            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, value))
11573                return false;
11574        }
11575
11576        // Elem[D[d],index,esize] = MemU[address,ebytes];
11577        uint32_t element = MemURead (context, address, esize, 0, &success);
11578        if (!success)
11579            return false;
11580
11581        element = element << (index * esize);
11582
11583        uint64_t reg_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11584        if (!success)
11585            return false;
11586
11587        uint64_t all_ones = -1;
11588        uint64_t mask = all_ones << ((index+1) * esize);  // mask is all 1's to left of where 'element' goes, & all 0's
11589                                                          // at element & to the right of element.
11590        if (index > 0)
11591            mask = mask | Bits64 (all_ones, (index * esize) - 1, 0); // add 1's to the right of where 'element' goes.
11592                                                                     // now mask should be 0's where element goes & 1's
11593                                                                     // everywhere else.
11594
11595        uint64_t masked_reg = reg_data & mask;  // Take original reg value & zero out 'element' bits
11596        reg_data = masked_reg & element;        // Put 'element' into those bits in reg_data.
11597
11598        context.type = eContextRegisterLoad;
11599        if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + d, reg_data))
11600            return false;
11601    }
11602    return true;
11603}
11604
11605// A8.6.391 VST1 (multiple single elements)
11606// Vector Store (multiple single elements) stores elements to memory from one, two, three, or four regsiters, without
11607// interleaving.  Every element of each register is stored.
11608bool
11609EmulateInstructionARM::EmulateVST1Multiple (const uint32_t opcode, ARMEncoding encoding)
11610{
11611#if 0
11612    if ConditionPassed() then
11613        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11614        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11615        if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11616        for r = 0 to regs-1
11617            for e = 0 to elements-1
11618                MemU[address,ebytes] = Elem[D[d+r],e,esize];
11619                address = address + ebytes;
11620#endif
11621
11622    bool success = false;
11623
11624    if (ConditionPassed (opcode))
11625    {
11626        uint32_t regs;
11627        uint32_t alignment;
11628        uint32_t ebytes;
11629        uint32_t esize;
11630        uint32_t elements;
11631        uint32_t d;
11632        uint32_t n;
11633        uint32_t m;
11634        bool wback;
11635        bool register_index;
11636
11637        switch (encoding)
11638        {
11639            case eEncodingT1:
11640            case eEncodingA1:
11641            {
11642                uint32_t type = Bits32 (opcode, 11, 8);
11643                uint32_t align = Bits32 (opcode, 5, 4);
11644
11645                // case type of
11646                if (type == 7)    // when �0111�
11647                {
11648                    // regs = 1; if align<1> == �1� then UNDEFINED;
11649                    regs = 1;
11650                    if (BitIsSet (align, 1))
11651                        return false;
11652                }
11653                else if (type == 10) // when �1010�
11654                {
11655                    // regs = 2; if align == �11� then UNDEFINED;
11656                    regs = 2;
11657                    if (align == 3)
11658                        return false;
11659                }
11660                else if (type == 6) // when �0110�
11661                {
11662                    // regs = 3; if align<1> == �1� then UNDEFINED;
11663                    regs = 3;
11664                    if (BitIsSet (align, 1))
11665                        return false;
11666                }
11667                else if (type == 2) // when �0010�
11668                    // regs = 4;
11669                    regs = 4;
11670                else // otherwise
11671                    // SEE �Related encodings�;
11672                    return false;
11673
11674                // alignment = if align == �00� then 1 else 4 << UInt(align);
11675                if (align == 0)
11676                    alignment = 1;
11677                else
11678                    alignment = 4 << align;
11679
11680                // ebytes = 1 << UInt(size); esize = 8 * ebytes; elements = 8 DIV ebytes;
11681                ebytes = 1 << Bits32 (opcode,7, 6);
11682                esize = 8 * ebytes;
11683                elements = 8 / ebytes;
11684
11685                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11686                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11687                n = Bits32 (opcode, 19, 16);
11688                m = Bits32 (opcode, 3, 0);
11689
11690                // wback = (m != 15); register_index = (m != 15 && m != 13);
11691                wback = (m != 15);
11692                register_index = ((m != 15) && (m != 13));
11693
11694                // if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11695                if ((d + regs) > 32)
11696                    return false;
11697
11698                if (n == 15)
11699                    return false;
11700
11701            }
11702                break;
11703
11704            default:
11705                return false;
11706        }
11707
11708        RegisterInfo base_reg;
11709        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11710
11711        uint32_t Rn = ReadCoreReg (n, &success);
11712        if (!success)
11713            return false;
11714
11715        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11716        addr_t address = Rn;
11717        if ((address % alignment) != 0)
11718            return false;
11719
11720        EmulateInstruction::Context context;
11721        // if wback then R[n] = R[n] + (if register_index then R[m] else 8*regs);
11722        if (wback)
11723        {
11724            uint32_t Rm = ReadCoreReg (m, &success);
11725            if (!success)
11726                return false;
11727
11728            uint32_t offset;
11729            if (register_index)
11730                offset = Rm;
11731            else
11732                offset = 8 * regs;
11733
11734            context.type = eContextAdjustBaseRegister;
11735            context.SetRegisterPlusOffset (base_reg, offset);
11736
11737            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11738                return false;
11739        }
11740
11741        RegisterInfo data_reg;
11742        context.type = eContextRegisterStore;
11743        // for r = 0 to regs-1
11744        for (int r = 0; r < regs; ++r)
11745        {
11746            GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d + r, data_reg);
11747            uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d + r, 0, &success);
11748            if (!success)
11749                return false;
11750
11751             // for e = 0 to elements-1
11752            for (int e = 0; e < elements; ++e)
11753            {
11754                // MemU[address,ebytes] = Elem[D[d+r],e,esize];
11755                uint64_t word = Bits64 (register_data, ((e + 1) * esize) - 1, e * esize);
11756
11757                context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11758                if (!MemUWrite (context, address, word, ebytes))
11759                    return false;
11760
11761                // address = address + ebytes;
11762                address = address + ebytes;
11763            }
11764        }
11765    }
11766    return true;
11767}
11768
11769// A8.6.392 VST1 (single element from one lane)
11770// This instruction stores one element to memory from one element of a register.
11771bool
11772EmulateInstructionARM::EmulateVST1Single (const uint32_t opcode, ARMEncoding encoding)
11773{
11774#if 0
11775    if ConditionPassed() then
11776        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11777        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11778        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11779        MemU[address,ebytes] = Elem[D[d],index,esize];
11780#endif
11781
11782    bool success = false;
11783
11784    if (ConditionPassed (opcode))
11785    {
11786        uint32_t ebytes;
11787        uint32_t esize;
11788        uint32_t index;
11789        uint32_t alignment;
11790        uint32_t d;
11791        uint32_t n;
11792        uint32_t m;
11793        bool wback;
11794        bool register_index;
11795
11796        switch (encoding)
11797        {
11798            case eEncodingT1:
11799            case eEncodingA1:
11800            {
11801                uint32_t size = Bits32 (opcode, 11, 10);
11802                uint32_t index_align = Bits32 (opcode, 7, 4);
11803
11804                // if size == �11� then UNDEFINED;
11805                if (size == 3)
11806                    return false;
11807
11808                // case size of
11809                if (size == 0) // when �00�
11810                {
11811                    // if index_align<0> != �0� then UNDEFINED;
11812                    if (BitIsClear (index_align, 0))
11813                        return false;
11814                    // ebytes = 1; esize = 8; index = UInt(index_align<3:1>); alignment = 1;
11815                    ebytes = 1;
11816                    esize = 8;
11817                    index = Bits32 (index_align, 3, 1);
11818                    alignment = 1;
11819                }
11820                else if (size == 1) // when �01�
11821                {
11822                    // if index_align<1> != �0� then UNDEFINED;
11823                    if (BitIsClear (index_align, 1))
11824                        return false;
11825
11826                    // ebytes = 2; esize = 16; index = UInt(index_align<3:2>);
11827                    ebytes = 2;
11828                    esize = 16;
11829                    index = Bits32 (index_align, 3, 2);
11830
11831                    // alignment = if index_align<0> == �0� then 1 else 2;
11832                    if (BitIsClear (index_align, 0))
11833                        alignment = 1;
11834                    else
11835                        alignment = 2;
11836                }
11837                else if (size == 2) // when �10�
11838                {
11839                    // if index_align<2> != �0� then UNDEFINED;
11840                    if (BitIsClear (index_align, 2))
11841                        return false;
11842
11843                    // if index_align<1:0> != �00� && index_align<1:0> != �11� then UNDEFINED;
11844                    if ((Bits32 (index_align, 1, 0) != 0) && (Bits32 (index_align, 1, 0) != 3))
11845                        return false;
11846
11847                    // ebytes = 4; esize = 32; index = UInt(index_align<3>);
11848                    ebytes = 4;
11849                    esize = 32;
11850                    index = Bit32 (index_align, 3);
11851
11852                    // alignment = if index_align<1:0> == �00� then 1 else 4;
11853                    if (Bits32 (index_align, 1, 0) == 0)
11854                        alignment = 1;
11855                    else
11856                        alignment = 4;
11857                }
11858                else
11859                {
11860                    return false;
11861                }
11862                // d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11863                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11864                n = Bits32 (opcode, 19, 16);
11865                m = Bits32 (opcode, 3, 0);
11866
11867                // wback = (m != 15); register_index = (m != 15 && m != 13);  if n == 15 then UNPREDICTABLE;
11868                wback = (m != 15);
11869                register_index = ((m != 15) && (m != 13));
11870
11871                if (n == 15)
11872                    return false;
11873            }
11874                break;
11875
11876            default:
11877                return false;
11878        }
11879
11880        RegisterInfo base_reg;
11881        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
11882
11883        uint32_t Rn = ReadCoreReg (n, &success);
11884        if (!success)
11885            return false;
11886
11887        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11888        addr_t address = Rn;
11889        if ((address % alignment) != 0)
11890            return false;
11891
11892        EmulateInstruction::Context context;
11893        // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11894        if (wback)
11895        {
11896            uint32_t Rm = ReadCoreReg (m, &success);
11897            if (!success)
11898                return false;
11899
11900            uint32_t offset;
11901            if (register_index)
11902                offset = Rm;
11903            else
11904                offset = ebytes;
11905
11906            context.type = eContextAdjustBaseRegister;
11907            context.SetRegisterPlusOffset (base_reg, offset);
11908
11909            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
11910                return false;
11911        }
11912
11913        // MemU[address,ebytes] = Elem[D[d],index,esize];
11914        uint64_t register_data = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_d0 + d, 0, &success);
11915        if (!success)
11916            return false;
11917
11918        uint64_t word = Bits64 (register_data, ((index + 1) * esize) - 1,  index * esize);
11919
11920        RegisterInfo data_reg;
11921        GetRegisterInfo (eRegisterKindDWARF, dwarf_d0 + d, data_reg);
11922        context.type = eContextRegisterStore;
11923        context.SetRegisterToRegisterPlusOffset (data_reg, base_reg, address - Rn);
11924
11925        if (!MemUWrite (context, address, word, ebytes))
11926            return false;
11927    }
11928    return true;
11929}
11930
11931// A8.6.309 VLD1 (single element to all lanes)
11932// This instruction loads one element from memory into every element of one or two vectors.
11933bool
11934EmulateInstructionARM::EmulateVLD1SingleAll (const uint32_t opcode, const ARMEncoding encoding)
11935{
11936#if 0
11937    if ConditionPassed() then
11938        EncodingSpecificOperations(); CheckAdvSIMDEnabled(); NullCheckIfThumbEE(n);
11939        address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
11940        if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
11941        replicated_element = Replicate(MemU[address,ebytes], elements);
11942        for r = 0 to regs-1
11943            D[d+r] = replicated_element;
11944#endif
11945
11946    bool success = false;
11947
11948    if (ConditionPassed (opcode))
11949    {
11950        uint32_t ebytes;
11951        uint32_t elements;
11952        uint32_t regs;
11953        uint32_t alignment;
11954        uint32_t d;
11955        uint32_t n;
11956        uint32_t m;
11957        bool wback;
11958        bool register_index;
11959
11960        switch (encoding)
11961        {
11962            case eEncodingT1:
11963            case eEncodingA1:
11964            {
11965                //if size == �11� || (size == �00� && a == �1�) then UNDEFINED;
11966                uint32_t size = Bits32 (opcode, 7, 6);
11967                if ((size == 3) || ((size == 0) && BitIsSet (opcode, 4)))
11968                    return false;
11969
11970                //ebytes = 1 << UInt(size); elements = 8 DIV ebytes; regs = if T == �0� then 1 else 2;
11971                ebytes = 1 << size;
11972                elements = 8 / ebytes;
11973                if (BitIsClear (opcode, 5))
11974                    regs = 1;
11975                else
11976                    regs = 2;
11977
11978                //alignment = if a == �0� then 1 else ebytes;
11979                if (BitIsClear (opcode, 4))
11980                    alignment = 1;
11981                else
11982                    alignment = ebytes;
11983
11984                //d = UInt(D:Vd); n = UInt(Rn); m = UInt(Rm);
11985                d = (Bit32 (opcode, 22) << 4) | Bits32 (opcode, 15, 12);
11986                n = Bits32 (opcode, 19, 16);
11987                m = Bits32 (opcode, 3, 0);
11988
11989                //wback = (m != 15); register_index = (m != 15 && m != 13);
11990                wback = (m != 15);
11991                register_index = ((m != 15) && (m != 13));
11992
11993                //if d+regs > 32 then UNPREDICTABLE; if n == 15 then UNPREDICTABLE;
11994                if ((d + regs) > 32)
11995                    return false;
11996
11997                if (n == 15)
11998                    return false;
11999            }
12000            break;
12001
12002            default:
12003                return false;
12004        }
12005
12006        RegisterInfo base_reg;
12007        GetRegisterInfo (eRegisterKindDWARF, dwarf_r0 + n, base_reg);
12008
12009        uint32_t Rn = ReadCoreReg (n, &success);
12010        if (!success)
12011            return false;
12012
12013        // address = R[n]; if (address MOD alignment) != 0 then GenerateAlignmentException();
12014        addr_t address = Rn;
12015        if ((address % alignment) != 0)
12016            return false;
12017
12018        EmulateInstruction::Context context;
12019        // if wback then R[n] = R[n] + (if register_index then R[m] else ebytes);
12020        if (wback)
12021        {
12022            uint32_t Rm = ReadCoreReg (m, &success);
12023            if (!success)
12024                return false;
12025
12026            uint32_t offset;
12027            if (register_index)
12028                offset = Rm;
12029            else
12030                offset = ebytes;
12031
12032            context.type = eContextAdjustBaseRegister;
12033            context.SetRegisterPlusOffset (base_reg, offset);
12034
12035            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_r0 + n, Rn + offset))
12036                return false;
12037        }
12038
12039        // replicated_element = Replicate(MemU[address,ebytes], elements);
12040
12041        context.type = eContextRegisterLoad;
12042        uint64_t word = MemURead (context, address, ebytes, 0, &success);
12043        if (!success)
12044            return false;
12045
12046        uint64_t replicated_element = 0;
12047        uint32_t esize = ebytes * 8;
12048        for (int e = 0; e < elements; ++e)
12049            replicated_element = (replicated_element << esize) | Bits64 (word, esize - 1, 0);
12050
12051        // for r = 0 to regs-1
12052        for (int r = 0; r < regs; ++r)
12053        {
12054            // D[d+r] = replicated_element;
12055            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_d0 + d + r, replicated_element))
12056                return false;
12057        }
12058    }
12059    return true;
12060}
12061
12062// B6.2.13 SUBS PC, LR and related instructions
12063//The SUBS PC, LR, #<const? instruction provides an exception return without the use of the stack.  It subtracts the
12064// immediate constant from the LR, branches to the resulting address, and also copies the SPSR to the CPSR.
12065bool
12066EmulateInstructionARM::EmulateSUBSPcLrEtc (const uint32_t opcode, const ARMEncoding encoding)
12067{
12068#if 0
12069    if ConditionPassed() then
12070        EncodingSpecificOperations();
12071        if CurrentInstrSet() == InstrSet_ThumbEE then
12072            UNPREDICTABLE;
12073        operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12074        case opcode of
12075            when �0000� result = R[n] AND operand2; // AND
12076            when �0001result = R[n] EOR operand2; // EOR
12077            when �0010� (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12078            when �0011� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12079            when �0100� (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12080            when �0101� (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12081            when �0110� (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12082            when �0111� (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12083            when1100result = R[n] OR operand2; // ORR
12084            when1101result = operand2; // MOV
12085            when1110result = R[n] AND NOT(operand2); // BIC
12086            when1111result = NOT(operand2); // MVN
12087        CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12088        BranchWritePC(result);
12089#endif
12090
12091    bool success = false;
12092
12093    if (ConditionPassed (opcode))
12094    {
12095        uint32_t n;
12096        uint32_t m;
12097        uint32_t imm32;
12098        bool register_form;
12099        ARM_ShifterType shift_t;
12100        uint32_t shift_n;
12101        uint32_t code;
12102
12103        switch (encoding)
12104        {
12105            case eEncodingT1:
12106                // if CurrentInstrSet() == InstrSet_ThumbEE then UNPREDICTABLE
12107                // n = 14; imm32 = ZeroExtend(imm8, 32); register_form = FALSE; opcode = �0010�; // = SUB
12108                n = 14;
12109                imm32 = Bits32 (opcode, 7, 0);
12110                register_form = false;
12111                code = 2;
12112
12113                // if InITBlock() && !LastInITBlock() then UNPREDICTABLE;
12114                if (InITBlock() && !LastInITBlock())
12115                    return false;
12116
12117                break;
12118
12119            case eEncodingA1:
12120                // n = UInt(Rn); imm32 = ARMExpandImm(imm12); register_form = FALSE;
12121                n = Bits32 (opcode, 19, 16);
12122                imm32 = ARMExpandImm (opcode);
12123                register_form = false;
12124                code = Bits32 (opcode, 24, 21);
12125
12126                break;
12127
12128            case eEncodingA2:
12129                // n = UInt(Rn); m = UInt(Rm); register_form = TRUE;
12130                n = Bits32 (opcode, 19, 16);
12131                m = Bits32 (opcode, 3, 0);
12132                register_form = true;
12133
12134                // (shift_t, shift_n) = DecodeImmShift(type, imm5);
12135                shift_n = DecodeImmShiftARM (opcode, shift_t);
12136
12137                break;
12138
12139            default:
12140                return false;
12141        }
12142
12143        // operand2 = if register_form then Shift(R[m], shift_t, shift_n, APSR.C) else imm32;
12144        uint32_t operand2;
12145        if (register_form)
12146        {
12147            uint32_t Rm = ReadCoreReg (m, &success);
12148            if (!success)
12149                return false;
12150
12151            operand2 = Shift (Rm, shift_t, shift_n, APSR_C, &success);
12152            if (!success)
12153                return false;
12154        }
12155        else
12156        {
12157            operand2 = imm32;
12158        }
12159
12160        uint32_t Rn = ReadCoreReg (n, &success);
12161        if (!success)
12162            return false;
12163
12164        AddWithCarryResult result;
12165
12166        // case opcode of
12167        switch (code)
12168        {
12169            case 0: // when �0000�
12170                // result = R[n] AND operand2; // AND
12171                result.result = Rn & operand2;
12172                break;
12173
12174            case 1: // when �0001�
12175                // result = R[n] EOR operand2; // EOR
12176                result.result = Rn ^ operand2;
12177                break;
12178
12179            case 2: // when �0010�
12180                // (result, -, -) = AddWithCarry(R[n], NOT(operand2), �1�); // SUB
12181                result = AddWithCarry (Rn, ~(operand2), 1);
12182                break;
12183
12184            case 3: // when �0011�
12185                // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, �1�); // RSB
12186                result = AddWithCarry (~(Rn), operand2, 1);
12187                break;
12188
12189            case 4: // when �0100�
12190                // (result, -, -) = AddWithCarry(R[n], operand2, �0�); // ADD
12191                result = AddWithCarry (Rn, operand2, 0);
12192                break;
12193
12194            case 5: // when �0101�
12195                // (result, -, -) = AddWithCarry(R[n], operand2, APSR.c); // ADC
12196                result = AddWithCarry (Rn, operand2, APSR_C);
12197                break;
12198
12199            case 6: // when �0110�
12200                // (result, -, -) = AddWithCarry(R[n], NOT(operand2), APSR.C); // SBC
12201                result = AddWithCarry (Rn, ~(operand2), APSR_C);
12202                break;
12203
12204            case 7: // when �0111�
12205                // (result, -, -) = AddWithCarry(NOT(R[n]), operand2, APSR.C); // RSC
12206                result = AddWithCarry (~(Rn), operand2, APSR_C);
12207                break;
12208
12209            case 10: // when �1100�
12210                // result = R[n] OR operand2; // ORR
12211                result.result = Rn | operand2;
12212                break;
12213
12214            case 11: // when �1101�
12215                // result = operand2; // MOV
12216                result.result = operand2;
12217                break;
12218
12219            case 12: // when �1110�
12220                // result = R[n] AND NOT(operand2); // BIC
12221                result.result = Rn & ~(operand2);
12222                break;
12223
12224            case 15: // when �1111�
12225                // result = NOT(operand2); // MVN
12226                result.result = ~(operand2);
12227                break;
12228
12229            default:
12230                return false;
12231        }
12232        // CPSRWriteByInstr(SPSR[], �1111�, TRUE);
12233
12234        // For now, in emulation mode, we don't have access to the SPSR, so we will use the CPSR instead, and hope for
12235        // the best.
12236        uint32_t spsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_cpsr, 0, &success);
12237        if (!success)
12238            return false;
12239
12240        CPSRWriteByInstr (spsr, 15, true);
12241
12242        // BranchWritePC(result);
12243        EmulateInstruction::Context context;
12244        context.type = eContextAdjustPC;
12245        context.SetImmediate (result.result);
12246
12247        BranchWritePC (context, result.result);
12248    }
12249    return true;
12250}
12251
12252EmulateInstructionARM::ARMOpcode*
12253EmulateInstructionARM::GetARMOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12254{
12255    static ARMOpcode
12256    g_arm_opcodes[] =
12257    {
12258        //----------------------------------------------------------------------
12259        // Prologue instructions
12260        //----------------------------------------------------------------------
12261
12262        // push register(s)
12263        { 0x0fff0000, 0x092d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12264        { 0x0fff0fff, 0x052d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push <register>" },
12265
12266        // set r7 to point to a stack offset
12267        { 0x0ffff000, 0x028d7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #<const>" },
12268        { 0x0ffff000, 0x024c7000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBR7IPImm, "sub r7, ip, #<const>"},
12269        // copy the stack pointer to ip
12270        { 0x0fffffff, 0x01a0c00d, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdSP, "mov ip, sp" },
12271        { 0x0ffff000, 0x028dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRdSPImm, "add ip, sp, #<const>" },
12272        { 0x0ffff000, 0x024dc000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBIPSPImm, "sub ip, sp, #<const>"},
12273
12274        // adjust the stack pointer
12275        { 0x0ffff000, 0x024dd000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #<const>"},
12276        { 0x0fef0010, 0x004d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12277
12278        // push one register
12279        // if Rn == '1101' && imm12 == '000000000100' then SEE PUSH;
12280        { 0x0e5f0000, 0x040d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRtSP, "str Rt, [sp, #-imm12]!" },
12281
12282        // vector push consecutive extension register(s)
12283        { 0x0fbf0f00, 0x0d2d0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12284        { 0x0fbf0f00, 0x0d2d0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12285
12286        //----------------------------------------------------------------------
12287        // Epilogue instructions
12288        //----------------------------------------------------------------------
12289
12290        { 0x0fff0000, 0x08bd0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12291        { 0x0fff0fff, 0x049d0004, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop <register>"},
12292        { 0x0fbf0f00, 0x0cbd0b00, ARMV6T2_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12293        { 0x0fbf0f00, 0x0cbd0a00, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12294
12295        //----------------------------------------------------------------------
12296        // Supervisor Call (previously Software Interrupt)
12297        //----------------------------------------------------------------------
12298        { 0x0f000000, 0x0f000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSVC, "svc #imm24"},
12299
12300        //----------------------------------------------------------------------
12301        // Branch instructions
12302        //----------------------------------------------------------------------
12303        { 0x0f000000, 0x0a000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b #imm24"},
12304        // To resolve ambiguity, "blx <label>" should come before "bl <label>".
12305        { 0xfe000000, 0xfa000000, ARMV5_ABOVE,   eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12306        { 0x0f000000, 0x0b000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12307        { 0x0ffffff0, 0x012fff30, ARMV5_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12308        // for example, "bx lr"
12309        { 0x0ffffff0, 0x012fff10, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12310        // bxj
12311        { 0x0ffffff0, 0x012fff20, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12312
12313        //----------------------------------------------------------------------
12314        // Data-processing instructions
12315        //----------------------------------------------------------------------
12316        // adc (immediate)
12317        { 0x0fe00000, 0x02a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #const"},
12318        // adc (register)
12319        { 0x0fe00010, 0x00a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12320        // add (immediate)
12321        { 0x0fe00000, 0x02800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmARM, "add{s}<c> <Rd>, <Rn>, #const"},
12322        // add (register)
12323        { 0x0fe00010, 0x00800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDReg, "add{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12324        // add (register-shifted register)
12325        { 0x0fe00090, 0x00800010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDRegShift, "add{s}<c> <Rd>, <Rn>, <Rm>, <type> <RS>"},
12326        // adr
12327        { 0x0fff0000, 0x028f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12328        { 0x0fff0000, 0x024f0000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12329        // and (immediate)
12330        { 0x0fe00000, 0x02000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #const"},
12331        // and (register)
12332        { 0x0fe00010, 0x00000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12333        // bic (immediate)
12334        { 0x0fe00000, 0x03c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #const"},
12335        // bic (register)
12336        { 0x0fe00010, 0x01c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12337        // eor (immediate)
12338        { 0x0fe00000, 0x02200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #const"},
12339        // eor (register)
12340        { 0x0fe00010, 0x00200000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12341        // orr (immediate)
12342        { 0x0fe00000, 0x03800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #const"},
12343        // orr (register)
12344        { 0x0fe00010, 0x01800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12345        // rsb (immediate)
12346        { 0x0fe00000, 0x02600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c> <Rd>, <Rn>, #<const>"},
12347        // rsb (register)
12348        { 0x0fe00010, 0x00600000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12349        // rsc (immediate)
12350        { 0x0fe00000, 0x02e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCImm, "rsc{s}<c> <Rd>, <Rn>, #<const>"},
12351        // rsc (register)
12352        { 0x0fe00010, 0x00e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSCReg, "rsc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12353        // sbc (immediate)
12354        { 0x0fe00000, 0x02c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12355        // sbc (register)
12356        { 0x0fe00010, 0x00c00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c> <Rd>, <Rn>, <Rm> {,<shift>}"},
12357        // sub (immediate, ARM)
12358        { 0x0fe00000, 0x02400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmARM, "sub{s}<c> <Rd>, <Rn>, #<const>"},
12359        // sub (sp minus immediate)
12360        { 0x0fef0000, 0x024d0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}<c> <Rd>, sp, #<const>"},
12361        // sub (register)
12362        { 0x0fe00010, 0x00400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c> <Rd>, <Rn>, <Rm>{,<shift>}"},
12363        // teq (immediate)
12364        { 0x0ff0f000, 0x03300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #const"},
12365        // teq (register)
12366        { 0x0ff0f010, 0x01300000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12367        // tst (immediate)
12368        { 0x0ff0f000, 0x03100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #const"},
12369        // tst (register)
12370        { 0x0ff0f010, 0x01100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rn>, <Rm> {,<shift>}"},
12371
12372        // mov (immediate)
12373        { 0x0fef0000, 0x03a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c> <Rd>, #<const>"},
12374        { 0x0ff00000, 0x03000000, ARMV6T2_ABOVE, eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>, #<imm16>" },
12375        // mov (register)
12376        { 0x0fef0ff0, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c> <Rd>, <Rm>"},
12377        // mvn (immediate)
12378        { 0x0fef0000, 0x03e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s}<c> <Rd>, #<const>"},
12379        // mvn (register)
12380        { 0x0fef0010, 0x01e00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c> <Rd>, <Rm> {,<shift>}"},
12381        // cmn (immediate)
12382        { 0x0ff0f000, 0x03700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12383        // cmn (register)
12384        { 0x0ff0f010, 0x01700000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12385        // cmp (immediate)
12386        { 0x0ff0f000, 0x03500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #<const>"},
12387        // cmp (register)
12388        { 0x0ff0f010, 0x01500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm> {,<shift>}"},
12389        // asr (immediate)
12390        { 0x0fef0070, 0x01a00040, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c> <Rd>, <Rm>, #imm"},
12391        // asr (register)
12392        { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c> <Rd>, <Rn>, <Rm>"},
12393        // lsl (immediate)
12394        { 0x0fef0070, 0x01a00000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c> <Rd>, <Rm>, #imm"},
12395        // lsl (register)
12396        { 0x0fef00f0, 0x01a00010, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c> <Rd>, <Rn>, <Rm>"},
12397        // lsr (immediate)
12398        { 0x0fef0070, 0x01a00020, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c> <Rd>, <Rm>, #imm"},
12399        // lsr (register)
12400        { 0x0fef00f0, 0x01a00050, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c> <Rd>, <Rn>, <Rm>"},
12401        // rrx is a special case encoding of ror (immediate)
12402        { 0x0fef0ff0, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c> <Rd>, <Rm>"},
12403        // ror (immediate)
12404        { 0x0fef0070, 0x01a00060, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c> <Rd>, <Rm>, #imm"},
12405        // ror (register)
12406        { 0x0fef00f0, 0x01a00070, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c> <Rd>, <Rn>, <Rm>"},
12407        // mul
12408        { 0x0fe000f0, 0x00000090, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul{s}<c> <Rd>,<R>,<Rm>" },
12409
12410        // subs pc, lr and related instructions
12411        { 0x0e10f000, 0x0210f000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,#<const> | <Rn>,#<const>" },
12412        { 0x0e10f010, 0x0010f000, ARMvAll,       eEncodingA2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "<opc>S<c> PC,<Rn>,<Rm{,<shift>}" },
12413
12414        //----------------------------------------------------------------------
12415        // Load instructions
12416        //----------------------------------------------------------------------
12417        { 0x0fd00000, 0x08900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12418        { 0x0fd00000, 0x08100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDA, "ldmda<c> <Rn>{!} <registers>" },
12419        { 0x0fd00000, 0x09100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12420        { 0x0fd00000, 0x09900000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMIB, "ldmib<c> <Rn<{!} <registers>" },
12421        { 0x0e500000, 0x04100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRImmediateARM, "ldr<c> <Rt> [<Rn> {#+/-<imm12>}]" },
12422        { 0x0e500010, 0x06100000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt> [<Rn> +/-<Rm> {<shift>}] {!}" },
12423        { 0x0e5f0000, 0x045f0000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>, [...]"},
12424        { 0xfe500010, 0x06500000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>, [<Rn>,+/-<Rm>{, <shift>}]{!}" },
12425        { 0x0e5f00f0, 0x005f00b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12426        { 0x0e5000f0, 0x001000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>,[<Rn>,+/-<Rm>]{!}"  },
12427        { 0x0e5000f0, 0x005000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>, [<Rn>{,#+/-<imm8>}]" },
12428        { 0x0e5f00f0, 0x005f00d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt> <label>" },
12429        { 0x0e5000f0, 0x001000d0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12430        { 0x0e5000f0, 0x005000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>{,#+/-<imm8>}]"},
12431        { 0x0e5f00f0, 0x005f00f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12432        { 0x0e5000f0, 0x001000f0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,+/-<Rm>]{!}" },
12433        { 0x0e5000f0, 0x004000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm8>]!"},
12434        { 0x0e500ff0, 0x000000d0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDRegister, "ldrd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12435        { 0x0e100f00, 0x0c100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12436        { 0x0e100f00, 0x0c100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12437        { 0x0f300f00, 0x0d100b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12438        { 0x0f300f00, 0x0d100a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12439        { 0xffb00000, 0xf4200000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12440        { 0xffb00300, 0xf4a00000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12441        { 0xffb00f00, 0xf4a00c00, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12442
12443        //----------------------------------------------------------------------
12444        // Store instructions
12445        //----------------------------------------------------------------------
12446        { 0x0fd00000, 0x08800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12447        { 0x0fd00000, 0x08000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDA, "stmda<c> <Rn>{!} <registers>" },
12448        { 0x0fd00000, 0x09000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12449        { 0x0fd00000, 0x09800000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMIB, "stmib<c> <Rn>{!} <registers>" },
12450        { 0x0e500010, 0x06000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> [<Rn> +/-<Rm> {<shift>}]{!}" },
12451        { 0x0e5000f0, 0x000000b0, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,+/-<Rm>[{!}" },
12452        { 0x0ff00ff0, 0x01800f90, ARMV6_ABOVE,   eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn>]"},
12453        { 0x0e500000, 0x04400000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBImmARM, "strb<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12454        { 0x0e500000, 0x04000000, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRImmARM, "str<c> <Rt>,[<Rn>,#+/-<imm12>]!"},
12455        { 0x0e5000f0, 0x004000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn> #+/-<imm8>]!"},
12456        { 0x0e500ff0, 0x000000f0, ARMV5TE_ABOVE, eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDReg, "strd<c> <Rt>, <Rt2>, [<Rn>, +/-<Rm>]{!}"},
12457        { 0x0e100f00, 0x0c000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12458        { 0x0e100f00, 0x0c000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!} <list>"},
12459        { 0x0f300f00, 0x0d000b00, ARMvAll,       eEncodingA1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd> [<Rn>{,#+/-<imm>}]"},
12460        { 0x0f300f00, 0x0d000a00, ARMvAll,       eEncodingA2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd> [<Rn>{,#+/-<imm>}]"},
12461        { 0xffb00000, 0xf4000000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12462        { 0xffb00300, 0xf4800000, ARMvAll,       eEncodingA1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12463
12464        //----------------------------------------------------------------------
12465        // Other instructions
12466        //----------------------------------------------------------------------
12467        { 0x0fff00f0, 0x06af00f0, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>{,<rotation>}" },
12468        { 0x0fff00f0, 0x06bf0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>{,<rotation>}" },
12469        { 0x0fff00f0, 0x06ef0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>{,<rotation>}" },
12470        { 0x0fff00f0, 0x06ff0070, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>{,<rotation>}" },
12471        { 0xfe500000, 0xf8100000, ARMV6_ABOVE,  eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{<amode>} <Rn>{!}" }
12472
12473    };
12474    static const size_t k_num_arm_opcodes = sizeof(g_arm_opcodes)/sizeof(ARMOpcode);
12475
12476    for (size_t i=0; i<k_num_arm_opcodes; ++i)
12477    {
12478        if ((g_arm_opcodes[i].mask & opcode) == g_arm_opcodes[i].value &&
12479            (g_arm_opcodes[i].variants & arm_isa) != 0)
12480            return &g_arm_opcodes[i];
12481    }
12482    return NULL;
12483}
12484
12485
12486EmulateInstructionARM::ARMOpcode*
12487EmulateInstructionARM::GetThumbOpcodeForInstruction (const uint32_t opcode, uint32_t arm_isa)
12488{
12489
12490    static ARMOpcode
12491    g_thumb_opcodes[] =
12492    {
12493        //----------------------------------------------------------------------
12494        // Prologue instructions
12495        //----------------------------------------------------------------------
12496
12497        // push register(s)
12498        { 0xfffffe00, 0x0000b400, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePUSH, "push <registers>" },
12499        { 0xffff0000, 0xe92d0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <registers>" },
12500        { 0xffff0fff, 0xf84d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePUSH, "push.w <register>" },
12501
12502        // set r7 to point to a stack offset
12503        { 0xffffff00, 0x0000af00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDRdSPImm, "add r7, sp, #imm" },
12504        // copy the stack pointer to r7
12505        { 0xffffffff, 0x0000466f, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdSP, "mov r7, sp" },
12506        // move from high register to low register (comes after "mov r7, sp" to resolve ambiguity)
12507        { 0xffffffc0, 0x00004640, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVLowHigh, "mov r0-r7, r8-r15" },
12508
12509        // PC-relative load into register (see also EmulateADDSPRm)
12510        { 0xfffff800, 0x00004800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr <Rt>, [PC, #imm]"},
12511
12512        // adjust the stack pointer
12513        { 0xffffff87, 0x00004485, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPRm, "add sp, <Rm>"},
12514        { 0xffffff80, 0x0000b080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBSPImm, "sub sp, sp, #imm"},
12515        { 0xfbef8f00, 0xf1ad0d00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub.w sp, sp, #<const>"},
12516        { 0xfbff8f00, 0xf2ad0d00, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw sp, sp, #imm12"},
12517        { 0xffef8000, 0xebad0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPReg, "sub{s}<c> <Rd>, sp, <Rm>{,<shift>}" },
12518
12519        // vector push consecutive extension register(s)
12520        { 0xffbf0f00, 0xed2d0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.64 <list>"},
12521        { 0xffbf0f00, 0xed2d0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPUSH, "vpush.32 <list>"},
12522
12523        //----------------------------------------------------------------------
12524        // Epilogue instructions
12525        //----------------------------------------------------------------------
12526
12527        { 0xfffff800, 0x0000a800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add<c> <Rd>, sp, #imm"},
12528        { 0xffffff80, 0x0000b000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDSPImm, "add sp, #imm"},
12529        { 0xfffffe00, 0x0000bc00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulatePOP, "pop <registers>"},
12530        { 0xffff0000, 0xe8bd0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <registers>" },
12531        { 0xffff0fff, 0xf85d0d04, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulatePOP, "pop.w <register>" },
12532        { 0xffbf0f00, 0xecbd0b00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.64 <list>"},
12533        { 0xffbf0f00, 0xecbd0a00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateVPOP, "vpop.32 <list>"},
12534
12535        //----------------------------------------------------------------------
12536        // Supervisor Call (previously Software Interrupt)
12537        //----------------------------------------------------------------------
12538        { 0xffffff00, 0x0000df00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSVC, "svc #imm8"},
12539
12540        //----------------------------------------------------------------------
12541        // If Then makes up to four following instructions conditional.
12542        //----------------------------------------------------------------------
12543        // The next 5 opcode _must_ come before the if then instruction
12544        { 0xffffffff, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop"},
12545        { 0xffffffff, 0x0000bf10, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop YIELD (yield hint)"},
12546        { 0xffffffff, 0x0000bf20, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFE (wait for event hint)"},
12547        { 0xffffffff, 0x0000bf30, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop WFI (wait for interrupt hint)"},
12548        { 0xffffffff, 0x0000bf40, ARMV7_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateNop, "nop SEV (send event hint)"},
12549        { 0xffffff00, 0x0000bf00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateIT, "it{<x>{<y>{<z>}}} <firstcond>"},
12550
12551        //----------------------------------------------------------------------
12552        // Branch instructions
12553        //----------------------------------------------------------------------
12554        // To resolve ambiguity, "b<c> #imm8" should come after "svc #imm8".
12555        { 0xfffff000, 0x0000d000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm8 (outside IT)"},
12556        { 0xfffff800, 0x0000e000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateB, "b<c> #imm11 (outside or last in IT)"},
12557        { 0xf800d000, 0xf0008000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside IT)"},
12558        { 0xf800d000, 0xf0009000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateB, "b<c>.w #imm8 (outside or last in IT)"},
12559        // J1 == J2 == 1
12560        { 0xf800d000, 0xf000d000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "bl <label>"},
12561        // J1 == J2 == 1
12562        { 0xf800d001, 0xf000c000, ARMV5_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBLXImmediate, "blx <label>"},
12563        { 0xffffff87, 0x00004780, ARMV5_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBLXRm, "blx <Rm>"},
12564        // for example, "bx lr"
12565        { 0xffffff87, 0x00004700, ARMvAll,       eEncodingA1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXRm, "bx <Rm>"},
12566        // bxj
12567        { 0xfff0ffff, 0xf3c08f00, ARMV5J_ABOVE,  eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBXJRm, "bxj <Rm>"},
12568        // compare and branch
12569        { 0xfffff500, 0x0000b100, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCB, "cb{n}z <Rn>, <label>"},
12570        // table branch byte
12571        { 0xfff0fff0, 0xe8d0f000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbb<c> <Rn>, <Rm>"},
12572        // table branch halfword
12573        { 0xfff0fff0, 0xe8d0f010, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTB, "tbh<c> <Rn>, <Rm>, lsl #1"},
12574
12575        //----------------------------------------------------------------------
12576        // Data-processing instructions
12577        //----------------------------------------------------------------------
12578        // adc (immediate)
12579        { 0xfbe08000, 0xf1400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCImm, "adc{s}<c> <Rd>, <Rn>, #<const>"},
12580        // adc (register)
12581        { 0xffffffc0, 0x00004140, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADCReg, "adcs|adc<c> <Rdn>, <Rm>"},
12582        { 0xffe08000, 0xeb400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADCReg, "adc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12583        // add (register)
12584        { 0xfffffe00, 0x00001800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "adds|add<c> <Rd>, <Rn>, <Rm>"},
12585        // Make sure "add sp, <Rm>" comes before this instruction, so there's no ambiguity decoding the two.
12586        { 0xffffff00, 0x00004400, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDReg, "add<c> <Rdn>, <Rm>"},
12587        // adr
12588        { 0xfffff800, 0x0000a000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12589        { 0xfbff8000, 0xf2af0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "sub<c> <Rd>, PC, #<const>"},
12590        { 0xfbff8000, 0xf20f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADR, "add<c> <Rd>, PC, #<const>"},
12591        // and (immediate)
12592        { 0xfbe08000, 0xf0000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDImm, "and{s}<c> <Rd>, <Rn>, #<const>"},
12593        // and (register)
12594        { 0xffffffc0, 0x00004000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateANDReg, "ands|and<c> <Rdn>, <Rm>"},
12595        { 0xffe08000, 0xea000000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateANDReg, "and{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12596        // bic (immediate)
12597        { 0xfbe08000, 0xf0200000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICImm, "bic{s}<c> <Rd>, <Rn>, #<const>"},
12598        // bic (register)
12599        { 0xffffffc0, 0x00004380, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateBICReg, "bics|bic<c> <Rdn>, <Rm>"},
12600        { 0xffe08000, 0xea200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateBICReg, "bic{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12601        // eor (immediate)
12602        { 0xfbe08000, 0xf0800000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORImm, "eor{s}<c> <Rd>, <Rn>, #<const>"},
12603        // eor (register)
12604        { 0xffffffc0, 0x00004040, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateEORReg, "eors|eor<c> <Rdn>, <Rm>"},
12605        { 0xffe08000, 0xea800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateEORReg, "eor{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12606        // orr (immediate)
12607        { 0xfbe08000, 0xf0400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRImm, "orr{s}<c> <Rd>, <Rn>, #<const>"},
12608        // orr (register)
12609        { 0xffffffc0, 0x00004300, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateORRReg, "orrs|orr<c> <Rdn>, <Rm>"},
12610        { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateORRReg, "orr{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12611        // rsb (immediate)
12612        { 0xffffffc0, 0x00004240, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRSBImm, "rsbs|rsb<c> <Rd>, <Rn>, #0"},
12613        { 0xfbe08000, 0xf1c00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBImm, "rsb{s}<c>.w <Rd>, <Rn>, #<const>"},
12614        // rsb (register)
12615        { 0xffe08000, 0xea400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRSBReg, "rsb{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12616        // sbc (immediate)
12617        { 0xfbe08000, 0xf1600000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCImm, "sbc{s}<c> <Rd>, <Rn>, #<const>"},
12618        // sbc (register)
12619        { 0xffffffc0, 0x00004180, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSBCReg, "sbcs|sbc<c> <Rdn>, <Rm>"},
12620        { 0xffe08000, 0xeb600000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSBCReg, "sbc{s}<c>.w <Rd>, <Rn>, <Rm> {,<shift>}"},
12621        // add (immediate, Thumb)
12622        { 0xfffffe00, 0x00001c00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rd>,<Rn>,#<imm3>" },
12623        { 0xfffff800, 0x00003000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateADDImmThumb, "adds|add<c> <Rdn>,#<imm8>" },
12624        { 0xfbe08000, 0xf1000000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "add{s}<c>.w <Rd>,<Rn>,#<const>" },
12625        { 0xfbf08000, 0xf2000000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateADDImmThumb, "addw<c> <Rd>,<Rn>,#<imm12>" },
12626        // sub (immediate, Thumb)
12627        { 0xfffffe00, 0x00001e00, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rd>, <Rn> #imm3"},
12628        { 0xfffff800, 0x00003800, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBImmThumb, "subs|sub<c> <Rdn>, #imm8"},
12629        { 0xfbe08000, 0xf1a00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "sub{s}<c>.w <Rd>, <Rn>, #<const>"},
12630        { 0xfbf08000, 0xf2a00000, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBImmThumb, "subw<c> <Rd>, <Rn>, #imm12"},
12631        // sub (sp minus immediate)
12632        { 0xfbef8000, 0xf1ad0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "sub{s}.w <Rd>, sp, #<const>"},
12633        { 0xfbff8000, 0xf2ad0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPImm, "subw<c> <Rd>, sp, #imm12"},
12634        // sub (register)
12635        { 0xfffffe00, 0x00001a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSUBReg, "subs|sub<c> <Rd>, <Rn>, <Rm>"},
12636        { 0xffe08000, 0xeba00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBReg, "sub{s}<c>.w <Rd>, <Rn>, <Rm>{,<shift>}"},
12637        // teq (immediate)
12638        { 0xfbf08f00, 0xf0900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQImm, "teq<c> <Rn>, #<const>"},
12639        // teq (register)
12640        { 0xfff08f00, 0xea900f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTEQReg, "teq<c> <Rn>, <Rm> {,<shift>}"},
12641        // tst (immediate)
12642        { 0xfbf08f00, 0xf0100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTImm, "tst<c> <Rn>, #<const>"},
12643        // tst (register)
12644        { 0xffffffc0, 0x00004200, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateTSTReg, "tst<c> <Rdn>, <Rm>"},
12645        { 0xfff08f00, 0xea100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateTSTReg, "tst<c>.w <Rn>, <Rm> {,<shift>}"},
12646
12647
12648        // move from high register to high register
12649        { 0xffffff00, 0x00004600, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "mov<c> <Rd>, <Rm>"},
12650        // move from low register to low register
12651        { 0xffffffc0, 0x00000000, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdRm, "movs <Rd>, <Rm>"},
12652        // mov{s}<c>.w <Rd>, <Rm>
12653        { 0xffeff0f0, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdRm, "mov{s}<c>.w <Rd>, <Rm>"},
12654        // move immediate
12655        { 0xfffff800, 0x00002000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMOVRdImm, "movs|mov<c> <Rd>, #imm8"},
12656        { 0xfbef8000, 0xf04f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "mov{s}<c>.w <Rd>, #<const>"},
12657        { 0xfbf08000, 0xf2400000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateMOVRdImm, "movw<c> <Rd>,#<imm16>"},
12658        // mvn (immediate)
12659        { 0xfbef8000, 0xf06f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNImm, "mvn{s} <Rd>, #<const>"},
12660        // mvn (register)
12661        { 0xffffffc0, 0x000043c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMVNReg, "mvns|mvn<c> <Rd>, <Rm>"},
12662        { 0xffef8000, 0xea6f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMVNReg, "mvn{s}<c>.w <Rd>, <Rm> {,<shift>}"},
12663        // cmn (immediate)
12664        { 0xfbf08f00, 0xf1100f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNImm, "cmn<c> <Rn>, #<const>"},
12665        // cmn (register)
12666        { 0xffffffc0, 0x000042c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm>"},
12667        { 0xfff08f00, 0xeb100f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMNReg, "cmn<c> <Rn>, <Rm> {,<shift>}"},
12668        // cmp (immediate)
12669        { 0xfffff800, 0x00002800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPImm, "cmp<c> <Rn>, #imm8"},
12670        { 0xfbf08f00, 0xf1b00f00, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateCMPImm, "cmp<c>.w <Rn>, #<const>"},
12671        // cmp (register) (Rn and Rm both from r0-r7)
12672        { 0xffffffc0, 0x00004280, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12673        // cmp (register) (Rn and Rm not both from r0-r7)
12674        { 0xffffff00, 0x00004500, ARMvAll,       eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateCMPReg, "cmp<c> <Rn>, <Rm>"},
12675        // asr (immediate)
12676        { 0xfffff800, 0x00001000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRImm, "asrs|asr<c> <Rd>, <Rm>, #imm"},
12677        { 0xffef8030, 0xea4f0020, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRImm, "asr{s}<c>.w <Rd>, <Rm>, #imm"},
12678        // asr (register)
12679        { 0xffffffc0, 0x00004100, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateASRReg, "asrs|asr<c> <Rdn>, <Rm>"},
12680        { 0xffe0f0f0, 0xfa40f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateASRReg, "asr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12681        // lsl (immediate)
12682        { 0xfffff800, 0x00000000, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLImm, "lsls|lsl<c> <Rd>, <Rm>, #imm"},
12683        { 0xffef8030, 0xea4f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLImm, "lsl{s}<c>.w <Rd>, <Rm>, #imm"},
12684        // lsl (register)
12685        { 0xffffffc0, 0x00004080, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSLReg, "lsls|lsl<c> <Rdn>, <Rm>"},
12686        { 0xffe0f0f0, 0xfa00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSLReg, "lsl{s}<c>.w <Rd>, <Rn>, <Rm>"},
12687        // lsr (immediate)
12688        { 0xfffff800, 0x00000800, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRImm, "lsrs|lsr<c> <Rd>, <Rm>, #imm"},
12689        { 0xffef8030, 0xea4f0010, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRImm, "lsr{s}<c>.w <Rd>, <Rm>, #imm"},
12690        // lsr (register)
12691        { 0xffffffc0, 0x000040c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLSRReg, "lsrs|lsr<c> <Rdn>, <Rm>"},
12692        { 0xffe0f0f0, 0xfa20f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLSRReg, "lsr{s}<c>.w <Rd>, <Rn>, <Rm>"},
12693        // rrx is a special case encoding of ror (immediate)
12694        { 0xffeff0f0, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRRX, "rrx{s}<c>.w <Rd>, <Rm>"},
12695        // ror (immediate)
12696        { 0xffef8030, 0xea4f0030, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORImm, "ror{s}<c>.w <Rd>, <Rm>, #imm"},
12697        // ror (register)
12698        { 0xffffffc0, 0x000041c0, ARMvAll,       eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateRORReg, "rors|ror<c> <Rdn>, <Rm>"},
12699        { 0xffe0f0f0, 0xfa60f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRORReg, "ror{s}<c>.w <Rd>, <Rn>, <Rm>"},
12700        // mul
12701        { 0xffffffc0, 0x00004340, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateMUL, "muls <Rdm>,<Rn>,<Rdm>" },
12702        // mul
12703        { 0xfff0f0f0, 0xfb00f000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateMUL, "mul<c> <Rd>,<Rn>,<Rm>" },
12704
12705        // subs pc, lr and related instructions
12706        { 0xffffff00, 0xf3de8f00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSUBSPcLrEtc, "SUBS<c> PC, LR, #<imm8>" },
12707
12708        //----------------------------------------------------------------------
12709        // RFE instructions  *** IMPORTANT *** THESE MUST BE LISTED **BEFORE** THE LDM.. Instructions in this table;
12710        // otherwise the wrong instructions will be selected.
12711        //----------------------------------------------------------------------
12712
12713        { 0xffd0ffff, 0xe810c000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfedb<c> <Rn>{!}" },
12714        { 0xffd0ffff, 0xe990c000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateRFE, "rfe{ia}<c> <Rn>{!}" },
12715
12716        //----------------------------------------------------------------------
12717        // Load instructions
12718        //----------------------------------------------------------------------
12719        { 0xfffff800, 0x0000c800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDM, "ldm<c> <Rn>{!} <registers>" },
12720        { 0xffd02000, 0xe8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDM, "ldm<c>.w <Rn>{!} <registers>" },
12721        { 0xffd00000, 0xe9100000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDMDB, "ldmdb<c> <Rn>{!} <registers>" },
12722        { 0xfffff800, 0x00006800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#imm}]"},
12723        { 0xfffff800, 0x00009800, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [SP{,#imm}]"},
12724        { 0xfff00000, 0xf8d00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c>.w <Rt>, [<Rn>{,#imm12}]"},
12725        { 0xfff00800, 0xf8500800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtRnImm, "ldr<c> <Rt>, [<Rn>{,#+/-<imm8>}]{!}"},
12726                  // Thumb2 PC-relative load into register
12727        { 0xff7f0000, 0xf85f0000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRtPCRelative, "ldr<c>.w <Rt>, [PC, +/-#imm}]"},
12728        { 0xfffffe00, 0x00005800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c> <Rt>, [<Rn>, <Rm>]" },
12729        { 0xfff00fc0, 0xf8500000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRRegister, "ldr<c>.w <Rt>, [<Rn>,<Rm>{,LSL #<imm2>}]" },
12730        { 0xfffff800, 0x00007800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>{,#<imm5>}]" },
12731        { 0xfff00000, 0xf8900000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12732        { 0xfff00800, 0xf8100800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBImmediate, "ldrb<c> <Rt>,[<Rn>, #+/-<imm8>]{!}" },
12733        { 0xff7f0000, 0xf81f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBLiteral, "ldrb<c> <Rt>,[...]" },
12734        { 0xfffffe00, 0x00005c00, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c> <Rt>,[<Rn>,<Rm>]" },
12735        { 0xfff00fc0, 0xf8100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRBRegister, "ldrb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]" },
12736        { 0xfffff800, 0x00008800, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>, [<Rn>{,#<imm>}]"  },
12737        { 0xfff00000, 0xf8b00000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c>.w <Rt>,[<Rn>{,#<imm12>}]" },
12738        { 0xfff00800, 0xf8300800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHImmediate, "ldrh<c> <Rt>,[<Rn>,#+/-<imm8>]{!}"  },
12739        { 0xff7f0000, 0xf83f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHLiteral, "ldrh<c> <Rt>, <label>" },
12740        { 0xfffffe00, 0x00005a00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c> <Rt>, [<Rn>,<Rm>]" },
12741        { 0xfff00fc0, 0xf8300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRHRegister, "ldrh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12742        { 0xfff00000, 0xf9900000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#<imm12>]" },
12743        { 0xfff00800, 0xf9100800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBImmediate, "ldrsb<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12744        { 0xff7f0000, 0xf91f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBLiteral, "ldrsb<c> <Rt>, <label>" },
12745        { 0xfffffe00, 0x00005600, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c> <Rt>,[<Rn>,<Rm>]" },
12746        { 0xfff00fc0, 0xf9100000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSBRegister, "ldrsb<c>.w <Rt>,[<Rn>,<Rm>{,LSL #imm2>}]"  },
12747        { 0xfff00000, 0xf9b00000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#<imm12>]" },
12748        { 0xfff00800, 0xf9300800, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHImmediate, "ldrsh<c> <Rt>,[<Rn>,#+/-<imm8>]" },
12749        { 0xff7f0000, 0xf93f0000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHLiteral, "ldrsh<c> <Rt>,<label>" },
12750        { 0xfffffe00, 0x00005e00, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c> <Rt>,[<Rn>,<Rm>]" },
12751        { 0xfff00fc0, 0xf9300000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRSHRegister, "ldrsh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12752        { 0xfe500000, 0xe8500000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateLDRDImmediate, "ldrd<c> <Rt>, <Rt2>, [<Rn>,#+/-<imm>]!"},
12753        { 0xfe100f00, 0xec100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>"},
12754        { 0xfe100f00, 0xec100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDM, "vldm{mode}<c> <Rn>{!}, <list>" },
12755        { 0xffe00f00, 0xed100b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12756        { 0xff300f00, 0xed100a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVLDR, "vldr<c> <Sd>, {<Rn>{,#+/-<imm>}]"},
12757        { 0xffb00000, 0xf9200000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Multiple, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12758        { 0xffb00300, 0xf9a00000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1Single, "vld1<c>.<size> <list>, [<Rn>{@<align>}],<Rm>"},
12759        { 0xffb00f00, 0xf9a00c00, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVLD1SingleAll, "vld1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12760
12761        //----------------------------------------------------------------------
12762        // Store instructions
12763        //----------------------------------------------------------------------
12764        { 0xfffff800, 0x0000c000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTM, "stm<c> <Rn>{!} <registers>" },
12765        { 0xffd00000, 0xe8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTM, "stm<c>.w <Rn>{!} <registers>" },
12766        { 0xffd00000, 0xe9000000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTMDB, "stmdb<c> <Rn>{!} <registers>" },
12767        { 0xfffff800, 0x00006000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>{,#<imm>}]" },
12768        { 0xfffff800, 0x00009000, ARMV4T_ABOVE,  eEncodingT2, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [SP,#<imm>]" },
12769        { 0xfff00000, 0xf8c00000, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c>.w <Rt>, [<Rn>,#<imm12>]" },
12770        { 0xfff00800, 0xf8400800, ARMV6T2_ABOVE, eEncodingT4, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRThumb, "str<c> <Rt>, [<Rn>,#+/-<imm8>]" },
12771        { 0xfffffe00, 0x00005000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRRegister, "str<c> <Rt> ,{<Rn>, <Rm>]" },
12772        { 0xfff00fc0, 0xf8400000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRRegister, "str<c>.w <Rt>, [<Rn>, <Rm> {lsl #imm2>}]" },
12773        { 0xfffff800, 0x00007000, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt>, [<Rn>, #<imm5>]" },
12774        { 0xfff00000, 0xf8800000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c>.w <Rt>, [<Rn>, #<imm12>]" },
12775        { 0xfff00800, 0xf8000800, ARMV6T2_ABOVE, eEncodingT3, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRBThumb, "strb<c> <Rt> ,[<Rn>, #+/-<imm8>]{!}" },
12776        { 0xfffffe00, 0x00005200, ARMV4T_ABOVE,  eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c> <Rt>,[<Rn>,<Rm>]" },
12777        { 0xfff00fc0, 0xf8200000, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRHRegister, "strh<c>.w <Rt>,[<Rn>,<Rm>{,LSL #<imm2>}]" },
12778        { 0xfff00000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTREX, "strex<c> <Rd>, <Rt>, [<Rn{,#<imm>}]" },
12779        { 0xfe500000, 0xe8400000, ARMV6T2_ABOVE, eEncodingT1, No_VFP, eSize32, &EmulateInstructionARM::EmulateSTRDImm, "strd<c> <Rt>, <Rt2>, [<Rn>, #+/-<imm>]!"},
12780        { 0xfe100f00, 0xec000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12781        { 0xfea00f00, 0xec000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTM, "vstm{mode}<c> <Rn>{!}, <list>"},
12782        { 0xff300f00, 0xed000b00, ARMvAll,       eEncodingT1, VFPv2_ABOVE,  eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Dd>, [<Rn>{,#+/-<imm>}]"},
12783        { 0xff300f00, 0xed000a00, ARMvAll,       eEncodingT2, VFPv2v3,      eSize32, &EmulateInstructionARM::EmulateVSTR, "vstr<c> <Sd>, [<Rn>{,#+/-<imm>}]"},
12784        { 0xffb00000, 0xf9000000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Multiple, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12785        { 0xffb00300, 0xf9800000, ARMvAll,       eEncodingT1, AdvancedSIMD, eSize32, &EmulateInstructionARM::EmulateVST1Single, "vst1<c>.<size> <list>, [<Rn>{@<align>}], <Rm>"},
12786
12787        //----------------------------------------------------------------------
12788        // Other instructions
12789        //----------------------------------------------------------------------
12790        { 0xffffffc0, 0x0000b240, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTB, "sxtb<c> <Rd>,<Rm>" },
12791        { 0xfffff080, 0xfa4ff080, ARMV6_ABOVE,   eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTB, "sxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12792        { 0xffffffc0, 0x0000b200, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateSXTH, "sxth<c> <Rd>,<Rm>" },
12793        { 0xfffff080, 0xfa0ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateSXTH, "sxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12794        { 0xffffffc0, 0x0000b2c0, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTB, "uxtb<c> <Rd>,<Rm>" },
12795        { 0xfffff080, 0xfa5ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTB, "uxtb<c>.w <Rd>,<Rm>{,<rotation>}" },
12796        { 0xffffffc0, 0x0000b280, ARMV6_ABOVE,   eEncodingT1, No_VFP, eSize16, &EmulateInstructionARM::EmulateUXTH, "uxth<c> <Rd>,<Rm>" },
12797        { 0xfffff080, 0xfa1ff080, ARMV6T2_ABOVE, eEncodingT2, No_VFP, eSize32, &EmulateInstructionARM::EmulateUXTH, "uxth<c>.w <Rd>,<Rm>{,<rotation>}" },
12798    };
12799
12800    const size_t k_num_thumb_opcodes = sizeof(g_thumb_opcodes)/sizeof(ARMOpcode);
12801    for (size_t i=0; i<k_num_thumb_opcodes; ++i)
12802    {
12803        if ((g_thumb_opcodes[i].mask & opcode) == g_thumb_opcodes[i].value &&
12804            (g_thumb_opcodes[i].variants & arm_isa) != 0)
12805            return &g_thumb_opcodes[i];
12806    }
12807    return NULL;
12808}
12809
12810bool
12811EmulateInstructionARM::SetArchitecture (const ArchSpec &arch)
12812{
12813    m_arch = arch;
12814    m_arm_isa = 0;
12815    const char *arch_cstr = arch.GetArchitectureName ();
12816    if (arch_cstr)
12817    {
12818        if      (0 == ::strcasecmp(arch_cstr, "armv4t"))    m_arm_isa = ARMv4T;
12819        else if (0 == ::strcasecmp(arch_cstr, "armv5tej"))  m_arm_isa = ARMv5TEJ;
12820        else if (0 == ::strcasecmp(arch_cstr, "armv5te"))   m_arm_isa = ARMv5TE;
12821        else if (0 == ::strcasecmp(arch_cstr, "armv5t"))    m_arm_isa = ARMv5T;
12822        else if (0 == ::strcasecmp(arch_cstr, "armv6k"))    m_arm_isa = ARMv6K;
12823        else if (0 == ::strcasecmp(arch_cstr, "armv6t2"))   m_arm_isa = ARMv6T2;
12824        else if (0 == ::strcasecmp(arch_cstr, "armv7s"))    m_arm_isa = ARMv7S;
12825        else if (0 == ::strcasecmp(arch_cstr, "arm"))       m_arm_isa = ARMvAll;
12826        else if (0 == ::strcasecmp(arch_cstr, "thumb"))     m_arm_isa = ARMvAll;
12827        else if (0 == ::strncasecmp(arch_cstr,"armv4", 5))  m_arm_isa = ARMv4;
12828        else if (0 == ::strncasecmp(arch_cstr,"armv6", 5))  m_arm_isa = ARMv6;
12829        else if (0 == ::strncasecmp(arch_cstr,"armv7", 5))  m_arm_isa = ARMv7;
12830        else if (0 == ::strncasecmp(arch_cstr,"armv8", 5))  m_arm_isa = ARMv8;
12831    }
12832    return m_arm_isa != 0;
12833}
12834
12835bool
12836EmulateInstructionARM::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target)
12837{
12838    if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target))
12839    {
12840        if (m_arch.GetTriple().getArch() == llvm::Triple::thumb)
12841            m_opcode_mode = eModeThumb;
12842        else
12843        {
12844            AddressClass addr_class = inst_addr.GetAddressClass();
12845
12846            if ((addr_class == eAddressClassCode) || (addr_class == eAddressClassUnknown))
12847                m_opcode_mode = eModeARM;
12848            else if (addr_class == eAddressClassCodeAlternateISA)
12849                m_opcode_mode = eModeThumb;
12850            else
12851                return false;
12852        }
12853        if (m_opcode_mode == eModeThumb)
12854            m_opcode_cpsr = CPSR_MODE_USR | MASK_CPSR_T;
12855        else
12856            m_opcode_cpsr = CPSR_MODE_USR;
12857        return true;
12858    }
12859    return false;
12860}
12861
12862bool
12863EmulateInstructionARM::ReadInstruction ()
12864{
12865    bool success = false;
12866    m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, 0, &success);
12867    if (success)
12868    {
12869        addr_t pc = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success);
12870        if (success)
12871        {
12872            Context read_inst_context;
12873            read_inst_context.type = eContextReadOpcode;
12874            read_inst_context.SetNoArgs ();
12875
12876            if (m_opcode_cpsr & MASK_CPSR_T)
12877            {
12878                m_opcode_mode = eModeThumb;
12879                uint32_t thumb_opcode = MemARead(read_inst_context, pc, 2, 0, &success);
12880
12881                if (success)
12882                {
12883                    if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
12884                    {
12885                        m_opcode.SetOpcode16 (thumb_opcode);
12886                    }
12887                    else
12888                    {
12889                        m_opcode.SetOpcode32 ((thumb_opcode << 16) | MemARead(read_inst_context, pc + 2, 2, 0, &success));
12890                    }
12891                }
12892            }
12893            else
12894            {
12895                m_opcode_mode = eModeARM;
12896                m_opcode.SetOpcode32 (MemARead(read_inst_context, pc, 4, 0, &success));
12897            }
12898        }
12899    }
12900    if (!success)
12901    {
12902        m_opcode_mode = eModeInvalid;
12903        m_addr = LLDB_INVALID_ADDRESS;
12904    }
12905    return success;
12906}
12907
12908uint32_t
12909EmulateInstructionARM::ArchVersion ()
12910{
12911    return m_arm_isa;
12912}
12913
12914bool
12915EmulateInstructionARM::ConditionPassed (const uint32_t opcode, bool *is_conditional)
12916{
12917   // If we are ignoring conditions, then always return true.
12918   // this allows us to iterate over disassembly code and still
12919   // emulate an instruction even if we don't have all the right
12920   // bits set in the CPSR register...
12921    if (m_ignore_conditions)
12922        return true;
12923
12924    if (is_conditional)
12925        *is_conditional = true;
12926
12927    const uint32_t cond = CurrentCond (opcode);
12928
12929    if (cond == UINT32_MAX)
12930        return false;
12931
12932    bool result = false;
12933    switch (UnsignedBits(cond, 3, 1))
12934    {
12935    case 0:
12936		if (m_opcode_cpsr == 0)
12937			result = true;
12938        else
12939            result = (m_opcode_cpsr & MASK_CPSR_Z) != 0;
12940		break;
12941    case 1:
12942        if (m_opcode_cpsr == 0)
12943            result = true;
12944        else
12945            result = (m_opcode_cpsr & MASK_CPSR_C) != 0;
12946		break;
12947    case 2:
12948        if (m_opcode_cpsr == 0)
12949            result = true;
12950        else
12951            result = (m_opcode_cpsr & MASK_CPSR_N) != 0;
12952		break;
12953    case 3:
12954        if (m_opcode_cpsr == 0)
12955            result = true;
12956        else
12957            result = (m_opcode_cpsr & MASK_CPSR_V) != 0;
12958		break;
12959    case 4:
12960        if (m_opcode_cpsr == 0)
12961            result = true;
12962        else
12963            result = ((m_opcode_cpsr & MASK_CPSR_C) != 0) && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12964		break;
12965    case 5:
12966        if (m_opcode_cpsr == 0)
12967            result = true;
12968        else
12969		{
12970            bool n = (m_opcode_cpsr & MASK_CPSR_N);
12971            bool v = (m_opcode_cpsr & MASK_CPSR_V);
12972            result = n == v;
12973        }
12974        break;
12975    case 6:
12976        if (m_opcode_cpsr == 0)
12977            result = true;
12978        else
12979		{
12980            bool n = (m_opcode_cpsr & MASK_CPSR_N);
12981            bool v = (m_opcode_cpsr & MASK_CPSR_V);
12982            result = n == v && ((m_opcode_cpsr & MASK_CPSR_Z) == 0);
12983        }
12984        break;
12985    case 7:
12986        // Always execute (cond == 0b1110, or the special 0b1111 which gives
12987        // opcodes different meanings, but always means execution happpens.
12988        if (is_conditional)
12989            *is_conditional = false;
12990        result = true;
12991        break;
12992    }
12993
12994    if (cond & 1)
12995        result = !result;
12996    return result;
12997}
12998
12999uint32_t
13000EmulateInstructionARM::CurrentCond (const uint32_t opcode)
13001{
13002    switch (m_opcode_mode)
13003    {
13004    case eModeInvalid:
13005        break;
13006
13007    case eModeARM:
13008        return UnsignedBits(opcode, 31, 28);
13009
13010    case eModeThumb:
13011        // For T1 and T3 encodings of the Branch instruction, it returns the 4-bit
13012        // 'cond' field of the encoding.
13013        {
13014            const uint32_t byte_size = m_opcode.GetByteSize();
13015            if (byte_size == 2)
13016            {
13017                if (Bits32(opcode, 15, 12) == 0x0d && Bits32(opcode, 11, 7) != 0x0f)
13018                    return Bits32(opcode, 11, 7);
13019            }
13020            else if (byte_size == 4)
13021            {
13022                if (Bits32(opcode, 31, 27) == 0x1e &&
13023                    Bits32(opcode, 15, 14) == 0x02 &&
13024                    Bits32(opcode, 12, 12) == 0x00 &&
13025                    Bits32(opcode, 25, 22) <= 0x0d)
13026                {
13027                    return Bits32(opcode, 25, 22);
13028                }
13029            }
13030            else
13031                // We have an invalid thumb instruction, let's bail out.
13032                break;
13033
13034            return m_it_session.GetCond();
13035        }
13036    }
13037    return UINT32_MAX;  // Return invalid value
13038}
13039
13040bool
13041EmulateInstructionARM::InITBlock()
13042{
13043    return CurrentInstrSet() == eModeThumb && m_it_session.InITBlock();
13044}
13045
13046bool
13047EmulateInstructionARM::LastInITBlock()
13048{
13049    return CurrentInstrSet() == eModeThumb && m_it_session.LastInITBlock();
13050}
13051
13052bool
13053EmulateInstructionARM::BadMode (uint32_t mode)
13054{
13055
13056    switch (mode)
13057    {
13058        case 16: return false; // '10000'
13059        case 17: return false; // '10001'
13060        case 18: return false; // '10010'
13061        case 19: return false; // '10011'
13062        case 22: return false; // '10110'
13063        case 23: return false; // '10111'
13064        case 27: return false; // '11011'
13065        case 31: return false; // '11111'
13066        default: return true;
13067    }
13068    return true;
13069}
13070
13071bool
13072EmulateInstructionARM::CurrentModeIsPrivileged ()
13073{
13074    uint32_t mode = Bits32 (m_opcode_cpsr, 4, 0);
13075
13076    if (BadMode (mode))
13077        return false;
13078
13079    if (mode == 16)
13080        return false;
13081
13082    return true;
13083}
13084
13085void
13086EmulateInstructionARM::CPSRWriteByInstr (uint32_t value, uint32_t bytemask, bool affect_execstate)
13087{
13088    bool privileged = CurrentModeIsPrivileged();
13089
13090    uint32_t tmp_cpsr = Bits32 (m_opcode_cpsr, 23, 20) << 20;
13091
13092    if (BitIsSet (bytemask, 3))
13093    {
13094        tmp_cpsr = tmp_cpsr | (Bits32 (value, 31, 27) << 27);
13095        if (affect_execstate)
13096            tmp_cpsr = tmp_cpsr | (Bits32 (value, 26, 24) << 24);
13097    }
13098
13099    if (BitIsSet (bytemask, 2))
13100    {
13101        tmp_cpsr = tmp_cpsr | (Bits32 (value, 19, 16) << 16);
13102    }
13103
13104    if (BitIsSet (bytemask, 1))
13105    {
13106        if (affect_execstate)
13107            tmp_cpsr = tmp_cpsr | (Bits32 (value, 15, 10) << 10);
13108        tmp_cpsr = tmp_cpsr | (Bit32 (value, 9) << 9);
13109        if (privileged)
13110            tmp_cpsr = tmp_cpsr | (Bit32 (value, 8) << 8);
13111    }
13112
13113    if (BitIsSet (bytemask, 0))
13114    {
13115        if (privileged)
13116            tmp_cpsr = tmp_cpsr | (Bits32 (value, 7, 6) << 6);
13117        if (affect_execstate)
13118            tmp_cpsr = tmp_cpsr | (Bit32 (value, 5) << 5);
13119        if (privileged)
13120            tmp_cpsr = tmp_cpsr | Bits32 (value, 4, 0);
13121    }
13122
13123    m_opcode_cpsr = tmp_cpsr;
13124}
13125
13126
13127bool
13128EmulateInstructionARM::BranchWritePC (const Context &context, uint32_t addr)
13129{
13130    addr_t target;
13131
13132    // Check the current instruction set.
13133    if (CurrentInstrSet() == eModeARM)
13134        target = addr & 0xfffffffc;
13135    else
13136        target = addr & 0xfffffffe;
13137
13138    if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13139        return false;
13140
13141    return true;
13142}
13143
13144// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by inspecting addr.
13145bool
13146EmulateInstructionARM::BXWritePC (Context &context, uint32_t addr)
13147{
13148    addr_t target;
13149    // If the CPSR is changed due to switching between ARM and Thumb ISETSTATE,
13150    // we want to record it and issue a WriteRegister callback so the clients
13151    // can track the mode changes accordingly.
13152    bool cpsr_changed = false;
13153
13154    if (BitIsSet(addr, 0))
13155    {
13156        if (CurrentInstrSet() != eModeThumb)
13157        {
13158            SelectInstrSet(eModeThumb);
13159            cpsr_changed = true;
13160        }
13161        target = addr & 0xfffffffe;
13162        context.SetISA (eModeThumb);
13163    }
13164    else if (BitIsClear(addr, 1))
13165    {
13166        if (CurrentInstrSet() != eModeARM)
13167        {
13168            SelectInstrSet(eModeARM);
13169            cpsr_changed = true;
13170        }
13171        target = addr & 0xfffffffc;
13172        context.SetISA (eModeARM);
13173    }
13174    else
13175        return false; // address<1:0> == '10' => UNPREDICTABLE
13176
13177    if (cpsr_changed)
13178    {
13179        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13180            return false;
13181    }
13182    if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, target))
13183        return false;
13184
13185    return true;
13186}
13187
13188// Dispatches to either BXWritePC or BranchWritePC based on architecture versions.
13189bool
13190EmulateInstructionARM::LoadWritePC (Context &context, uint32_t addr)
13191{
13192    if (ArchVersion() >= ARMv5T)
13193        return BXWritePC(context, addr);
13194    else
13195        return BranchWritePC((const Context)context, addr);
13196}
13197
13198// Dispatches to either BXWritePC or BranchWritePC based on architecture versions and current instruction set.
13199bool
13200EmulateInstructionARM::ALUWritePC (Context &context, uint32_t addr)
13201{
13202    if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM)
13203        return BXWritePC(context, addr);
13204    else
13205        return BranchWritePC((const Context)context, addr);
13206}
13207
13208EmulateInstructionARM::Mode
13209EmulateInstructionARM::CurrentInstrSet ()
13210{
13211    return m_opcode_mode;
13212}
13213
13214// Set the 'T' bit of our CPSR.  The m_opcode_mode gets updated when the next
13215// ReadInstruction() is performed.  This function has a side effect of updating
13216// the m_new_inst_cpsr member variable if necessary.
13217bool
13218EmulateInstructionARM::SelectInstrSet (Mode arm_or_thumb)
13219{
13220    m_new_inst_cpsr = m_opcode_cpsr;
13221    switch (arm_or_thumb)
13222    {
13223    default:
13224        return false;
13225    case eModeARM:
13226        // Clear the T bit.
13227        m_new_inst_cpsr &= ~MASK_CPSR_T;
13228        break;
13229    case eModeThumb:
13230        // Set the T bit.
13231        m_new_inst_cpsr |= MASK_CPSR_T;
13232        break;
13233    }
13234    return true;
13235}
13236
13237// This function returns TRUE if the processor currently provides support for
13238// unaligned memory accesses, or FALSE otherwise. This is always TRUE in ARMv7,
13239// controllable by the SCTLR.U bit in ARMv6, and always FALSE before ARMv6.
13240bool
13241EmulateInstructionARM::UnalignedSupport()
13242{
13243    return (ArchVersion() >= ARMv7);
13244}
13245
13246// The main addition and subtraction instructions can produce status information
13247// about both unsigned carry and signed overflow conditions.  This status
13248// information can be used to synthesize multi-word additions and subtractions.
13249EmulateInstructionARM::AddWithCarryResult
13250EmulateInstructionARM::AddWithCarry (uint32_t x, uint32_t y, uint8_t carry_in)
13251{
13252    uint32_t result;
13253    uint8_t carry_out;
13254    uint8_t overflow;
13255
13256    uint64_t unsigned_sum = x + y + carry_in;
13257    int64_t signed_sum = (int32_t)x + (int32_t)y + (int32_t)carry_in;
13258
13259    result = UnsignedBits(unsigned_sum, 31, 0);
13260//    carry_out = (result == unsigned_sum ? 0 : 1);
13261    overflow = ((int32_t)result == signed_sum ? 0 : 1);
13262
13263    if (carry_in)
13264        carry_out = ((int32_t) x >= (int32_t) (~y)) ? 1 : 0;
13265    else
13266        carry_out = ((int32_t) x > (int32_t) y) ? 1 : 0;
13267
13268    AddWithCarryResult res = { result, carry_out, overflow };
13269    return res;
13270}
13271
13272uint32_t
13273EmulateInstructionARM::ReadCoreReg(uint32_t num, bool *success)
13274{
13275    uint32_t reg_kind, reg_num;
13276    switch (num)
13277    {
13278    case SP_REG:
13279        reg_kind = eRegisterKindGeneric;
13280        reg_num  = LLDB_REGNUM_GENERIC_SP;
13281        break;
13282    case LR_REG:
13283        reg_kind = eRegisterKindGeneric;
13284        reg_num  = LLDB_REGNUM_GENERIC_RA;
13285        break;
13286    case PC_REG:
13287        reg_kind = eRegisterKindGeneric;
13288        reg_num  = LLDB_REGNUM_GENERIC_PC;
13289        break;
13290    default:
13291        if (num < SP_REG)
13292        {
13293            reg_kind = eRegisterKindDWARF;
13294            reg_num  = dwarf_r0 + num;
13295        }
13296        else
13297        {
13298            //assert(0 && "Invalid register number");
13299            *success = false;
13300            return UINT32_MAX;
13301        }
13302        break;
13303    }
13304
13305    // Read our register.
13306    uint32_t val = ReadRegisterUnsigned (reg_kind, reg_num, 0, success);
13307
13308    // When executing an ARM instruction , PC reads as the address of the current
13309    // instruction plus 8.
13310    // When executing a Thumb instruction , PC reads as the address of the current
13311    // instruction plus 4.
13312    if (num == 15)
13313    {
13314        if (CurrentInstrSet() == eModeARM)
13315            val += 8;
13316        else
13317            val += 4;
13318    }
13319
13320    return val;
13321}
13322
13323// Write the result to the ARM core register Rd, and optionally update the
13324// condition flags based on the result.
13325//
13326// This helper method tries to encapsulate the following pseudocode from the
13327// ARM Architecture Reference Manual:
13328//
13329// if d == 15 then         // Can only occur for encoding A1
13330//     ALUWritePC(result); // setflags is always FALSE here
13331// else
13332//     R[d] = result;
13333//     if setflags then
13334//         APSR.N = result<31>;
13335//         APSR.Z = IsZeroBit(result);
13336//         APSR.C = carry;
13337//         // APSR.V unchanged
13338//
13339// In the above case, the API client does not pass in the overflow arg, which
13340// defaults to ~0u.
13341bool
13342EmulateInstructionARM::WriteCoreRegOptionalFlags (Context &context,
13343                                                  const uint32_t result,
13344                                                  const uint32_t Rd,
13345                                                  bool setflags,
13346                                                  const uint32_t carry,
13347                                                  const uint32_t overflow)
13348{
13349    if (Rd == 15)
13350    {
13351        if (!ALUWritePC (context, result))
13352            return false;
13353    }
13354    else
13355    {
13356        uint32_t reg_kind, reg_num;
13357        switch (Rd)
13358        {
13359        case SP_REG:
13360            reg_kind = eRegisterKindGeneric;
13361            reg_num  = LLDB_REGNUM_GENERIC_SP;
13362            break;
13363        case LR_REG:
13364            reg_kind = eRegisterKindGeneric;
13365            reg_num  = LLDB_REGNUM_GENERIC_RA;
13366            break;
13367        default:
13368            reg_kind = eRegisterKindDWARF;
13369            reg_num  = dwarf_r0 + Rd;
13370        }
13371        if (!WriteRegisterUnsigned (context, reg_kind, reg_num, result))
13372            return false;
13373        if (setflags)
13374            return WriteFlags (context, result, carry, overflow);
13375    }
13376    return true;
13377}
13378
13379// This helper method tries to encapsulate the following pseudocode from the
13380// ARM Architecture Reference Manual:
13381//
13382// APSR.N = result<31>;
13383// APSR.Z = IsZeroBit(result);
13384// APSR.C = carry;
13385// APSR.V = overflow
13386//
13387// Default arguments can be specified for carry and overflow parameters, which means
13388// not to update the respective flags.
13389bool
13390EmulateInstructionARM::WriteFlags (Context &context,
13391                                   const uint32_t result,
13392                                   const uint32_t carry,
13393                                   const uint32_t overflow)
13394{
13395    m_new_inst_cpsr = m_opcode_cpsr;
13396    SetBit32(m_new_inst_cpsr, CPSR_N_POS, Bit32(result, CPSR_N_POS));
13397    SetBit32(m_new_inst_cpsr, CPSR_Z_POS, result == 0 ? 1 : 0);
13398    if (carry != ~0u)
13399        SetBit32(m_new_inst_cpsr, CPSR_C_POS, carry);
13400    if (overflow != ~0u)
13401        SetBit32(m_new_inst_cpsr, CPSR_V_POS, overflow);
13402    if (m_new_inst_cpsr != m_opcode_cpsr)
13403    {
13404        if (!WriteRegisterUnsigned (context, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
13405            return false;
13406    }
13407    return true;
13408}
13409
13410bool
13411EmulateInstructionARM::EvaluateInstruction (uint32_t evaluate_options)
13412{
13413    // Advance the ITSTATE bits to their values for the next instruction.
13414    if (m_opcode_mode == eModeThumb && m_it_session.InITBlock())
13415        m_it_session.ITAdvance();
13416
13417    ARMOpcode *opcode_data = NULL;
13418
13419    if (m_opcode_mode == eModeThumb)
13420        opcode_data = GetThumbOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13421    else if (m_opcode_mode == eModeARM)
13422        opcode_data = GetARMOpcodeForInstruction (m_opcode.GetOpcode32(), m_arm_isa);
13423
13424    if (opcode_data == NULL)
13425        return false;
13426
13427    const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
13428    m_ignore_conditions = evaluate_options & eEmulateInstructionOptionIgnoreConditions;
13429
13430    bool success = false;
13431    if (m_opcode_cpsr == 0 || m_ignore_conditions == false)
13432    {
13433        m_opcode_cpsr = ReadRegisterUnsigned (eRegisterKindDWARF,
13434                                                dwarf_cpsr,
13435                                                0,
13436                                                &success);
13437    }
13438
13439    // Only return false if we are unable to read the CPSR if we care about conditions
13440    if (success == false && m_ignore_conditions == false)
13441        return false;
13442
13443    uint32_t orig_pc_value = 0;
13444    if (auto_advance_pc)
13445    {
13446        orig_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13447        if (!success)
13448            return false;
13449    }
13450
13451    // Call the Emulate... function.
13452    success = (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding);
13453    if (!success)
13454        return false;
13455
13456    if (auto_advance_pc)
13457    {
13458        uint32_t after_pc_value = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc, 0, &success);
13459        if (!success)
13460            return false;
13461
13462        if (auto_advance_pc && (after_pc_value == orig_pc_value))
13463        {
13464            if (opcode_data->size == eSize32)
13465                after_pc_value += 4;
13466            else if (opcode_data->size == eSize16)
13467                after_pc_value += 2;
13468
13469            EmulateInstruction::Context context;
13470            context.type = eContextAdvancePC;
13471            context.SetNoArgs();
13472            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc, after_pc_value))
13473                return false;
13474
13475        }
13476    }
13477    return true;
13478}
13479
13480bool
13481EmulateInstructionARM::TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data)
13482{
13483    if (!test_data)
13484    {
13485        out_stream->Printf ("TestEmulation: Missing test data.\n");
13486        return false;
13487    }
13488
13489    static ConstString opcode_key ("opcode");
13490    static ConstString before_key ("before_state");
13491    static ConstString after_key ("after_state");
13492
13493    OptionValueSP value_sp = test_data->GetValueForKey (opcode_key);
13494
13495    uint32_t test_opcode;
13496    if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeUInt64))
13497    {
13498        out_stream->Printf ("TestEmulation: Error reading opcode from test file.\n");
13499        return false;
13500    }
13501    test_opcode = value_sp->GetUInt64Value ();
13502
13503    if (arch.GetTriple().getArch() == llvm::Triple::arm)
13504    {
13505        m_opcode_mode = eModeARM;
13506        m_opcode.SetOpcode32 (test_opcode);
13507    }
13508    else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
13509    {
13510        m_opcode_mode = eModeThumb;
13511        if (test_opcode < 0x10000)
13512            m_opcode.SetOpcode16 (test_opcode);
13513        else
13514            m_opcode.SetOpcode32 (test_opcode);
13515
13516    }
13517    else
13518    {
13519        out_stream->Printf ("TestEmulation:  Invalid arch.\n");
13520        return false;
13521    }
13522
13523    EmulationStateARM before_state;
13524    EmulationStateARM after_state;
13525
13526    value_sp = test_data->GetValueForKey (before_key);
13527    if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13528    {
13529        out_stream->Printf ("TestEmulation:  Failed to find 'before' state.\n");
13530        return false;
13531    }
13532
13533    OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary ();
13534    if (!before_state.LoadStateFromDictionary (state_dictionary))
13535    {
13536        out_stream->Printf ("TestEmulation:  Failed loading 'before' state.\n");
13537        return false;
13538    }
13539
13540    value_sp = test_data->GetValueForKey (after_key);
13541    if ((value_sp.get() == NULL) || (value_sp->GetType() != OptionValue::eTypeDictionary))
13542    {
13543        out_stream->Printf ("TestEmulation:  Failed to find 'after' state.\n");
13544        return false;
13545    }
13546
13547    state_dictionary = value_sp->GetAsDictionary ();
13548    if (!after_state.LoadStateFromDictionary (state_dictionary))
13549    {
13550        out_stream->Printf ("TestEmulation: Failed loading 'after' state.\n");
13551        return false;
13552    }
13553
13554    SetBaton ((void *) &before_state);
13555    SetCallbacks (&EmulationStateARM::ReadPseudoMemory,
13556                  &EmulationStateARM::WritePseudoMemory,
13557                  &EmulationStateARM::ReadPseudoRegister,
13558                  &EmulationStateARM::WritePseudoRegister);
13559
13560    bool success = EvaluateInstruction (eEmulateInstructionOptionAutoAdvancePC);
13561    if (!success)
13562    {
13563        out_stream->Printf ("TestEmulation:  EvaluateInstruction() failed.\n");
13564        return false;
13565    }
13566
13567    success = before_state.CompareState (after_state);
13568    if (!success)
13569        out_stream->Printf ("TestEmulation:  'before' and 'after' states do not match.\n");
13570
13571    return success;
13572}
13573//
13574//
13575//const char *
13576//EmulateInstructionARM::GetRegisterName (uint32_t reg_kind, uint32_t reg_num)
13577//{
13578//    if (reg_kind == eRegisterKindGeneric)
13579//    {
13580//        switch (reg_num)
13581//        {
13582//        case LLDB_REGNUM_GENERIC_PC:    return "pc";
13583//        case LLDB_REGNUM_GENERIC_SP:    return "sp";
13584//        case LLDB_REGNUM_GENERIC_FP:    return "fp";
13585//        case LLDB_REGNUM_GENERIC_RA:    return "lr";
13586//        case LLDB_REGNUM_GENERIC_FLAGS: return "cpsr";
13587//        default: return NULL;
13588//        }
13589//    }
13590//    else if (reg_kind == eRegisterKindDWARF)
13591//    {
13592//        return GetARMDWARFRegisterName (reg_num);
13593//    }
13594//    return NULL;
13595//}
13596//
13597bool
13598EmulateInstructionARM::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
13599{
13600    unwind_plan.Clear();
13601    unwind_plan.SetRegisterKind (eRegisterKindDWARF);
13602
13603    UnwindPlan::RowSP row(new UnwindPlan::Row);
13604
13605    // Our previous Call Frame Address is the stack pointer
13606    row->SetCFARegister (dwarf_sp);
13607
13608    // Our previous PC is in the LR
13609    row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true);
13610    unwind_plan.AppendRow (row);
13611
13612    // All other registers are the same.
13613
13614    unwind_plan.SetSourceName ("EmulateInstructionARM");
13615    unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
13616    unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
13617    return true;
13618}
13619